Python / Cython / C和回调,使用Cython从C调用Python函数

我有以下问题.
我们必须将回调函数传递给C代码.如果该函数是同一模块中的Cython函数,则情况非常简单

在Cython中:

def callme(int x):
    c_callme(x, <int (*)(int)>&callbackme) 

cdef int callbackme(int x):
    print <int> x
    return <int>x

在C:

int c_callme(int x, int (*f)(int))
{
    printf("---%d\n",x);
    printf("--%d\n",f(x));
    return x;
}

问题如下:我们希望以最Pythonic的方式推广这个代码,以便它也可以接受python函数作为回调参数(当然,还需要一些额外的层),以及来自另一个模块的C/C++ython函数.我想,对于来自单独模块的C/C++ython函数,必须获取这些函数的地址(转换为long int?),对于Python函数,需要某个包装器

最佳答案
在这个例子中,extracted from a Python wrapperCubature integration C library,Python函数被传递给C函数,该函数具有由cfunction给出的原型.您可以使用相同的原型创建一个函数,称为cfunction_cb(回调),并返回相同的类型,在此示例中为int):

cdef object f
ctypedef int (*cfunction) (double a, double b, double c, void *args)

cdef int cfunction_cb(double a, double b, double c, void *args):
    global f
    result_from_function = (<object>f)(a, b, c, *<tuple>args)
    for k in range(fdim):
        fval[k] = fval_buffer[k]
    return 0

调用C函数时,可以使用C原型强制转换回调包装:

def main(pythonf, double a, double b, double c, args): 
    global f
    f = pythonf
    c_function( <cfunction> cfunction_cb,
                double a,
                double b,
                double c,
                <void *> args )

在这个例子中,还展示了如何通过C将参数传递给Python函数.

转载注明原文:Python / Cython / C和回调,使用Cython从C调用Python函数 - 代码日志