14.14.1.14 ポインタ

ポインタのインスタンスはctypes型に対してpointer関数を 呼び出して作成します:

>>> from ctypes import *
>>> i = c_int(42)
>>> pi = pointer(i)
>>>

ポインタインスタンスはポインタが指すオブジェクト(上の例ではi)を返す contents属性を持ちます:

>>> pi.contents
c_long(42)
>>>

ctypesはOOR (original object return、元のオブジェクトを返すこと)ではないことに 注意してください。属性を取り出す度に、新しい同等のオブジェクトを作成していいるのです:

>>> pi.contents is i
False
>>> pi.contents is pi.contents
False
>>>

別のc_intインスタンスがポインタのcontents属性に代入されると、 これが記憶されているメモリ位置を指すポインタに変化します:

>>> i = c_int(99)
>>> pi.contents = i
>>> pi.contents
c_long(99)
>>>

ポインタインスタンスは整数でインデックス指定することもできます:

>>> pi[0]
99
>>>

整数インデックスへ代入するとポインタが指す値が変更されます:

>>> print i
c_long(99)
>>> pi[0] = 22
>>> print i
c_long(22)
>>>

0ではないインデックスを使うこともできますが、Cの場合と同じように 自分が何をしているかを理解している必要があります。 任意のメモリ位置にアクセスもしくは変更できるのです。 一般的にこの機能を使うのは、C関数からポインタを受け取り、そのポインタが 単一の要素ではなく実際に配列を指していると分かっている場合だけです。

舞台裏では、pointer関数は単にポインタインスタンスを作成する という以上のことを行っています。はじめにポインタを作成する必要があります。 これは任意のctypes型を受け取るPOINTER関数を使って行われ、新しい型を 返します:

>>> PI = POINTER(c_int)
>>> PI
<class 'ctypes.LP_c_long'>
>>> PI(42)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: expected c_long instead of int
>>> PI(c_int(42))
<ctypes.LP_c_long object at 0x...>
>>>

ポインタ型を引数なしで呼び出すとNULLポインタを作成します。 NULLポインタはFalseブール値を持っています:

>>> null_ptr = POINTER(c_int)()
>>> print bool(null_ptr)
False
>>>

ctypesはポインタの指す値を取り出すときにNULLかどうかを調べます (しかし、NULLでないポインタの指す値の取り出す行為はPythonをクラッシュさせるでしょう):

>>> null_ptr[0]
Traceback (most recent call last):
    ....
ValueError: NULL pointer access
>>>

>>> null_ptr[0] = 1234
Traceback (most recent call last):
    ....
ValueError: NULL pointer access
>>>

ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。