Pregunta

Tengo la siguiente configuración:

  • Biblioteca GDAL con enlaces de Python (SWIG)
  • Algún código adhesivo (Python)
  • Una biblioteca C, interconectada con ctypes

Quiero pasar el puntero/identificador del conjunto de datos subyacente del SWIG Dataset objeto a mi biblioteca C.¿Cómo puedo recuperar este puntero?

no desea interconectar la biblioteca C con SWIG.

¿Fue útil?

Solución

En realidad, fue bastante fácil y espero que mi solución sea portátil.Dado que mi definición de función C se parece a esto:

int myfunc(GDALDatasetH ds);

Entonces mi ctypes La definición es así:

_lib = C.LibraryLoader(C.CDLL).LoadLibrary(lib_path)
_myfunc = _lib.myfunc
_myfunc.argtypes = [C.c_void_p]
_myfunc.restype = C.POINTER(C.c_char)

Y puedo llamar a la función C con:

ds = gdal.Open(path)
...
_myfunc(C.c_void_p(long(ds.this)))

Otros consejos

Mi reserva con el enfoque de ctypes para este problema es que el recuento de referencias del objeto ds no se incrementa automáticamente y se convertirá en un mal puntero si se sale del alcance.

Un mejor enfoque sería definir un módulo de extensión C Python que administraría el contador de referencia de datos.

Estoy usando un PyObject * estático para contener el objeto, obviamente una implementación real lo almacenaría de manera más inteligente.

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); 
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top