python - 如何在 Cython 中将函数指针传递给外部程序

标签 python 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 库

最佳答案

我猜你知道 this

<罢工>

Is it possible to call my Python code from C?

Answer: Yes, easily. Follow the example in Demos/callback/ in the Cython source distribution

因此,知道您可以加载 main 函数,让我们采取另一种方法。我写了几个愚蠢的函数来测试这个:

/* 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

关于python - 如何在 Cython 中将函数指针传递给外部程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8800838/

相关文章:

c++ - 如何通过 Cython 处理 C++ 包装中的双指针

python - 在 numpy 数组中查找条件索引的最快方法

javascript - Django 和tinymce

python - 使用 SWIG 打印为 Python 包装的 C++ 类时不调用 __str__()

python - 如何检查 Python 模块的版本?

python - 只保留某一天 python 的最后一个时间戳

c - 在 cython 中包装一个 c 库,其中包含一个 python 内部 c 符号

python - 为什么在 Python 3 中索引字符串而不是切片时会出现 IndexError?

python - Pypi 和 Cython

python - Cythonized 函数出乎意料地慢