使用多个模块中的函数类型时出现错误的签名错误

时间:2014-04-03 17:40:27

标签: python function module cython

我有以下Cython模块:

compmech    
    integrate
        integratev.pxd
        integratev.pyx
    conecyl
        main.pyx

在我integratev.pxd宣布:

ctypedef void (*f_type)(int npts, double *xs, double *ts, double *out,
                    double *alphas, double *betas, void *args) nogil

cdef int trapz2d(f_type f, int fdim, np.ndarray[cDOUBLE, ndim=1] final_out,
                 double xmin, double xmax, int m,
                 double ymin, double ymax, int n,
                 void *args, int num_cores)

我从trapz2d致电main.pyx,传递给trapz2d的函数在main.pyx中声明,例如:

from compmech.integrate.integratev cimport trapz2d

cdef void cfk0L(int npts, double *xs, double *ts, double *out,
                double *alphas, double *betas, void *args) nogil:
    ...

trapz2d(<f_type>cfk0L, fdim, k0Lv, xa, xb, nx, ta, tb, nt, &args, num_cores)

它编译得很好,但是当我运行时我得到了错误:

TypeError: C function compmech.integrate.integratev.trapz2d has wrong signature       
(expected int (__pyx_t_8compmech_9integrate_10integratev_f_type, int, PyArrayObject *,
               double, double, int, double, double, int, void *, int),
 got int (__pyx_t_10integratev_f_type, int, PyArrayObject *,
          double, double, int, double, double, int, void *, int))

对我来说这似乎是个错误,但也许我在这里错过了一些重要的事情......


注意:当我将所有内容放在main.pyx内而不是使用多个模块时,它会起作用。

1 个答案:

答案 0 :(得分:0)

解决方案是将所有内容作为void *传递,然后在<f_type>内实际执行函数之前强制转换为trapz2d()。代码的最终布局是:

ctypedef void (*f_type)(int npts, double *xs, double *ts, double *out,
                    double *alphas, double *betas, void *args) nogil

cdef int trapz2d(void *fin, int fdim, np.ndarray[cDOUBLE, ndim=1] final_out,
                 double xmin, double xmax, int m,
                 double ymin, double ymax, int n,
                 void *args, int num_cores)
    cdef f_type f
    f = <f_type>fin
    ...

和其他代码:

from compmech.integrate.integratev cimport trapz2d

cdef void cfk0L(int npts, double *xs, double *ts, double *out,
                double *alphas, double *betas, void *args) nogil:
    ...

trapz2d(<void *>cfk0L, fdim, k0Lv, xa, xb, nx, ta, tb, nt, &args, num_cores)