底層的指針/句柄我具有以下設置:GDAL:獲取對象C
- GDAL庫Python綁定(SWIG)
- 一些膠水代碼(Python)的
- AC文庫,接口與ctypes
我想將SWIG Dataset
對象的底層數據集指針/句柄傳遞給我的C庫。我如何檢索這個指針?
我做不是想要將C庫與SWIG連接起來。
底層的指針/句柄我具有以下設置:GDAL:獲取對象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)
我可以調用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函數的時間更長。因此,不會出現陳舊指針的問題。 – Constantinius 2015-12-26 19:43:27