2017-07-15 284 views
1

我想將Python程序中的ByteArray變量傳遞給我用C編寫的DLL,以便加速某些特定的處理,這些處理在Python中速度太慢。我已經通過網絡,嘗試了與C#參數組合,byref,cast,memoryviews,addressof,但沒有任何作用。有沒有簡單的方法來實現這一點,而不是將我的ByteArray複製到其他將會通過的東西? 這裏就是我想要做:將ByteArray從Python傳遞到C函數

/* My C DLL */ 
__declspec(dllexport) bool FastProc(char *P, int L) 
{ 
    /* Do some complex processing on the char buffer */ 
    ; 
    return true; 
} 

# My Python program 
from ctypes import * 
def main(argv): 
    MyData = ByteArray([1,2,3,4,5,6]) 
    dll = CDLL('CHELPER.dll') 
    dll.FastProc.argtypes = (c_char_p, c_int) 
    dll.FastProc.restype = c_bool 

    Result = dll.FastProc(MyData, len(MyData)) 
    print(Result) 

但傳遞的第一個參數(邁德特)C函數時,我得到一個類型錯誤。

是否有任何解決方案不需要太多的開銷會浪費我的C函數的好處?

奧利維爾

+0

什麼是'ByteArray'?它不應該是'bytearray'(全部小寫)嗎?你在使用Python 3嗎? –

+0

是它的一個字節數組,對於輸入錯誤 – Marmotte06

+0

創建一個長度相同的ctypes數組類型,並將'bytearray'傳遞給它的['from_buffer'](https://docs.python.org/3/library/ctypes。 html#ctypes._CData.from_buffer)contsructor,例如'L = len(MyData);''P =(ctypes.c_char * L).from_buffer(MyData);''dll.FastProc(P,L)'。 – eryksun

回答

0

我假設ByteArray應該是bytearray。我們可以使用create_string_buffer來創建一個可變字符緩衝區,它是一個​​數組c_char。但create_string_buffer不是接受bytearray,我們需要傳遞一個bytes對象來初始化它;幸運的是,bytesbytearray之間的投射是快速且高效的。

我沒有你的DLL,因此爲了測試數組的行爲是否正確,我將使用libc.strfry函數來混洗它的字符。

from ctypes import CDLL, create_string_buffer 

libc = CDLL("libc.so.6") 

# Some test data, NUL-terminated so we can safely pass it to a str function. 
mydata = bytearray([65, 66, 67, 68, 69, 70, 0]) 
print(mydata) 

# Convert the Python bytearray to a C array of char 
p = create_string_buffer(bytes(mydata), len(mydata)) 

#Shuffle the bytes before the NUL terminator byte, in-place. 
libc.strfry(p) 

# Convert the modified C array back to a Python bytearray 
newdata = bytearray(p.raw) 
print(newdata) 

典型輸出

bytearray(b'ABCDEF\x00') 
bytearray(b'BFDACE\x00') 
+0

嗯,乍一看我以爲你已經找到了解決方案,但我去了create_string_buffer的文檔,我的理解是它創建了一個新對象,並拷貝了它原來的bytearray。這就是爲什麼在最後你打印新數據而不是mydata。我更喜歡迄今爲止,我的函數就地工作原始字節數組,沒有任何複製。字節數是可變的,不應該違反Python法則。我發現帖子建議SWIG達到我想要的,我需要深入瞭解這一點。非常感謝您的幫助,我發現了create_string_buffer函數 – Marmotte06