14

次のように定義した ctypes 配列があります。

buff= (c_ubyte*buff_size)()

バッファをデータでいっぱいにした後、このデータをバイト形式にする必要があります。現在、私は次のようにしています。

buff= [n for n in buff]
buff = ''.join(map(chr, buff))

これに関する問題は、それを 4 バイト (または任意のバイト数) の int に変換してから 1 バイトの文字列に戻すことであり、これにより多くの CPU が浪費されます。

ctypes バッファをバイトに直接変換するにはどうすればよいですか? 元のバッファを保持できないため、とにかくコピーを作成する必要があるため、コピーを保存しようとはしていません。Pythonにはそのようなもののためのキャスト機能がありますか?

ありがとう。

4

1 に答える 1

19

コピーが必要な場合は、次を使用できますbytearray

>>> buff = (c_ubyte * 4)(*[97,98,99,100])
>>> bs = bytearray(buff)
>>> bs
bytearray(b'abcd')
>>> str(bs)
'abcd'

編集

が欠けている 2.6 より前のバージョンの Python ではbytearray、代わりに次のいずれかを使用できます。

  • 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_bufferclass メソッドは 2.6 で追加されました。以前のバージョンでは、次を使用できますcast

  • buff2 = cast(buff, POINTER(c_char * len(buff)))[0]

c_charそもそも配列を使用していない理由はありますか? 数値配列と文字列の両方として使用する必要があるかどうかは理解しています。

補遺:

2番目の方法は、バッファをコピーしないため、より「キャスト」に似ています。最初のアプローチでは、2 回コピーさbytearraystrます。しかし、 aには文字列メソッドがあり、必要なのはそれだけかもしれません。基本的には 3.x の変更可能なバージョンです。bytesstrbytearraybytes

c_charCcharタイプです。配列に乗算すると、現在のc_ubyte配列のようなバイトの可変バッファになります。ただし、 Python バイト文字列を返すおよび記述子c_ubyteがあるため、より便利な場合があります。また、整数ではなく 1 文字のバイト文字列としてインデックスを作成し、繰り返します。valueraw

c_char_p関数が it を変更する場合、Python 文字列から a -- 文字データへのポインタ --を作成してはいけません。Python 文字列オブジェクトは不変です。バッファを変更すると、奇妙なバグが発生する可能性があります。私は最近、そのトピックに関する質問に答えました。

于 2013-03-13T10:12:31.707 に答える