2015-11-26 51 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