我有一个cdef函数,该函数的参数中有一个函数。我试图生成一个将调用它的python'包装器'函数。我知道将函数定义为cpdef()可以访问该函数的python版本。但是,如果这样做,我将得到一个错误(如预期的那样),该错误表示python无法识别我提供的函数定义。
有什么建议吗?
我的原始函数是特定于域的,而且时间很长,但是我认为以下示例说明了我所追求的目标。我将定义以下 cdef()函数,
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)
答案 0 :(得分:3)
如果您确实需要这样做(可以考虑进行重构,那么就不用了)-您需要某种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