2017-07-15 10 views
1

PythonプログラムのByteArray変数を、Pythonで遅すぎる処理を高速化するためにC言語で書かれたDLLに渡したいとします。私はWebを通過し、Byref、キャスト、memoryviews、addressofの組み合わせでCtypesを試しましたが、何も動作しません。私の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関数に最初のパラメータ(のMyData)を通過するとき、私は型エラーを取得:ここに は、私がやろうとしていますものです。

C関数のメリットを浪費するオーバーヘッドをあまり必要としないソリューションはありますか?

オリヴィエ

+0

は 'ByteArray'何ですか?それは 'bytearray'(小文字)であってはならないのですか?あなたはPython 3を使用していますか? –

+0

はい、bytearray、ごめんなさい。 – Marmotte06

+0

同じ長さのctypes配列型を作成し、その 'bytearray'を[' from_buffer'](https://docs.python.org/3/library/ctypes)に渡してください。 html#ctypes._CData.from_buffer)コンストラクタ、例えば'L = len(MyData);' 'P =(ctypes.c_char * L).from_buffer(MyData);' 'dll.FastProc(P、L)'です。 – eryksun

答えて

0

私はByteArraybytearrayことになっていることを前提としています。 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

Mmmm、一見して私はあなたが解決策を見つけたと思っていましたが、私はcreate_string_bufferの文書に行きました。私はそれが新しいオブジェクトを作成し、元のbytearrayをxopiesしています。これは、最後にmydataではなく新しいデータを印刷する理由です。私は、私の機能は元のバイテリアで、コピーを一切使わずにインプレースで動作することを望んでいます。 BytearraysはPythonの法律に違反してはいけない、変更可能です。私は、私が欲しいものを達成するためにSWIGを推薦する投稿を見つけました。私はこれを掘り下げる必要があります。あなたの助けをありがとう、私はcreate_string_buffer関数を発見した – Marmotte06

関連する問題