Reputation: 1524
At the moment I'm trying out Cython and want to see, if I can write my whole project in this language, unfortunately I have quite a problem.
I've got a C library lets call it "lib.c" from which I import a function:
cdef extern from 'lib.c':
double compute(double params[7], double IN[2])
Now I want to assign this function to an arbitrary variable which does not have to be accessible from Python:
K = compute
which is no problem at all in Python, but on compiling I get the error
Cannot convert 'double (double *, double *)' to Python object.
Wrapping the C function with a Cython function does not work either. If e.g. I do
cdef double _K_wrap(double params[7], double IN[2]):
return compute(params, IN)
K = _K_wrap
I get the same error.
Any suggestions of how to assign a C function to a Python/ Cython variable would be greatly appreciated. Thanks in advance!
EDIT:
OK, I just tried the suggestion of hivert:
ctypedef double (*Func)(double params[7], double IN[2])
cdef class FunctionHandler:
cdef Func K
def __cinit__(self, Func f):
self.K = f
def __call__(self, double params[7], double IN[2]):
return self.K(params, IN)
K = FunctionHandler(compute)
This results in the same error. Probably I did something wrong in the __call__ method.
Upvotes: 3
Views: 954
Reputation: 10667
You have to wrap your function in a cdef class
:
cdef extern from 'lib.c':
double compute(double params[7], double IN[2])
ctypedef double (*Func)(double params[7], double IN[2])
cdef class FunctionHandler:
cdef Func K
# def __cinit__(self, Func f):
# self.K = f
def __init__(self):
raise Exception, "FunctionHandler cannot be instanciated from Python"
def __call__(self, list pm, list inn):
cdef double parm[7], cin[2]
for i in range(7):
parm[i] = pm[i]
for i in range(2):
cin[i] = inn[i]
return self.K(parm, cin)
cdef CreateFunctionHandler(Func f):
cdef FunctionHandler res = FunctionHandler.__new__(FunctionHandler)
res.K = f
return res
example = CreateFunctionHandler(compute)
then
>>> import wrap
>>> wrap.example([1.1]+range(6), [4.4, 1.])
8.64
Upvotes: 2