私はこのように定義したctypes配列を持っています:
buff= (c_ubyte*buff_size)()
バッファをデータでいっぱいにした後、このデータをバイト形式にする必要があります。今、私はそれを次のようにやっています:
buff= [n for n in buff]
buff = ''.join(map(chr, buff))
これに伴う問題は、それを1バイト文字列に戻す前に4バイト(または任意のバイト数)のintに変換することであり、これは多くのCPUを浪費します。
Ctypesバッファを直接バイトに変換するにはどうすればよいですか?元のバッファを保持できないため、とにかくコピーを実行する必要があるため、自分でコピーを保存しようとはしていません。 pythonにはそのようなもののキャスト機能がありますか?
ありがとう。
コピーが必要な場合は、bytearray
を使用できます。
_>>> buff = (c_ubyte * 4)(*[97,98,99,100])
>>> bs = bytearray(buff)
>>> bs
bytearray(b'abcd')
>>> str(bs)
'abcd'
_
編集:
bytearray
がない2.6より前のバージョンのPython)の場合、代わりに次のいずれかを使用できます。
cast(buff, c_char_p).value
buffer(buff)[:]
同じバッファを共有したい場合は、_c_char
_配列を作成できます。
_>>> buff2 = (c_char * len(buff)).from_buffer(buff)
>>> buff2.value # string copy
'abcd'
>>> buff2[:] = 'efgh'
>>> buff[:] # modified original
[101, 102, 103, 104]
_
編集:
_
from_buffer
_クラスメソッドは2.6で追加されました。以前のバージョンでは、cast
を使用できます。
buff2 = cast(buff, POINTER(c_char * len(buff)))[0]
そもそも_c_char
_配列を使用していない理由はありますか?数値配列と文字列の両方として使用する必要があるかどうかを理解しています。
補遺:
2番目の方法は、バッファをコピーしないため、より「キャスト」されます。最初のアプローチでは、2回コピーされます。1回目はbytearray
を作成し、もう1回はstr
を作成します(bytes
は2のstr
のエイリアスです。バツ)。しかし、bytearray
には文字列メソッドがあり、必要なのはそれだけかもしれません。これは基本的に3.xbytes
の変更可能なバージョンです。
_c_char
_はC char
型です。配列に乗算すると、現在の_c_ubyte
_配列のようなバイトの可変バッファーになります。ただし、Pythonバイト文字列を返すvalue
およびraw
記述子があるため、_c_ubyte
_よりも便利な場合があります。整数ではなく、1文字のバイト文字列として繰り返されます。
あなたがすることになっていないことは、_c_char_p
_--文字データへのポインタ-をPython文字列(関数がそれを変更する場合)から作成することです。Python文字列オブジェクトは不変です。バッファを変更すると奇妙なバグが発生する可能性があります。最近 質問に回答しました そのトピックについて。