Ho lavorato con Cython nel tentativo di interfacciare una libreria scritta in C++. Finora le cose stanno andando abbastanza bene e posso utilizzare efficacemente le funzioni MOST all'interno della libreria. Il mio unico problema si trova nell'implementare i callback. La biblioteca dispone di 4 definizioni di funzioni che sembrano un po 'qualcosa di simile a questo:Cython - implementazione di callback
typedef void (*Function1)(const uint16_t *data,
unsigned width, unsigned height);
void SetCallBack(Function1);
Quindi, per attuare li ho pensato che avrei fatto qualcosa di simile con Cython:
ctypedef void (*Function1)(unsigned short *data,
unsigned width, unsigned height);
cdef extern from "lib.hpp":
void SetCallBack(Function1)
che in realtà compilato correttamente, tuttavia, Non posso per la vita di me pensare a come implementarlo realmente in modo tale che la richiamata funzioni. Ho cercato di creare una funzione che basta chiamare che, in modo simile a come si farebbe per qualsiasi altra funzione, fino a venire con questo:
def PySetCallBack(Func):
SetCallBack(Func)
ma che mi dà la (prevedibile) di errore:
"Impossibile convertire l'oggetto Python in 'Function1'"
quindi sì, è dove sono. Se qualcuno ha qualche esperienza nell'impostare i callback in Cython, sarei molto grato per qualsiasi tipo di assistenza. Grazie.
Edit: seguito il tuo consiglio, ho creato una funzione intermedia con un CDEF, che assomiglia a questo:
cdef void cSetCallBack(Function1 function):
SetCallBack(function)
Questo mi sembra aver ottenuto ... Closer? Ottenere un errore diverso ora almeno:
error: invalid conversion from ‘void (*)(short unsigned int*, unsigned int, unsigned int)’ to ‘void (*)(const uint16_t*, unsigned int, unsigned int)’
Ora, per quanto posso dire quei tipi sono identiche, quindi non riesco a capire cosa sta succedendo.
Edit2: Risolto il problema dichiarando un nuovo typedef:
ctypedef unsigned short uint16_t
ed usando che come argomento per chiamare, ma a quanto pare che non era in realtà sempre più vicino, ma solo a me di prendere in giro una traccia laterale, poiché quando provo a chiamare quella funzione, ottengo lo stesso errore "Impossibile convertire l'oggetto Python in" Function1 "" di nuovo.
Quindi, sono tornato indietro da dove ho iniziato. L'unica cosa che posso immaginare ora è di lanciare esplicitamente l'oggetto Python come una funzione simile, ma, ad essere onesti, non ho idea di come potrei farlo.
Modificare il terzo: Bene, dopo sezionare la tua risposta ho finalmente capito, e funziona, quindi evviva e quant'altro. Quello che ho finito per fare era creare una funzione come questa:
cdef void cSetCallback(Function1 function):
SetCallback(function)
cdef void callcallback(const_ushort *data, unsigned width, unsigned height):
global callbackfunc
callbackfunc(data,width,height)
cSetCallback(callcallback)
def PySetCallback(callbackFunc):
global callbackfunc
callbackfunc = callbackFunc
Così ora l'unico problema è che non è possibile convertire const_ushort * dati in un oggetto Python, ma questo è un altro problema del tutto, quindi credo che questo è risolto, grazie mille.
Cambia 'short unsigned int *' a 'const short unsigned int *'. – aschepler
Per quanto ne so, Cython non ha idea di cosa const sia, e ogni volta che cerco di usarlo, ottengo "Const non è un identificatore di tipo". – Josiah