Как вызвать функцию cyde cdef (), которая содержит в качестве параметра функцию в python? - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть функция 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)

1 Ответ

0 голосов
/ 05 декабря 2018

Если вам это действительно нужно (возможно, вам стоит подумать о рефакторинге), вам понадобится какой-то 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
...