Question

J'ai la configuration suivante:

  • Bibliothèque GDAL avec des bindings Python (LAMPÉE)
  • Un peu de colle, de code (Python)
  • Une bibliothèque C, interfacé avec ctypes

Je veux passer le dataset sous-jacent pointeur/handle de la GORGÉE Dataset l'objet de mon C de la bibliothèque.Comment puis-je récupérer ce pointeur?

Je ne pas voulez interface de la bibliothèque C avec SWIG.

Était-ce utile?

La solution

Il est en fait assez facile, et j'espère que ma solution est portable.Étant donné, que mon C définition de la fonction ressemble un peu à ceci:

int myfunc(GDALDatasetH ds);

Puis mon ctypes définition se présente comme ceci:

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

Et je peux appeler la fonction C avec:

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

Autres conseils

Ma réservation avec le ctypes approche de ce problème est que le compteur de référence de la ds objet n'est pas incrémenté automatiquement et deviendra un mauvais pointeur si elle était hors de portée.

Une meilleure approche serait de définir un C python module d'extension qui permettrait de gérer les données de référence du compteur.

Je suis à l'aide d'un statique PyObject * organiser l'objet, à l'évidence une réelle mise en œuvre serait de les stocker de manière plus 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); 
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top