バッファインタフェースは、あるオブジェクトの内部データを一連の データチャンク (chunk) として見せるモデルを外部から利用できるようにします。 各チャンクはポインタ/データ長からなるペアで指定します。 チャンクはセグメント(segment) と呼ばれ、 メモリ内に不連続的に配置されるものと想定されています。
バッファインタフェースを利用できるようにしたくないオブジェクト では、PyTypeObject 構造体の tp_as_buffer メンバを NULLにしなくてはなりません。利用できるようにする場合、 tp_as_buffer はPyBufferProcs 構造体を 指さねばなりません。
注意:
PyTypeObject 構造体の tp_flags メンバ
の値を 0
でなく Py_TPFLAGS_DEFAULT に
しておくことがとても重要です。この設定は、
PyBufferProcs 構造体に bf_getcharbuffer
スロットが入っていることを Python ランタイムに教えます。
Python の古いバージョンには bf_getcharbuffer メンバが
存在しないので、古い拡張モジュールを使おうとしている新しいバージョンの
Python インタプリタは、このメンバがあるかどうかテストしてから
使えるようにする必要があるのです。
最初のスロットはbf_getreadbuffer で、 getreadbufferproc 型です。 このスロットが NULLの場合、オブジェクトは内部データの 読み出しをサポートしません。そのような仕様には意味がないので、 実装を行う側はこのスロットに値を埋めるはずですが、呼び出し側では 非 NULL の値かどうかきちんと調べておくべきです。
次のスロットは bf_getwritebuffer で、 getwritebufferproc 型です。オブジェクトが返すバッファに 対して書き込みを許可しない場合はこのスロットをNULL にできます。
第三のスロットは bf_getsegcount で、 getsegcountproc 型です。このスロットは NULL であっては ならず、オブジェクトにいくつセグメントが入っているかを呼び出し側に 教えるために使われます。PyString_Type や PyBuffer_Type オブジェクトのような単純なオブジェクトには単一のセグメントしか入って いません。
最後のスロットは bf_getcharbuffer で、 getcharbufferproc です。オブジェクトの PyTypeObject 構造体における tp_flags フィールドに、 Py_TPFLAGS_HAVE_GETCHARBUFFER ビットフラグがセットされている 場合にのみ、このスロットが存在することになります。 このスロットの使用に先立って、呼び出し側は PyType_HasFeature() を使ってスロットが存在するか調べねばなりません。 フラグが立っていても、bf_getcharbufferは NULLのときもあり、 NULLはオブジェクトの内容を 8 ビット文字列 として利用できない ことを示します。 このスロットに入る関数も、オブジェクトの内容を 8 ビット文字列に 変換できない場合に例外を送出することがあります。例えば、 オブジェクトが浮動小数点数を保持するように設定されたアレイの場合、 呼び出し側が bf_getcharbuffer を使って 8 ビット文字列 としてデータを取り出そうとすると例外を送出するようにできます。 この、内部バッファを ``テキスト'' として取り出すという概念は、 本質的にはバイナリで、文字ベースの内容を持ったオブジェクト間の 区別に使われます。
注意: 現在のポリシでは、文字 (character) はマルチバイト文字 でもかまわないと決めているように思われます。従って、 サイズ N のバッファが N 個のキャラクタからなる とはかぎらないことになります。
*ptrptr
の中の読み出し可能なバッファセグメントへのポインタを返します。
この関数は例外を送出してもよく、送出する場合には -1
を返さねばなりません。
segment に渡す値はゼロまたは正の値で、bf_getsegcount
スロット関数が返すセグメント数よりも必ず小さな値でなければなりません。
成功すると、セグメントのサイズを返し、 *ptrptr
を
そのセグメントを指すポインタ値にセットします。
*ptrptr
に
返し、セグメントの長さを関数の戻り値として返します。エラーによる例外の
場合には -1
を-1
を返さねばなりません。
オブジェクトが呼び出し専用バッファしかサポートしていない場合には
TypeError を、segment が存在しないセグメントを
指している場合には SystemError を送出しなければなりません。
*lenp
を介して
報告しなければなりません。この関数呼び出しは失敗させられません。
-1
を返します。
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。