1

我有以下设置:

  • 带有 Python 绑定的 GDAL 库 (SWIG)
  • 一些胶水代码(Python)
  • AC 库,与 ctypes 接口

我想将 SWIGDataset对象的基础数据集指针/句柄传递给我的 C 库。如何检索此指针?

不想将 C 库与 SWIG 接口。

4

2 回答 2

1

这实际上很容易,我希望我的解决方案是可移植的。鉴于,我的 C 函数定义看起来有点像这样:

int myfunc(GDALDatasetH ds);

那么我的ctypes定义是这样的:

_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)))
于 2012-03-13T14:28:22.273 回答
1

我对这个问题的 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); 
}
于 2015-12-22T23:18:10.903 回答