Pergunta

Eu tenho a seguinte configuração:

  • Biblioteca GDAL com Python bindings (GOLE)
  • Um pouco de cola código (Python)
  • Uma biblioteca C, a interface com ctypes

Eu quero passar o dataset subjacente ponteiro/alça do GOLE Dataset objeto de meu C biblioteca.Como posso recuperar este ponteiro?

Eu não quer a interface da biblioteca C com GOLE.

Foi útil?

Solução

Foi realmente muito fácil, e eu espero que a minha solução é portátil.Dado, que a minha função C definição parece-se com esta:

int myfunc(GDALDatasetH ds);

Então meu ctypes definição é semelhante a esse:

_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 eu posso chamar a função C com:

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

Outras dicas

Minha reserva com o ctypes abordagem para este problema é que a contagem de referência do objeto de ds não é incrementado automaticamente e vai se tornar um ponteiro ruim, se fosse para sair do escopo.

Uma abordagem melhor seria definir um C python módulo de extensão que iria gerir os dados de contador de referência.

Eu estou usando um static PyObject * para manter o objeto, obviamente, uma implementação real seria armazená-lo de forma mais 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top