Ich habe mit Cython gearbeitet und versucht, eine Schnittstelle zu einer in C++ geschriebenen Bibliothek zu schaffen. Bis jetzt läuft es ganz gut, und ich kann die meisten Funktionen der Bibliothek effektiv nutzen. Mein einziges Problem liegt in der Implementierung von Rückrufen. Die Bibliothek hat 4 Funktionsdefinitionen, die ein wenig wie folgt aussehen:
typedef void (*Function1)(const uint16_t *data,
unsigned width, unsigned height);
void SetCallBack(Function1);
Also, um sie zu implementieren, dachte ich, ich würde so etwas wie dieses mit Cython tun:
ctypedef void (*Function1)(unsigned short *data,
unsigned width, unsigned height);
cdef extern from "lib.hpp":
void SetCallBack(Function1)
Die tatsächlich korrekt kompiliert, aber ich kann nicht für das Leben von mir denken, wie man tatsächlich implementieren, dass in einer solchen Weise, dass der Rückruf funktionieren würde. Ich habe zuerst versucht, eine Funktion zu erstellen, die nur aufrufen würde, dass, ähnlich wie Sie es für jede andere Funktion tun würde, kommen mit diesem:
def PySetCallBack(Func):
SetCallBack(Func)
aber das gibt mir den (vorhersehbaren) Fehler:
"Python-Objekt kann nicht in 'Funktion1' umgewandelt werden"
Also ja, so weit bin ich schon. Wenn jemand Erfahrung mit der Einrichtung von Rückrufen in Cython hat, wäre ich für jede Hilfe sehr dankbar. Danke!
bearbeiten : Ihrem Rat folgend, habe ich eine Zwischenfunktion mit einem cdef erstellt, die wie folgt aussieht:
cdef void cSetCallBack(Function1 function):
SetCallBack(function)
Das hat mich anscheinend... Näher dran? Zumindest wird jetzt ein anderer Fehler angezeigt:
error: invalid conversion from ‘void (*)(short unsigned int*, unsigned int, unsigned int)’ to ‘void (*)(const uint16_t*, unsigned int, unsigned int)’
Soweit ich das beurteilen kann, sind diese Typen identisch, so dass ich nicht herausfinden kann, was hier los ist.
Bearbeiten2 : Dieses Problem wurde durch die Deklaration eines neuen Typedefs behoben:
ctypedef unsigned short uint16_t
und mit, dass als das Argument aufzurufen, aber anscheinend, dass war nicht wirklich näher, sondern nur, die mich um ein Nebengleis, da beim Versuch, diese Funktion aufzurufen, bekomme ich die gleiche "Cannot konvertieren Python-Objekt zu 'Function1'" Fehler alle wieder.
Ich bin also so ziemlich wieder da, wo ich angefangen habe. Das einzige, was ich jetzt tun kann, ist explizit das Python-Objekt kommen in als eine C-Funktion wie das, aber, um ehrlich zu sein, ich habe keine Ahnung, wie ich über das gehen würde.
Bearbeiten Sie die dritte : In Ordnung, nach sezieren Ihre Antwort ich endlich bekommen es, und es funktioniert, so Hurra und was nicht. Was ich am Ende tat, war die Erstellung einer Funktion wie diese:
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
So jetzt das einzige Problem ist, dass es nicht const_ushort *data in ein Python-Objekt konvertieren kann, aber das ist ein anderes Problem ganz, so ich denke, dieses ist gelöst, vielen Dank.