Py学习  »  Python

如何在python中调用包含作为参数的函数的cython cdef()函数?

marcos • 5 年前 • 1300 次点击  

我有一个cdef函数,它的参数中有一个函数。我正在尝试生成一个python“wrapper”函数来调用它。我知道将一个函数定义为cpdef()我将能够访问该函数的python版本。但是,如果我这样做了,我将得到一个错误(如预期的那样),表明python无法识别我提供的函数定义。

有什么建议吗?

我最初的功能是特定于领域的,并且很长时间,但是我认为下面的示例捕获了我所追求的。我要以下的 cFED() 函数定义,

ctypedef double (*ftype) (double)

cdef cy_myfunc(int a,..., double x, ftype f):
  ...
  cdef double result
  result = f(x)

  return result

我想定义如下内容,以便在python中调用它:

def py_myfunc(a,..., x, f):
    return cy_myfunc(a,...,x,f)
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/43218
 
1300 次点击  
文章 [ 1 ]  |  最新文章 5 年前
chrisb
Reply   •   1 楼
chrisb    6 年前

如果你真的需要这样做(可能会考虑重构,所以你不需要)-你需要某种 PyObject 存储c函数指针。

这个 PyCapsule api提供了一种在python空间中传递不透明指针的方法。我可能会做这样的事,我可能漏掉了一些安全检查

%%cython
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_GetPointer

ctypedef double (*ftype) (double)

# c function you want to wrapper
cdef double f(double a):
    return a + 22.0

# wrapper capsule
wrapped_f = PyCapsule_New(<void*>f, 'f', NULL)

cdef cy_myfunc(double x, ftype f):
  cdef double result = f(x)
  return result

def py_myfunc(double x, object f_capsule):
    cdef ftype f = <ftype> PyCapsule_GetPointer(f_capsule, 'f')
    return cy_myfunc(x, f)

用法

wrapped_f
# Out[90]: <capsule object "f" at 0x0000000015ACFE70>

py_myfunc(2, wrapped_f)
# Out[91]: 24.0