我一直在与 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 对象作为 ac 函数传入,但是,老实说,我不知道该怎么做。
编辑第三个:好吧,在剖析你的答案之后,我终于明白了,它有效,所以万岁等等。我最终做的是创建一个这样的函数:
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 *data 转换为 python 对象,但这完全是另一个问题,所以我想这个问题已经解决了,非常感谢。