Python GDAL:获取底层C对象的指针/句柄

Python GDAL:获取底层C对象的指针/句柄,python,swig,ctypes,gdal,Python,Swig,Ctypes,Gdal,我有以下设置: 带有Python绑定的GDAL库(SWIG) 一些胶水代码(Python) 与ctypes接口的C库 我想将SWIGdataset对象的底层数据集指针/句柄传递给我的C库。如何检索此指针 我不想将C库与SWIG连接起来。这实际上非常简单,我希望我的解决方案是可移植的。假设我的C函数定义看起来像这样: int myfunc(GDALDatasetH ds); _lib = C.LibraryLoader(C.CDLL).LoadLibrary(lib_path) _myfun

我有以下设置:

  • 带有Python绑定的GDAL库(SWIG)
  • 一些胶水代码(Python)
  • 与ctypes接口的C库
我想将SWIG
dataset
对象的底层数据集指针/句柄传递给我的C库。如何检索此指针


我不想将C库与SWIG连接起来。

这实际上非常简单,我希望我的解决方案是可移植的。假设我的C函数定义看起来像这样:

int myfunc(GDALDatasetH ds);
_lib = C.LibraryLoader(C.CDLL).LoadLibrary(lib_path)
_myfunc = _lib.myfunc
_myfunc.argtypes = [C.c_void_p]
_myfunc.restype = C.POINTER(C.c_char)
然后我的
ctypes
定义如下:

int myfunc(GDALDatasetH ds);
_lib = C.LibraryLoader(C.CDLL).LoadLibrary(lib_path)
_myfunc = _lib.myfunc
_myfunc.argtypes = [C.c_void_p]
_myfunc.restype = C.POINTER(C.c_char)
我可以通过以下方式调用C函数:

ds = gdal.Open(path)
...
_myfunc(C.c_void_p(long(ds.this)))

对于这个问题,我对ctypes方法的保留意见是,ds对象的引用计数不会自动递增,如果超出范围,它将成为一个错误的指针

更好的方法是定义一个C python扩展模块来管理数据引用计数器

我使用静态PyObject*来保存对象,很明显,真正的实现将更智能地存储它

static PyObject * ds;
PyObject* GiveDsToC(PyObject * self, PyObject * args)
{
    PyObject * pThis=NULL;
    unsigned long addr;
    if(!PyArg_ParseTuple(args, "O", &ds))
         return NULL;

    /* Ensure the interpreter keeps ds around while we have it */
    Py_INCREF(ds); 

    pThis = PyObject_GetAttrString(ds, "this"); // new reference
    addr = PyLong_AsLong(pThis); // convert using __int__ method

    Py_DECREF(pThis); // Release the object back

    CallSomeCFunction(addr);
    Py_RETURN_NONE;
}
void FinishedWithDS(void)
{
    // Lock the GIL and decrement the reference counter
    PyGILState_STATE state = PyGILState_Ensure(); 
    Py_DECREF(ds);
    PyGILState_Release(state); 
}

我同意,这有一定的有效性,但在安装过程中需要编译步骤,这会带来额外的麻烦,并禁止装运纯python包。(这对我来说是不可能的)。在我的解决方案中,指针的保存时间永远不会超过调用C函数的时间。因此,永远不会出现指针过时的问题。