[英]Importing C function with cython, how to pass a pointer to a python function
[英]How to pass a function pointer to an external program in Cython
我正在尝试围绕 C 程序编写一个包装器,以便我可以从 Python 中调用它。 我正在使用 Cython 来做到这一点。 C 函数接受一个回调函数作为参数,但是这个回调函数只会在 python 程序的运行时被知道。 我一直在寻找如何做到这一点,似乎没有简单的解决方案,但以下似乎有效:
#python.py
libc = cdll.LoadLibrary("myfunc.so") #Callback function is defined in myfunc.so
....
c_wrapper(libc.fun, ...)
.
#c_wrapper.pyx
cdef extern void mainfunction(void *F, ...) #The intial C function we are wrapping
ctypedef void (*myfuncptr) ()
def c_wrapper(f, ...) # our function pointer is passed to the wrapper as a Python object
cdef myfuncptr thisfunc
thisfunc = (<myfuncptr*><size_t>addressof(f))[0]
mainfunction(thisfunc, ...)
这种方法适用于 C 和 FORTRAN 函数(我假设它适用于大多数编译语言)和 Python 函数(使用 C 类型),但似乎有点尴尬。 在 Cython 中有没有更简单的方法来做到这一点?
谢谢
编辑:我无法更改我试图包装的 C 库
我想你知道
这一点吗?
是否可以从 C 调用我的 Python 代码?
回答:是的,很容易。 按照 Cython 源代码分发中的 Demos/callback/ 中的示例进行操作
因此,知道您可以 dload 主函数,让我们采取另一种方法。 我写了几个愚蠢的函数来测试这个:
/* lib.c -> lib.so */
#include <stdio.h>
void fn1(void) {
puts("Called function 1");
}
void fn2(void) {
puts("Called function 2");
}
然后,接受回调的函数
/* main.c -> main.so */
typedef void (*callback)();
void mainfunction(void *F) {
((callback)F)();
}
可以直接从 Python 传递:
>>> from ctypes import cdll
>>> lib = cdll.LoadLibrary('./lib.so')
>>> main = cdll.LoadLibrary('./main.so')
>>> main.mainfunction(lib.fn1)
Called function 1
>>> main.mainfunction(lib.fn2)
Called function 2
现在,让我们包装一个 Python 函数:
>>> from ctypes import CFUNCTYPE
>>> def pyfn():
... print "Called the Python function"
...
>>> CWRAPPER = CFUNCTYPE(None)
>>> wrapped_py_func = CWRAPPER(pyfn)
>>> main.mainfunction(wrapped_py_func)
Called the Python function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.