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库
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函数的时间。因此,永远不会出现指针过时的问题。