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

标签 python c function callback cython

我有以下问题。 我们必须将回调函数传递给 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 wrapperCubature 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/

相关文章:

python - 稠密矩形矩阵乘以稀疏矩阵

比较整数函数 SIGSEGV

c - yacc 从非终端获取零值

java8 将数学运算符应用于函数的可能性

c++ - 使用数组和结构的四分卫评级函数表现得很奇怪

python - Django TextField 始终是必需的,尽管 blank=True,Null=True

python - 从包含多个模式的列表中查找字符串

python - 如何避免 tkinter 的 IntVar.get() 在空白字符串上引发 TclError

c - 在字符串上使用sscanf时,如何正确使用(否定的)字符类或扫描集?

c - 在 C 中定义一个函数两次