c – Cython – 实现回调

我一直在使用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对象作为一个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 *数据转换为python对象,但这完全是另一个问题,所以我想这个问题已经解决了,非常感谢.

最佳答案
如果您可以修改库来定义:

typedef void (*Function1)(const uint16_t *data, 
                          unsigned width, unsigned height,
                          void *user_data);
void SetCallBack(Function1, void*);

相反,我担心你运气不好.如果你有void *,那么你定义一个函数调用一个带有正确参数的python可调用对象,而SetCallBack调用这个函数和python可调用.

如果你不能,但回调是全局的(似乎是),你可以创建一个全局变量来存储python对象.比你再次创建一个函数来调用python对象并将它传递给SetCallBack和你的PySetCallback只会设置全局并确保注册正确的函数.

如果回调是特定于上下文的,但你无法将它传递给“用户数据”指针,我担心你在这里运气不好.

我知道python和C,但不是cython,所以我不知道你是否可以在cython中创建函数,或者你是否必须用C语言编写.

转载注明原文:c – Cython – 实现回调 - 代码日志