我有以下问题。 我们必须将回调函数传递给 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/Cython 函数模块。我想,对于来自单独模块的 C/Cython 函数,必须获取这些函数的地址(转换为 long int?),对于 Python 函数,需要特定的包装器
最佳答案
在这个例子中,extracted from a Python wrapper到 Cubature integration C library ,一个 Python 函数被传递给一个 C 函数,该函数具有 cfunction
给出的原型(prototype)。您可以创建一个具有相同原型(prototype)的函数,称为 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 原型(prototype)转换回调包装器:
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 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11700501/