ctypes
には別のことを期待しているのに実際に起きる起きることは違うという場合が
あります。
次に示す例について考えてみてください:
>>> from ctypes import * >>> class POINT(Structure): ... _fields_ = ("x", c_int), ("y", c_int) ... >>> class RECT(Structure): ... _fields_ = ("a", POINT), ("b", POINT) ... >>> p1 = POINT(1, 2) >>> p2 = POINT(3, 4) >>> rc = RECT(p1, p2) >>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y 1 2 3 4 >>> # now swap the two points >>> rc.a, rc.b = rc.b, rc.a >>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y 3 4 3 4 >>>
うーん、最後の文に3 4 1 2
と表示されることを期待していたはずです。
何が起きたのでしょうか?上の行のrc.a, rc.b = rc.b, rc.a
の
各段階はこのようになります:
>>> temp0, temp1 = rc.b, rc.a >>> rc.a = temp0 >>> rc.b = temp1 >>>
temp0
とtemp1
は前記のrc
オブジェクトの内部バッファで
まだ使われているオブジェクトです。したがって、rc.a = temp0
を実行すると
temp0
のバッファ内容がrc
のバッファへコピーされます。さらに、
これはtemp1
の内容を変更します。そのため、最後の代入rc.b = temp1
は、
期待する結果にはならないのです。
Structure、UnionおよびArrayのサブオブジェクトを取り出しても、そのサブオブジェクトが コピーされるわけではなく、ルートオブジェクトの内部バッファにアクセスする ラッパーオブジェクトを取り出すことを覚えておいてください。
期待とは違う振る舞いをする別の例はこれです:
>>> s = c_char_p() >>> s.value = "abc def ghi" >>> s.value 'abc def ghi' >>> s.value is s.value False >>>
なぜFalse
と表示されるのでしょうか?ctypesインスタンスは
メモリの内容にアクセスするいくつかの記述子付きメモリを含むオブジェクトです。
メモリブロックにPythonオブジェクトを保存してもオブジェクト自身が保存
される訳ではなく、オブジェクトのcontents
が保存されます。
そのcontentsに再アクセスすると新しいPythonオブジェクトがその度に作られます。
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。