我一直在尝试使用Cython来接口一个用C++编写的库。到目前为止,情况还不错,我可以有效地使用库中的大多数函数。我的唯一问题在于实现回调函数。该库有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)’
今日免费次数已满, 请开通会员/明日再来
ctypedef unsigned short uint16_t
使用这个作为调用的参数,但显然这并没有使我更接近解决问题,而只是把我带到了一个岔路口,因为在尝试调用该函数时,我又一次收到了“无法将Python对象转换为'Function1'”的错误信息。
所以,我现在基本上回到了起点。现在唯一能想到的就是显式地将输入的Python对象强制转换成C函数,但说实话,我不知道该怎么做。
第三次编辑: 好吧,在分析了你的答案之后,我终于明白了,并且它也能够工作,所以欢呼一下。我最终做的事情是创建一个像这样的函数:
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对象,但这完全是另一个问题,所以我想这个问题已经解决了,非常感谢。
short unsigned int*
更改为const short unsigned int*
。 - aschepler