Domanda

Ho la seguente configurazione:

    .
  • Libreria GDAL con Binding Python (Swig)
  • alcuni codici colla (Python)
  • una libreria C, interfacciata con ctypes

Voglio passare il puntatore del set di dati sottostanti / maniglia dell'oggetto Dataset Swig alla mia libreria C.Come posso recuperare questo puntatore?

I Do NON Vuoi interfacciare la libreria C con Swig.

È stato utile?

Soluzione

È stato in realtà abbastanza facile, e spero che la mia soluzione sia portatile.Dato, che la mia definizione della funzione C sembra un po 'come questa:

int myfunc(GDALDatasetH ds);
.

Allora la mia definizione ctypes è come questa:

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

E posso chiamare la funzione C con:

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

Altri suggerimenti

La mia prenotazione con l'approccio ctypes per questo problema è che il conteggio di riferimento dell'oggetto DS non viene incrementato automaticamente e diventerà un brutto puntatore se dovesse uscire dalla portata.

Un approccio migliore sarebbe quello di definire un modulo di estensione P Python che gestirebbe il contatore di riferimento dei dati.

Sto usando un Pyobject statico * per tenere l'oggetto, ovviamente una vera implementazione lo memorizzerebbe più intelligente.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top