Python / Cython / C和回调,使用Cython从C调用Python函数 [英] Python/Cython/C and callbacks, calling a Python function from C using Cython

查看:1319
本文介绍了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 \\\
,f(x));
return x;
}

问题如下:方式,使得它也可以接受python函数作为回调参数(当然,需要一些额外的层),以及来自另一个模块的C / Cython函数。我想,对于来自单独模块的C / Cython函数,必须获取这些函数的地址(转换为long int?),对于Python函数,需要一个特定的包装器。

解决方案

在此示例中,从Python包装器 Cubature集成C库,Python函数将传递给C函数具有由 cfunction 给出的原型。您可以使用相同的原型创建一个函数,名为 cfunction_cb (callback),并返回相同类型 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> (fdim)中的k:
fval [k] = fval_buffer [k]
return 0
(a,b,c,* args) / code>

调用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函数。


I have the following question. We have to pass callback functions to the C code. If the function is a Cython function in the same module, the situation is quite simple

In Cython:

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

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

In C:

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

The question is as follows: we want to generalize this code in the most Pythonic way so that it can accept also python functions as callback arguments (of course, some additional layer is needed), and also C/Cython functions from another module. I suppose, for C/Cython functions from a separate module one has to get the address of these functions (convert to long int?) and for Python function a certain wrapper is needed

解决方案

In this example, extracted from a Python wrapper to the Cubature integration C library, a Python function is passed to a C function that has the prototype given by cfunction. You can create a function with the same prototype, called cfunction_cb (callback), and returning the same type, int in this example):

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

When calling the C function, you can cast your callback wrapper using the 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 )

In this example it is also shown how to pass arguments to your Python function, through C.

这篇关于Python / Cython / C和回调,使用Cython从C调用Python函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆