2012-04-08 59 views
10

我想從Python調用我的C函數,以便操縱一些NumPy數組。功能是這樣的:在Cython和NumPy中包裝C函數

void c_func(int *in_array, int n, int *out_array); 

,其中結果在out_array,其大小我知道事先提供的(不是我的功能,實際上)。我嘗試做相應.pyx文件中的以下,爲了能夠從與NumPy陣列通過輸入功能,並把結果存儲在一個與NumPy陣列:

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array):  
    n = len(in_array) 
    out_array = np.zeros((512,), dtype = np.int32) 
    mymodule.c_func(<int *> in_array.data, n, <int *> out_array.data) 
    return out_array 

,但我得到 "Python objects cannot be cast to pointers of primitive types"輸出分配錯誤。我該如何做到這一點?

(如果我需要Python的調用者分配適當的輸出數組,然後我可以做

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array, np.ndarray[np.int32_t, ndim=1] out_array): 
    n = len(in_array) 
    mymodule.cfunc(<int *> in_array.data, n, <int*> out_array.data) 

但我能做到這一點的方式,調用者不必預先分配適當大小輸出數組?

+1

沒請您儘量提供補充'CDEF np.ndarray'之前'out_array' assignement? – Simon 2012-04-08 17:58:01

+0

工作,謝謝! – Peter 2012-04-08 18:07:57

回答

5

您應該​​assignement前添加cdef np.ndarray

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array):  
    cdef np.ndarray out_array = np.zeros((512,), dtype = np.int32) 
    n = len(in_array) 
    mymodule.c_func(<int *> in_array.data, n, <int *> out_array.data) 
    return out_array 
0

這裏是一個示例如何使用通過ctypes在C/C++中編寫的代碼來處理NumPy數組我寫了一個小函數在C中,從第一個數組中取數的平方並將結果寫入第二個數組,元素個數由第三個參數給出,該代碼被編譯爲共享對象

squares.c編譯squares.so:

void square(double* pin, double* pout, int n) { 
    for (int i=0; i<n; ++i) { 
     pout[i] = pin[i] * pin[i]; 
    } 
} 

在Python中,您使用的ctypes只是加載庫並調用該函數。數組指針是從NumPy ctypes接口獲得的。

import numpy as np 
import ctypes 

n = 5 
a = np.arange(n, dtype=np.double) 
b = np.zeros(n, dtype=np.double) 

square = ctypes.cdll.LoadLibrary("./square.so") 

aptr = a.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) 
bptr = b.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) 
square.square(aptr, bptr, n) 

print b 

這對於任何C語言庫工作,你只需要知道哪些參數類型傳遞,可能使用ctypes的重建C-結構的蟒蛇。

+2

我認爲OP想要使用cython而不是ctypes – Simon 2012-04-08 17:51:22