2015-11-26 49 views
0

我想用一个数组作为参数(指针)并使用它做一些事情。但我找不到如何为cdef函数定义数组参数。这是我制作的一些玩具代码。从一个Cdef函数返回一个数组

cdef void test(double[] array ) except? -2: 
    cdef int i,n 
    i = 0 
    n = len(array) 
    for i in range(0,n): 
    array[i] = array[i]+1.0 



def ctest(a): 
    n = len(a) 
    #Make a C-array on the heap. 
    cdef double *v 
    v = <double *>malloc(n*sizeof(double)) 
    #Copy in the python array 
    for i in range(n): 
     v[i] = float(a[i]) 
    #Calling the C-function which do something with the array 
    test(v) 
    #Puttint the changed C-array back into python 
    for i in range(n): 
     a[i] = v[i] 
    free(v) 
    return a 

该代码不会编译。有搜索如何在Cython中定义C数组,但还没有找到如何去做。 double []数组显然不起作用。也曾尝试用:

cdef void test(double* array ) except? -2: 

我可以设法做纯C相同,但不是在用Cython :(

D:\cython-test\ python setup.py build_ext --inplace 
    Compiling ctest.pyx because it changed. 
    [1/1] Cythonizing ctest.pyx 

    Error compiling Cython file: 
    ------------------------------------------------------------ 
    ... 
    from libc.stdlib cimport malloc, free 

    cdef void test(double[] array): 
     cdef int i,n 
     n = len(array) 
       ^
    ------------------------------------------------------------ 

    ctest.pyx:5:17: Cannot convert 'double *' to Python object 

    Error compiling Cython file: 
    ------------------------------------------------------------ 
    ... 
    from libc.stdlib cimport malloc, free 

    cdef void test(double[] array): 
     cdef int i,n 
     n = len(array) 
     for i in range(0,len(array)): 
           ^
    ------------------------------------------------------------ 

    ctest.pyx:6:30: Cannot convert 'double *' to Python object 
    Traceback (most recent call last): 
    File "setup.py", line 10, in <module> 
     ext_modules = cythonize("ctest.pyx"), 
    File "C:\Anaconda\lib\site-packages\Cython\Build\Dependencies.py", line   877, i 
    n cythonize 
     cythonize_one(*args) 
    File "C:\Anaconda\lib\site-packages\Cython\Build\Dependencies.py", line 997, i 
    n cythonize_one 
     raise CompileError(None, pyx_file) 
    Cython.Compiler.Errors.CompileError: ctest.pyx 

    E:\GD\UD\Software\BendStiffener\curvmom> 

UPDATE:

已经更新了我的代码毕竟建议,它现在编译:)但我的数组仍然没有更新。我希望所有参赛作品必须用5.0更新,但他们没有

from libc.stdlib cimport malloc, free 

cdef void test(double[] array): 
    cdef int i,n 
    n = sizeof(array)/sizeof(double) 
    for i in range(0,n): 
     array[i] = array[i]+5.0 

def ctest(a): 
    n = len(a) 
    #Make a C-array on the heap. 
    cdef double* v 
    v = <double*>malloc(n*sizeof(double)) 
    #Copy in the python array 
    for i in range(n): 
     v[i] = float(a[i]) 
    #Calling the C-function which do something with the array 
    test(v) 
    #Puttint the changed C-array back into python 
    for i in range(n): 
     a[i] = v[i] 
    free(v) 
    for x in a: 
     print x 
    return a 

下面是测试我的代码的Python测试程序:

import ctest 
a = [0,0,0] 
ctest.ctest(a) 

那么还有什么我做错了。任何建议?

+0

您必须发布错误消息。 –

回答

0

len()是一个仅适用于python对象的python函数。这就是它不能编译的原因。 对于C型阵列,您可以用n = sizeof(array)/sizeof(double)代替n=len(array)

0

您可能想看看typed memoryviews和缓冲区界面。这些提供了一个像数组结构一样的好接口,比如那些底层的numpy数组,但也可以用来处理C数组。从文档:

例如,他们可以处理C数组和Cython数组类型(Cython arrays)。

你的情况,这可能帮助:

cdef test(double[:] array) except? -2: 
    ... 

double[:]允许所有1D双阵列传递给函数。那些可以被修改。由于[:]定义了一个内存视图,所有更改将在您创建内存视图的数组(您作为参数传递给test)的数组中进行。

+0

我会研究一下 – fossekall