目前我正在尝试Cython,想看看,如果我能用这种语言写我的整个项目,不幸的是,我有一个相当大的问题。
我有一个C库,我们称它为“lib.C”,从中导入一个函数:

cdef extern from 'lib.c':
    double compute(double params[7], double IN[2])

现在,我想将此函数分配给一个不必从Python访问的任意变量:
K = compute

这在Python中根本没有问题,但是在编译时我会得到错误
无法将“double(double*,double*)”转换为Python对象。
用Cython函数包装C函数也不起作用。如果我知道
cdef double _K_wrap(double params[7], double IN[2]):
    return compute(params, IN)

K = _K_wrap

我也有同样的错误。
对于如何将C函数分配给Python/Cython变量的任何建议都将非常感谢。提前谢谢!
编辑:
好吧,我只是尝试了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)

这会导致同样的错误。可能我在调用方法中做错了什么。

最佳答案

你必须用一个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)

然后
>>> import wrap
>>> wrap.example([1.1]+range(6), [4.4, 1.])
8.64

10-06 05:31
查看更多