2010-08-19 75 views
0

我有C代碼,它使用變量data,這是一個用malloc創建的可變大小的大型二維數組。現在我必須編寫一個接口,以便可以在Python中調用C函數。我使用ctypes。訪問一個變量的變量被鑄造成int數組的指針python

C代碼:

FOO* pytrain(float **data){ 
    FOO *foo = foo_autoTrain((float (*)[])data); 
    return foo; 
} 

FOO *foo_autoTrain(float data[nrows][ncols]) {...} 

Python代碼:

autofoo=cdll.LoadLibrary("./libfoo.so") 
... data gets filled ... 
foo = autofoo.pytrain(pointer(pointer(p_data))) 

我的問題是,當我嘗試訪問data在foo_autoTrain我只得到0.0或其他隨機值和稍後的seg故障。那麼我怎麼能通過float (*)[])data到Python的foo_autoTrain?

請不要猶豫,指出,如果我描述了我的問題的一些部分不夠。

回答

0

它看起來像我這個問題是多維數組如何在C中工作的誤解。像a[r][c]這樣的表達式可能意味着兩種情況之一,具體取決於a的類型。如果a類型是float **,那麼,如果做出來的長手錶達將意味着一個雙指針偏移解引用,像這樣:

float *row = a[r]; // First dereference yields a pointer to the row array 
return row[c]  // Second dereference yields the value 

如果a類型是不是float (*)[ncols],則表達式變成簡單地簡寫爲成形的連續的一維存儲器區域作爲一個多維數組:

float *flat = (float *)a; 
return flat[(r * ncols) + c]; // Same as a[r][c] 

所以在C代碼,pytrain()的參數的類型應該是float *float (*)[ncols]和你的Python代碼看起來應該像下面這樣(假設你使用NumPy的爲你的陣列數據):

c_float_p = ctypes.POINTER(ctypes.c_float) 
autofoo.pytrain.argtypes = [c_float_p] 
data = numpy.array([[0.1, 0.1], [0.2, 0.2], [0.3, 0.3]], dtype=numpy.float32) 
data_p = data.ctypes.data_as(c_float_p) 
autofoo.pytrain(data_p) 

如果你實際上使用與NumPy,檢查出ctypes page of the SciPy wiki