如何在Cython中将函数指针传递给外部程序 [英] How to pass a function pointer to an external program in Cython

查看:102
本文介绍了如何在Cython中将函数指针传递给外部程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为C程序编写包装程序,以便可以从Python调用它。我正在使用Cython来执行此操作。 C函数将回调函数作为参数,但是此回调函数仅在python程序运行时才知道。我一直在搜索如何执行此操作,似乎没有简单的解决方案,但以下方法似乎可行:

I am trying to write a wrapper around a C program so that I can call it from Python. I am using Cython to do this. The C function takes a callback function as an argument, but this call back function will only be known at run-time of the python program. I have been searching how to do this and it seems there is not simple solution but the following seems to work:

#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中,还有其他更简单的方法吗?

This method works for C and FORTRAN functions (i am assuming it will work for most compiled languges) and Python functions (using C types), but it seems a little awkward. Is there any more simple way of doing this in Cython?

谢谢

编辑:我是无法更改我要包装的C库

推荐答案

我想您知道


是否可以从C调用我的Python代码?

Is it possible to call my Python code from C?

答案:是的,很容易。请按照Demos / callback /中
Cython源分布中的示例

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

知道您可以卸载您的主要功能,让我们采取另一种方法。我写了几个愚蠢的函数来测试:

So, knowing that you can dload your main function, let's take another approach. I wrote a couple of stupid functions to test this:

/* 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传递以下内容:

Which can be passed directly from 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函数:

And now, let's wrap a Python function:

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

这篇关于如何在Cython中将函数指针传递给外部程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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