Я работал с Cython, пытаясь взаимодействовать с библиотекой, написанной на c ++.Пока что дела идут довольно хорошо, и я могу эффективно использовать MOST-функции в библиотеке.Моя единственная проблема заключается в реализации обратных вызовов.В библиотеке есть 4 определения функций, которые выглядят примерно так:
typedef void (*Function1)(const uint16_t *data,
unsigned width, unsigned height);
void SetCallBack(Function1);
Так что для их реализации я решил, что я сделаю что-то подобное с cython:
ctypedef void (*Function1)(unsigned short *data,
unsigned width, unsigned height);
cdef extern from "lib.hpp":
void SetCallBack(Function1)
, который на самом деле компилируетсяправильно, однако, я не могу на всю жизнь подумать, как на самом деле реализовать это таким образом, чтобы обратный вызов работал.Сначала я попытался создать функцию, которая просто вызывала бы ее, подобно тому, как вы делали бы это для любой другой функции, но предложила следующее:
def PySetCallBack(Func):
SetCallBack(Func)
, но это дает мне (предсказуемую) ошибку:
"Невозможно преобразовать объект Python в 'Function1'"
, так что да, вот где я.Если у кого-то есть опыт настройки обратных вызовов в Cython, я был бы очень признателен за любую помощь.Спасибо.
Редактировать : Следуя вашему совету, я создал промежуточную функцию с помощью cdef, которая выглядит следующим образом:
cdef void cSetCallBack(Function1 function):
SetCallBack(function)
Это, похоже, до меня дошло... ближе?По крайней мере, теперь появляется другая ошибка:
error: invalid conversion from ‘void (*)(short unsigned int*, unsigned int, unsigned int)’ to ‘void (*)(const uint16_t*, unsigned int, unsigned int)’
Теперь, насколько я могу судить, эти типы идентичны, поэтому я не могу понять, что происходит.
Edit2 : исправил эту проблему, объявив новый typedef:
ctypedef unsigned short uint16_t
и использовав его в качестве аргумента для вызова, но, очевидно, это на самом деле не приближалось, а просто заставляло меня обходить боковую дорожку,поскольку при попытке вызвать эту функцию я снова и снова получаю ту же ошибку «Невозможно преобразовать объект Python в« Function1 »».
Итак, я почти вернулся к тому, с чего начал.Единственное, что я могу сделать сейчас - это явно привести объект python, поступающий как функция переменного тока, но, честно говоря, я не знаю, как бы я поступил об этом.
Редактироватьтретий : Хорошо, после разбора вашего ответа я, наконец, получил его, и он работает, так что ура и еще много чего.Я закончил тем, что создал такую функцию:
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
Так что теперь единственная проблема в том, что он не может преобразовать данные const_ushort * в объект python, но это совершенно другая проблема, так что я думаю,это решено, большое спасибо.