2012-03-13 71 views
1

底層的指針/句柄我具有以下設置:GDAL:獲取對象C

  • GDAL庫Python綁定(SWIG)
  • 一些膠水代碼(Python)的
  • AC文庫,接口與ctypes

我想將SWIG Dataset對象的底層數據集指針/句柄傳遞給我的C庫。我如何檢索這個指針?

我做不是想要將C庫與SWIG連接起來。

回答

1

這實際上很簡單,我希望我的解決方案是可移植的。鑑於,我的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))) 
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); 
} 
+0

我同意,這有一定的道理,但需要一個編譯步驟中安裝的額外麻煩和禁止純Python包的貨物。 (這對我來說是不行的)。 在我的解決方案中,指針永遠不會比調用C函數的時間更長。因此,不會出現陳舊指針的問題。 – Constantinius 2015-12-26 19:43:27