从C++调用Cython函数
我有一个C++的库,它有一个Python的包装器(是用SWIG写的)。这个库可以执行一些小的用户自定义代码(叫做回调),比如对向量进行逐元素的操作。也就是说,除了简单的加法,你可以做任何你想要的二元函数。目前的做法是接受一个可调用的Python对象作为这个二元函数,然后调用它。这样是可以的,但每次迭代都要在Python和C++之间来回跳,速度大约慢了80倍。
我该如何编写/构建/导入一个Cython函数,让它可以直接被我的C++库调用呢?
编辑:如果我只用C的话,我会写类似这样的代码:
EWise(double (*callback)(double, double))
然后EWise会像这样调用 callback(10, 20);
。我希望 callback
是用Cython写的,用户可以自定义名字,并且需要通过某种方式将它的指针传递给我的C++库。这个“某种方式”我还不太清楚。
3 个回答
0
你可以看看这篇文章,内容是关于如何把Python嵌入到其他应用程序中的,这可能会对你有帮助。
2
你可以通过使用纯粹的 cdef
函数来实现这个目标:
# declare the prototype of your function
ctypedef void (*callback_ptr)(int arg)
# declare your function as cdef
cdef void my_callback(int arg):
print 'doing some python here', arg
# now, you can use the cdef func as a callback
# in pure C !
cdef void run():
cdef callback_ptr p = my_callback
p(42)
if __name__ == '__main__':
run()
注意:你可以使用 "cython -a" 命令来查看运行的内容中没有涉及任何 Python 代码。因此,它可以和你的 C 库一起工作。
18
使用cython的一个窍门就是要用到一个关键词叫做 public
cdef public double cython_function( double value, double value2 ):
return value + value2
接着,你可以用命令 cythonize <your_file.pyx>
,这个命令会生成一个 <your_file.c>
文件,同时还会创建一个头文件 <your_file.h>
,你可以把这个头文件包含进来。或者,你也可以自己手动创建这个头文件:
#ifdef __cplusplus {
extern "C"
#endif
double cython_function( double value, double value2 );
#ifdef __cplusplus
}
#endif
更新:
然后,借助Python的一些功能,你可以使用 ctypes的回调机制
func_type = CFUNCTYPE(c_double, c_double, c_double)
your_library.set_callback_function ( func_type(user_modules.cython_function) )