将1或2维numpy数组传递给c throw cython

将1或2维numpy数组传递给c throw cython,numpy,cython,python-c-api,Numpy,Cython,Python C Api,我正在用c和cython编写python代码的扩展,方法是遵循指南 我的c函数签名是 void c_disloc(double *pEOutput, double *pNOutput, double *pZOutput, double *pModel, double *pECoords, double *pNCoords, double nu, int NumStat, int NumDisl) 我的cython函数是 cdef extern void c_disloc(double *pEO

我正在用c和cython编写python代码的扩展,方法是遵循指南

我的c函数签名是

void c_disloc(double *pEOutput, double *pNOutput, double *pZOutput, double *pModel, double *pECoords, double *pNCoords, double nu, int NumStat, int NumDisl)
我的cython函数是

cdef extern void c_disloc(double *pEOutput, double *pNOutput, double *pZOutput, double *pModel, double *pECoords, double *pNCoords, double nu, int NumStat, int NumDisl)

@cython.boundscheck(False)
@cython.wraparound(False)
def disloc(np.ndarray[double, ndim=2, mode="c"] pEOutput not None,
           np.ndarray[double, ndim=2, mode="c"] pNOutput not None,
           np.ndarray[double, ndim=2, mode="c"] pZOutput not None,
           np.ndarray[double, ndim=1, mode="c"] pModel not None,
           np.ndarray[double, ndim=2, mode="c"] pECoords not None,
           np.ndarray[double, ndim=2, mode="c"] pNCoords not None,
           double nu,int NumStat, int NumDisl ):

    c_disloc(&pEOutput[0,0], &pNOutput[0,0], &pZOutput[0,0], &pModel[0], &pECoords[0,0], &pNCoords[0,0], nu, NumStat, NumDisl)

    return None
现在,我的c函数具有相同的行为,无论它获取的数组是1d还是2d数组,但我没有成功地使cython函数能够获取1d或2d numpy数组。 当然,我可以编写两个cython函数,一个用于1d,一个用于2d,但是使用一个函数会更简洁。
有人知道怎么做吗?

我会接受一个非类型化的参数,检查它是否是一个C连续数组,然后使用
np.ravel
获得一个平面数组(当传递一个C连续数组时,返回的是一个视图,而不是副本)。很容易将其创建为cdef函数:

cdef double* get_array_pointer(arr) except NULL:
    assert(arr.flags.c_contiguous) # if this isn't true, ravel will make a copy
    cdef double[::1] mview = arr.ravel()
    return &mview[0]
那你会的

def disloc(pEOutput,
           pNOutput,
           # etc...
           double nu,int NumStat, int NumDisl ):

    c_disloc(get_array_pointer(pEOutput), get_array_pointer(pNOutput),
            # etc
            nu, NumStat, NumDisl)

我已经把灯拆了

@cython.boundscheck(False)
@cython.wraparound(False)

因为很明显,他们会让你几乎一无所获。在我看来,使用它们而不考虑它们是否会做任何事情就像是货物崇拜编程

我接受一个非类型化的参数,检查它是否是一个C连续数组,然后使用
np.ravel
获得一个平面数组(当传递一个C连续数组时,它返回一个视图,而不是副本)。很容易将其创建为cdef函数:

cdef double* get_array_pointer(arr) except NULL:
    assert(arr.flags.c_contiguous) # if this isn't true, ravel will make a copy
    cdef double[::1] mview = arr.ravel()
    return &mview[0]
那你会的

def disloc(pEOutput,
           pNOutput,
           # etc...
           double nu,int NumStat, int NumDisl ):

    c_disloc(get_array_pointer(pEOutput), get_array_pointer(pNOutput),
            # etc
            nu, NumStat, NumDisl)

我已经把灯拆了

@cython.boundscheck(False)
@cython.wraparound(False)
因为很明显,他们会让你几乎一无所获。在我看来,使用它们而不考虑它们是否会做任何事情就像是货物崇拜编程