1

私は次の設定をしています:

  • Python バインディングを備えた GDAL ライブラリ (SWIG)
  • グルーコード (Python)
  • ctypes と連動する AC ライブラリ

DatasetSWIGオブジェクトの基になるデータセット ポインター/ハンドルを 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 拡張モジュールを定義することです。

オブジェクトを保持するために static 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 に答える