C 構造体から PyBuffer を作成する
-
19-09-2019 - |
質問
編集:元の質問を読み直してみると、言葉遣いが非常に悪く、曖昧で、混乱しすぎてまともな答えを得ることができないことがすぐにわかりました。昼休みの終わりに急いで質問をすると、それが得られます。これがより明確になることを願っています:
単純な C 構造を Python (3.x) に PyBuffer として公開して、そこから MemoryView を取得できるようにしようとしています。私が公開したい構造は次のようなものです。
struct ImageBuffer {
void* bytes;
int row_count;
int bytes_per_row;
};
そして、スクリプト作成者が次のようにデータにアクセスできるようにしたいと考えています。
img_buffer = img.get_buffer()
img_buffer[1::4] = 255 # Set every Red component to full intensity
残念ながら、これらの構造の C API に関する既存のドキュメントは非常に希薄で、所々で自己矛盾があり、他の部分では完全に間違っています (ドキュメント化された関数シグネチャがヘッダー内のシグネチャと一致しないなど)。そのため、私にはあまり良いドキュメントがありません。これを最適に公開する方法についてのアイデア。また、コア ライブラリの一部であるべき機能を実現するためにサードパーティのライブラリを含めるのは避けたいと思っていますが、PyBuffer の機能はまだかなり未熟なように感じます。おそらく NumPy のようなものがより良い選択になるでしょう。
これに関して何かアドバイスがある人はいますか?
解決
拡張タイプがバッファ プロトコルをサポートするために実装するメソッドのセットについては、以下で説明します。 http://docs.python.org/3.1/c-api/typeobj.html#buffer-object- Structures
ドキュメントがかなり大雑把であることは認識しているので、私ができる最善のアドバイスは、C 型によるバッファー API の既存の実装 (たとえば、公式 Python ソース コードの bytesobject.c または bytearrayobject.c) から始めることです。
ただし、バッファ プロトコルでは、引用したような高レベルの表記法にはアクセスできないことに注意してください。 img_buffer[1::4] = 255
は、memoryview オブジェクトでは機能しません。
編集: より正確に言うと、メモリビューは一部の種類のスライス割り当てをサポートしていますが、すべてをサポートしているわけではありません。また、スライスに 255 を割り当てるということは、実際にはバイト値を繰り返すことを意味するということを理解できるほど「賢く」はありません。例:
>>> b = bytearray(b"abcd") >>> m = memoryview(b) >>> m[0:2] = b"xy" >>> b bytearray(b'xycd') >>> m[0:2] = 255 Traceback (most recent call last): File "", line 1, in TypeError: 'int' does not support the buffer interface >>> m[0:2] = b"x" Traceback (most recent call last): File "", line 1, in ValueError: cannot modify size of memoryview object >>> m[0::2] = b"xy" Traceback (most recent call last): File "", line 1, in NotImplementedError