質問

次の設定があります。

  • Python Bindings(SWIG)
  • のGDALライブラリー
  • いくつかの接着剤コード(Python)
  • Cライブラリー、CTypes
  • にインターフェース

SWIG Datasetオブジェクトの基礎となるデータセットポインタ/ハンドルをCライブラリに渡したい。このポインタを取得する方法は?

i do not は、cライブラリをSWIGでインタフェースしたいです。

役に立ちましたか?

解決

実際には非常に簡単だったので、私の解決策が移植可能であることを願っています。与えられた、私の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)))
.

他のヒント

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); 
}
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top