Pracowałem z Cythonem, próbując połączyć się z biblioteką napisaną w języku C++. Do tej pory wszystko idzie całkiem nieźle i mogę skutecznie korzystać z MOST funkcji w bibliotece. Mój jedyny problem leży w implementacji wywołań zwrotnych. Biblioteka posiada 4 definicje funkcji, które wyglądają trochę coś takiego:Cython - implementowanie wywołań zwrotnych
typedef void (*Function1)(const uint16_t *data,
unsigned width, unsigned height);
void SetCallBack(Function1);
Więc do wprowadzania ich Pomyślałem chciałbym zrobić coś takiego z Cython:
ctypedef void (*Function1)(unsigned short *data,
unsigned width, unsigned height);
cdef extern from "lib.hpp":
void SetCallBack(Function1)
Które faktycznie kompiluje poprawnie, jednak Nie mogę na całe życie pomyśleć, jak to zaimplementować w taki sposób, aby zadziałało wywołanie zwrotne. Po raz pierwszy spróbował tworząc funkcję, która po prostu zadzwonić, że podobnie jak w jaki sposób to zrobić dla każdej innej funkcji, wymyślanie to:
def PySetCallBack(Func):
SetCallBack(Func)
ale to daje mi (przewidywalne) Błąd:
"Nie można przekonwertować obiektu Pythona na" Funkcję 1 ""
więc tak, właśnie w tym jestem. Jeśli ktokolwiek ma doświadczenie w tworzeniu wywołań zwrotnych w Cython, byłbym bardzo wdzięczny za jakąkolwiek pomoc. Dzięki.
Edit: Po poradę, stworzyłem pośrednią funkcję z cdef, który wygląda tak:
cdef void cSetCallBack(Function1 function):
SetCallBack(function)
Wydaje mi się zdobyć ... bliżej? Otrzymuję teraz inny błąd co najmniej:
error: invalid conversion from ‘void (*)(short unsigned int*, unsigned int, unsigned int)’ to ‘void (*)(const uint16_t*, unsigned int, unsigned int)’
Teraz, o ile mogę powiedzieć, że te typy są identyczne, więc nie mogę określić, co się dzieje.
Edit2: Poprawiono ten problem poprzez uznanie nowego typedef:
ctypedef unsigned short uint16_t
i używając które jako argument zadzwonić, ale widocznie to nie był rzeczywiście coraz bliżej, ale tylko przy mnie dookoła poboczna ścieżka, ponieważ próbując wywołać tę funkcję, otrzymuję taki sam komunikat "Nie można ponownie przekonwertować obiektu Pythona na błąd" Function1 ".
Więc, jestem już z powrotem tam, gdzie zacząłem. Jedyne, co mogę teraz zrobić, to jawnie rzucić obiekt python jako funkcję c, ale szczerze mówiąc, nie mam pojęcia, jak bym to robił.
Edycja trzecia: porządku, po krajanie odpowiedź I wreszcie dostać to, i to działa, więc hurra i etażerka. Co skończyło się robi było stworzenie funkcję tak:
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
Więc teraz jedynym problemem jest to, że nie można przekonwertować const_ushort * dane w obiekt Pythona, ale to już inny problem całkowicie, więc myślę, że ten jeden jest rozwiązany, wielkie dzięki.
Zmień 'short unsigned int *' na 'const short unsigned int *'. – aschepler
Zgodnie z moją wiedzą, Cython nie ma pojęcia, co oznacza const, a gdy próbuję go użyć, otrzymuję "Const nie jest identyfikatorem typu". – Josiah