How to call a cython cdef() function that contains as a parameter a function in python?

丶灬走出姿态 提交于 2020-01-06 12:38:21

问题


I have a cdef function that has amongst its parameters a function. I am trying to generate a python 'wrapper' function that will call it. I know that defining a function as cpdef() I would be able to get access to a python version of the function. However, if I do this, I will get an error (as expected) that says that python cannot recognize the function definition I provided.

Any suggestions?

My original function is domain specific and quite long but I think that the following example captures what I am after. I would have the following cdef() function defined,

ctypedef double (*ftype) (double)

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

  return result

and I would like to define something like the following so that I can call it in python:

def py_myfunc(a,..., x, f):
    return cy_myfunc(a,...,x,f)

回答1:


If you actually need to this (might think about refactoring so you don't) - you need some kind of PyObject to store the c function pointer.

The PyCapsule api provides a way of passing opaque pointers around in python space. Could do something like this, I'm probably missing some safety checks

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

Usage

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

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


来源:https://stackoverflow.com/questions/53619438/how-to-call-a-cython-cdef-function-that-contains-as-a-parameter-a-function-in

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!