# 16.16. `ctypes` --- Pythonのための外部関数ライブラリ

`ctypes` は Python のための外部関数ライブラリです。このライブラリは C と互換性のあるデータ型を提供し、動的リンク/共有ライブラリ内の関数呼び出しを可能にします。動的リンク/共有ライブラリを純粋な Python でラップするために使うことができます。

## 16.16.1. ctypesチュートリアル

注意: このチュートリアルのコードサンプルは動作確認のために `doctest` を使います。コードサンプルの中には Linux、 Windows、あるいは Mac OS X 上で異なる動作をするものがあるため、サンプルのコメントに doctest 命令を入れてあります。

注意: いくつかのコードサンプルで ctypes の `c_int` 型を参照しています。 `sizeof(long) == sizeof(int)` であるようなプラットフォームでは、この型は `c_long` のエイリアスです。そのため、 `c_int` 型を想定しているときに `c_long` が表示されたとしても、混乱しないようにしてください --- 実際には同じ型なのです。

### 16.16.1.1. 動的リンクライブラリをロードする

動的リンクライブラリをロードするために、 `ctypes` は cdll をエクスポートします。 Windows では windll と oledll オブジェクトをエクスポートします。

これらのオブジェクトの属性としてライブラリにアクセスすることでライブラリをロードします。 cdll は、標準 `cdecl` 呼び出し規約を用いて関数をエクスポートしているライブラリをロードします。それに対して、 windll ライブラリは `stdcall` 呼び出し規約を用いる関数を呼び出します。 oledll も `stdcall` 呼び出し規約を使いますが、関数が Windows `HRESULT` エラーコードを返すことを想定しています。このエラーコードは関数呼び出しが失敗したとき、 `OSError` 例外を自動的に送出させるために使われます。

バージョン 3.3 で変更: Windows エラーは以前は `WindowsError` を送出していましたが、これは現在では `OSError` の別名になっています。

Windows用の例ですが、 `msvcrt` はほとんどの標準 C 関数が含まれている MS 標準 C ライブラリであり、 cdecl 呼び出し規約を使うことに注意してください:

    >>> from ctypes import *
    >>> print(windll.kernel32)
    <WinDLL 'kernel32', handle ... at ...>
    >>> print(cdll.msvcrt)
    <CDLL 'msvcrt', handle ... at ...>
    >>> libc = cdll.msvcrt
    >>>

Windows では通常の `.dll` ファイル拡張子を自動的に追加します。

注釈

`cdll.msvcrt` 経由で標準 C ライブラリにアクセスすると、Python が使用しているライブラリとは互換性のない可能性のある、古いバージョンのライブラリが使用されます。可能な場合には、ネイティブ Python の機能を使用するか、`msvcrt` モジュールをインポートして使用してください。

Linux ではライブラリをロードするために拡張子を 含む ファイル名を指定する必要があるので、ロードしたライブラリに対する属性アクセスはできません。 dll ローダーの `LoadLibrary()` メソッドを使うか、コンストラクタを呼び出して CDLL のインスタンスを作ることでライブラリをロードするかのどちらかを行わなければなりません:

    >>> cdll.LoadLibrary("libc.so.6")
    <CDLL 'libc.so.6', handle ... at ...>
    >>> libc = CDLL("libc.so.6")
    >>> libc
    <CDLL 'libc.so.6', handle ... at ...>
    >>>

### 16.16.1.2. ロードしたdllから関数にアクセスする

dll オブジェクトの属性として関数にアクセスします:

    >>> from ctypes import *
    >>> libc.printf
    <_FuncPtr object at 0x...>
    >>> print(windll.kernel32.GetModuleHandleA)
    <_FuncPtr object at 0x...>
    >>> print(windll.kernel32.MyOwnFunction)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "ctypes.py", line 239, in __getattr__
        func = _StdcallFuncPtr(name, self)
    AttributeError: function 'MyOwnFunction' not found
    >>>

`kernel32` や `user32` のような win32 システム dll は、多くの場合関数の UNICODE バージョンに加えて ANSI バージョンもエクスポートすることに注意してください。 UNICODE バージョンは後ろに `W` が付いた名前でエクスポートされ、 ANSI バージョンは `A` が付いた名前でエクスポートされます。与えられたモジュールの モジュールハンドル を返す win32 `GetModuleHandle` 関数は次のような C プロトタイプを持ちます。 UNICODE バージョンが定義されているかどうかにより `GetModuleHandle` としてどちらか一つを公開するためにマクロが使われます:

    /* ANSI version */
    HMODULE GetModuleHandleA(LPCSTR lpModuleName);
    /* UNICODE version */
    HMODULE GetModuleHandleW(LPCWSTR lpModuleName);

windll は魔法を使ってどちらか一つを選ぶようなことはしません。`GetModuleHandleA` もしくは `GetModuleHandleW` を明示的に指定して必要とするバージョンにアクセスし、バイト列か文字列を使ってそれぞれ呼び出さなければなりません。

時には、 dll が関数を `"??2@YAPAXI@Z"` のような Python 識別子として有効でない名前でエクスポートすることがあります。このような場合に関数を取り出すには、 `getattr()` を使わなければなりません。:

    >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")
    <_FuncPtr object at 0x...>
    >>>

Windows では、名前ではなく序数によって関数をエクスポートする dll もあります。こうした関数には序数を使って dll オブジェクトにインデックス指定することでアクセスします:

    >>> cdll.kernel32[1]
    <_FuncPtr object at 0x...>
    >>> cdll.kernel32[0]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "ctypes.py", line 310, in __getitem__
        func = _StdcallFuncPtr(name, self)
    AttributeError: function ordinal 0 not found
    >>>

### 16.16.1.3. 関数を呼び出す

これらの関数は他の Python 呼び出し可能オブジェクトと同じように呼び出すことができます。この例では `time()` 関数 (Unixエポックからのシステム時間を秒単位で返す) と、 `GetModuleHandleA()` 関数 (win32モジュールハンドルを返す) を使います。

この例は両方の関数を NULL ポインタとともに呼び出します (`None` を NULL ポインタとして使う必要があります):

    >>> print(libc.time(None))
    1150640792
    >>> print(hex(windll.kernel32.GetModuleHandleA(None)))
    0x1d000000
    >>>

注釈

不正な数の引数が渡されたことを検知した場合、 `ctypes` は関数を呼び出した後に `ValueError` を送出することがあります。 この動作には依存するべきではありません。 この動作は 3.6.2 で非推奨であり、 3.7 で削除予定です。

`cdecl` 呼び出し規約を使って `stdcall` 関数を呼び出したときには、 `ValueError` が送出されます。逆の場合も同様です:

    >>> cdll.kernel32.GetModuleHandleA(None)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: Procedure probably called with not enough arguments (4 bytes missing)
    >>>

    >>> windll.msvcrt.printf(b"spam")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: Procedure probably called with too many arguments (4 bytes in excess)
    >>>

正しい呼び出し規約を知るためには、呼び出したい関数についての C ヘッダファイルもしくはドキュメントを見なければなりません。

Windows では、関数が無効な引数とともに呼び出された場合の一般保護例外によるクラッシュを防ぐために、 `ctypes` は win32 構造化例外処理を使います:

    >>> windll.kernel32.GetModuleHandleA(32)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: exception: access violation reading 0x00000020
    >>>

しかしそれでも他に `ctypes` で Python がクラッシュする状況はあるので、どちらにせよ気を配るべきです。クラッシュのデバッグには、 `faulthandler` モジュールが役に立つ場合があります (例えば、誤った C ライブラリ呼び出しによって引き起こされたセグメンテーション違反) 。

`None` 、整数、バイト列オブジェクトおよび (Unicode) 文字列だけが、こうした関数呼び出しにおいてパラメータとして直接使えるネイティブの Python オブジェクトです。 `None` は C の `NULL` ポインタとして渡され、バイト文字列とユニコード文字列はそのデータを含むメモリブロックへのポインタ (`char *` または `wchar_t *`) として渡されます。 Python 整数はプラットホームのデフォルトの C `int` 型として渡され、その値は C `int` 型に合うようにマスクされます。

他のパラメータ型をもつ関数呼び出しに移る前に、 `ctypes` データ型についてさらに学ぶ必要があります。

### 16.16.1.4. 基本データ型

`ctypes` ではいくつもの C 互換のプリミティブなデータ型を定義しています:

ctypes の型 | C の型 | Python の型
--- | --- | ---
`c_bool` | `_Bool` | bool (1)
`c_char` | `char` | 1文字のバイト列オブジェクト
`c_wchar` | `wchar_t` | 1文字の文字列
`c_byte` | `char` | int
`c_ubyte` | `unsigned char` | int
`c_short` | `short` | int
`c_ushort` | `unsigned short` | int
`c_int` | `int` | int
`c_uint` | `unsigned int` | int
`c_long` | `long` | int
`c_ulong` | `unsigned long` | int
`c_longlong` | `__int64` または `long long` | int
`c_ulonglong` | `unsigned __int64` または `unsigned long long` | int
`c_size_t` | `size_t` | int
`c_ssize_t` | `ssize_t` または `Py_ssize_t` | int
`c_float` | `float` | 浮動小数点数
`c_double` | `double` | 浮動小数点数
`c_longdouble` | `long double` | 浮動小数点数
`c_char_p` | `char *` (NUL 終端) | バイト列オブジェクトまたは `None`
`c_wchar_p` | `wchar_t *` (NUL 終端) | 文字列または `None`
`c_void_p` | `void *` | 整数または `None`

1. コンストラクタは任意のオブジェクトをその真偽値として受け取ります。

これら全ての型はその型を呼び出すことによって作成でき、オプションとして型と値が合っている初期化子を指定することができます:

    >>> c_int()
    c_long(0)
    >>> c_wchar_p("Hello, World")
    c_wchar_p(140018365411392)
    >>> c_ushort(-3)
    c_ushort(65533)
    >>>

これらの型は変更可能であり、値を後で変更することもできます:

    >>> i = c_int(42)
    >>> print(i)
    c_long(42)
    >>> print(i.value)
    42
    >>> i.value = -99
    >>> print(i.value)
    -99
    >>>

新しい値をポインタ型 `c_char_p`, `c_wchar_p` および `c_void_p` のインスタンスへ代入すると、変わるのは指している メモリ位置 であって、メモリブロックの 内容ではありません (これは当然で、なぜなら、 Python バイト列オブジェクトは変更不可能だからです):

    >>> s = "Hello, World"
    >>> c_s = c_wchar_p(s)
    >>> print(c_s)
    c_wchar_p(139966785747344)
    >>> print(c_s.value)
    Hello World
    >>> c_s.value = "Hi, there"
    >>> print(c_s)              # the memory location has changed
    c_wchar_p(139966783348904)
    >>> print(c_s.value)
    Hi, there
    >>> print(s)                # first object is unchanged
    Hello, World
    >>>

しかし、変更可能なメモリを指すポインタであることを想定している関数へそれらを渡さないように注意すべきです。もし変更可能なメモリブロックが必要なら、 ctypes には `create_string_buffer()` 関数があり、いろいろな方法で作成することできます。現在のメモリブロックの内容は `raw` プロパティを使ってアクセス (あるいは変更) することができます。もし現在のメモリブロックに NUL 終端文字列としてアクセスしたいなら、 `value` プロパティを使ってください:

    >>> from ctypes import *
    >>> p = create_string_buffer(3)            # create a 3 byte buffer, initialized to NUL bytes
    >>> print(sizeof(p), repr(p.raw))
    3 b'\x00\x00\x00'
    >>> p = create_string_buffer(b"Hello")     # create a buffer containing a NUL terminated string
    >>> print(sizeof(p), repr(p.raw))
    6 b'Hello\x00'
    >>> print(repr(p.value))
    b'Hello'
    >>> p = create_string_buffer(b"Hello", 10) # create a 10 byte buffer
    >>> print(sizeof(p), repr(p.raw))
    10 b'Hello\x00\x00\x00\x00\x00'
    >>> p.value = b"Hi"
    >>> print(sizeof(p), repr(p.raw))
    10 b'Hi\x00lo\x00\x00\x00\x00\x00'
    >>>

`create_string_buffer()` 関数は初期の ctypes リリースにあった `c_string()` 関数だけでなく、 (エイリアスとしてはまだ利用できる) `c_buffer()` 関数をも置き換えるものです。 C の型 `wchar_t` の Unicode 文字を含む変更可能なメモリブロックを作成するには、 `create_unicode_buffer()` 関数を使ってください。

### 16.16.1.5. 続・関数を呼び出す

printf は `sys.stdout` では なく 、本物の標準出力チャンネルへプリントすることに注意してください。したがって、これらの例はコンソールプロンプトでのみ動作し、 IDLE や PythonWin では動作しません。:

    >>> printf = libc.printf
    >>> printf(b"Hello, %s\n", b"World!")
    Hello, World!
    14
    >>> printf(b"Hello, %S\n", "World!")
    Hello, World!
    14
    >>> printf(b"%d bottles of beer\n", 42)
    42 bottles of beer
    19
    >>> printf(b"%f bottles of beer\n", 42.5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2
    >>>

前に述べたように、必要な C のデータ型へ変換できるようにするためには、整数、文字列およびバイト列オブジェクトを除くすべての Python 型を対応する `ctypes` 型でラップしなければなりません:

    >>> printf(b"An int %d, a double %f\n", 1234, c_double(3.14))
    An int 1234, a double 3.140000
    31
    >>>

### 16.16.1.6. 自作のデータ型とともに関数を呼び出す

自作のクラスのインスタンスを関数引数として使えるように、 `ctypes` 引数変換をカスタマイズすることもできます。 `ctypes` は `_as_parameter_` 属性を探し出し、関数引数として使います。もちろん、整数、文字列もしくはバイト列オブジェクトの中の一つでなければなりません:

    >>> class Bottles:
    ...     def __init__(self, number):
    ...         self._as_parameter_ = number
    ...
    >>> bottles = Bottles(42)
    >>> printf(b"%d bottles of beer\n", bottles)
    42 bottles of beer
    19
    >>>

`_as_parameter_` インスタンス変数にインスタンスのデータを保持したくない場合は、必要に応じて利用できる属性を作る `property` を定義しても構いません。

### 16.16.1.7. 要求される引数の型を指定する (関数プロトタイプ)

`argtypes` 属性を設定することによって、 DLL からエクスポートされている関数に要求される引数の型を指定することができます。

`argtypes` は C データ型のシーケンスでなければなりません (この場合 `printf` 関数はおそらく良い例ではありません。なぜなら、引数の数が可変であり、フォーマット文字列に依存した異なる型のパラメータを取るからです。一方では、この機能の実験にはとても便利です)。:

    >>> printf.argtypes = [c_char_p, c_char_p, c_int, c_double]
    >>> printf(b"String '%s', Int %d, Double %f\n", b"Hi", 10, 2.2)
    String 'Hi', Int 10, Double 2.200000
    37
    >>>

(C の関数のプロトタイプのように) 書式を指定すると互換性のない引数型になるのを防ぎ、引数を有効な型へ変換しようとします。:

    >>> printf(b"%d %d %d", 1, 2, 3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ArgumentError: argument 2: exceptions.TypeError: wrong type
    >>> printf(b"%s %d %f\n", b"X", 2, 3)
    X 2 3.000000
    13
    >>>

関数呼び出しへ渡す自作のクラスを定義した場合には、 `argtypes` シーケンスの中で使えるようにするために、そのクラスに `from_param()` クラスメソッドを実装しなければなりません。 `from_param()` クラスメソッドは関数呼び出しへ渡された Python オブジェクトを受け取り、型チェックもしくはこのオブジェクトが受け入れ可能であると確かめるために必要なことはすべて行ってから、オブジェクト自身、 `_as_parameter_` 属性、あるいは、この場合に C 関数引数として渡したい何かの値を返さなければなりません。繰り返しになりますが、その返される結果は整数、文字列、バイト列、 `ctypes` インスタンス、あるいは `_as_parameter_` 属性をもつオブジェクトであるべきです。

### 16.16.1.8. 戻り値の型

デフォルトでは、関数は C `int` を返すと仮定されます。他の戻り値の型を指定するには、関数オブジェクトの `restype` 属性に設定します。

さらに高度な例として、 `strchr` 関数を使います。この関数は文字列ポインタと char を受け取り、文字列へのポインタを返します。:

    >>> strchr = libc.strchr
    >>> strchr(b"abcdef", ord("d"))
    8059983
    >>> strchr.restype = c_char_p    # c_char_p is a pointer to a string
    >>> strchr(b"abcdef", ord("d"))
    b'def'
    >>> print(strchr(b"abcdef", ord("x")))
    None
    >>>

上の `ord("x")` 呼び出しを避けたいなら、 `argtypes` 属性を設定することができます。二番目の引数が一文字の Python バイト列オブジェクトから C の char へ変換されます:

    >>> strchr.restype = c_char_p
    >>> strchr.argtypes = [c_char_p, c_char]
    >>> strchr(b"abcdef", b"d")
    'def'
    >>> strchr(b"abcdef", b"def")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ArgumentError: argument 2: exceptions.TypeError: one character string expected
    >>> print(strchr(b"abcdef", b"x"))
    None
    >>> strchr(b"abcdef", b"d")
    'def'
    >>>

外部関数が整数を返す場合は、 `restype` 属性として呼び出し可能な Python オブジェクト (例えば、関数またはクラス) を使うこともできます。呼び出し可能オブジェクトは C 関数が返す 整数 とともに呼び出され、この呼び出しの結果は関数呼び出しの結果として使われるでしょう。これはエラーの戻り値をチェックして自動的に例外を送出させるために役に立ちます。:

    >>> GetModuleHandle = windll.kernel32.GetModuleHandleA
    >>> def ValidHandle(value):
    ...     if value == 0:
    ...         raise WinError()
    ...     return value
    ...
    >>>
    >>> GetModuleHandle.restype = ValidHandle
    >>> GetModuleHandle(None)
    486539264
    >>> GetModuleHandle("something silly")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 3, in ValidHandle
    OSError: [Errno 126] The specified module could not be found.
    >>>

`WinError` はエラーコードの文字列表現を得るために Windows の `FormatMessage()` api を呼び出し、例外を 返す 関数です。 `WinError` はオプションでエラーコードパラメータを取ります。このパラメータが使われない場合は、エラーコードを取り出すために `GetLastError()` を呼び出します。

`errcheck` 属性によってもっと強力なエラーチェック機構を利用できることに注意してください。詳細はリファレンスマニュアルを参照してください。

### 16.16.1.9. ポインタを渡す(または、パラメータの参照渡し)

時には、 C api 関数がパラメータのデータ型として ポインタ を想定していることがあります。おそらくパラメータと同一の場所に書き込むためか、もしくはそのデータが大きすぎて値渡しできない場合です。これは パラメータの参照渡し としても知られています。

`ctypes` は `byref()` 関数をエクスポートしており、パラメータを参照渡しするために使用します。 `pointer()` 関数を使っても同じ効果が得られます。しかし、 `pointer()` は本当のポインタオブジェクトを構築するためより多くの処理を行うことから、 Python 側でポインタオブジェクト自体を必要としないならば `byref()` を使う方がより高速です。:

    >>> i = c_int()
    >>> f = c_float()
    >>> s = create_string_buffer(b'\000' * 32)
    >>> print(i.value, f.value, repr(s.value))
    0 0.0 b''
    >>> libc.sscanf(b"1 3.14 Hello", b"%d %f %s",
    ...             byref(i), byref(f), s)
    3
    >>> print(i.value, f.value, repr(s.value))
    1 3.1400001049 b'Hello'
    >>>

### 16.16.1.10. 構造体と共用体

構造体と共用体は `ctypes` モジュールに定義されている `Structure` および `Union` ベースクラスからの派生クラスでなければなりません。それぞれのサブクラスは `_fields_` 属性を定義する必要があります。 `_fields_` は フィールド名 と フィールド型 を持つ 2要素タプル のリストでなければなりません。

フィールド型は `c_int` か他の `ctypes` 型 (構造体、共用体、配列、ポインタ) から派生した `ctypes` 型である必要があります。

以下は、 x と y という名前の二つの整数からなる簡単な POINT 構造体の例です。コンストラクタで構造体を初期化する方法も説明しています:

    >>> from ctypes import *
    >>> class POINT(Structure):
    ...     _fields_ = [("x", c_int),
    ...                 ("y", c_int)]
    ...
    >>> point = POINT(10, 20)
    >>> print(point.x, point.y)
    10 20
    >>> point = POINT(y=5)
    >>> print(point.x, point.y)
    0 5
    >>> POINT(1, 2, 3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: too many initializers
    >>>

しかし、もっと複雑な構造体を構築することもできます。ある構造体は、他の構造体をフィールド型として使うことで、他の構造体を含むことができます。

upperleft と lowerright という名前の二つの POINT を持つ RECT 構造体です。:

    >>> class RECT(Structure):
    ...     _fields_ = [("upperleft", POINT),
    ...                 ("lowerright", POINT)]
    ...
    >>> rc = RECT(point)
    >>> print(rc.upperleft.x, rc.upperleft.y)
    0 5
    >>> print(rc.lowerright.x, rc.lowerright.y)
    0 0
    >>>

入れ子になった構造体はいくつかの方法を用いてコンストラクタで初期化することができます。:

    >>> r = RECT(POINT(1, 2), POINT(3, 4))
    >>> r = RECT((1, 2), (3, 4))

フィールド descriptor (記述子)は クラス から取り出せます。デバッグするときに役に立つ情報を得ることができます:

    >>> print(POINT.x)
    <Field type=c_long, ofs=0, size=4>
    >>> print(POINT.y)
    <Field type=c_long, ofs=4, size=4>
    >>>

警告

`ctypes` では、ビットフィールドのある共用体や構造体の関数への値渡しはサポートしていません。これは 32-bit の x86 環境では動くかもしれませんが、このライブラリでは一般の場合に動作することは保証していません。

### 16.16.1.11. 構造体/共用体アライメントとバイトオーダー

デフォルトでは、構造体 (Structure) と共用体(Union) のフィールドは C コンパイラが行うのと同じ方法でアライメントされています。サブクラスを定義するときに `_pack_` クラス属性を指定することでこの動作を変えることは可能です。このクラス属性には正の整数を設定する必要があり、フィールドの最大アライメントを指定します。これは MSVC で `#pragma pack(n)` が行っていること同じです。

`ctypes` は Structure と Union に対してネイティブのバイトオーダーを使います。ネイティブではないバイトオーダーの構造体を作成するには、 `BigEndianStructure`, `LittleEndianStructure`, `BigEndianUnion` および `LittleEndianUnion` ベースクラスの中の一つを使います。これらのクラスにポインタフィールドを持たせることはできません。

### 16.16.1.12. 構造体と共用体におけるビットフィールド

ビットフィールドを含む構造体と共用体を作ることができます。ビットフィールドは整数フィールドに対してのみ作ることができ、ビット幅は `_fields_` タプルの第三要素で指定します。:

    >>> class Int(Structure):
    ...     _fields_ = [("first_16", c_int, 16),
    ...                 ("second_16", c_int, 16)]
    ...
    >>> print(Int.first_16)
    <Field type=c_long, ofs=0:0, bits=16>
    >>> print(Int.second_16)
    <Field type=c_long, ofs=0:16, bits=16>
    >>>

### 16.16.1.13. 配列

配列 (Array) はシーケンスであり、決まった数の同じ型のインスタンスを持ちます。

推奨されている配列の作成方法はデータ型に正の整数を掛けることです。:

    TenPointsArrayType = POINT * 10

ややわざとらしいデータ型の例になりますが、他のものに混ざって 4 個の POINT がある構造体です:

    >>> from ctypes import *
    >>> class POINT(Structure):
    ...     _fields_ = ("x", c_int), ("y", c_int)
    ...
    >>> class MyStruct(Structure):
    ...     _fields_ = [("a", c_int),
    ...                 ("b", c_float),
    ...                 ("point_array", POINT * 4)]
    >>>
    >>> print(len(MyStruct().point_array))
    4
    >>>

インスタンスはクラスを呼び出す通常の方法で作成します。:

    arr = TenPointsArrayType()
    for pt in arr:
        print(pt.x, pt.y)

上記のコードは `0 0` という行が並んだものを表示します。配列の要素がゼロで初期化されているためです。

正しい型の初期化子を指定することもできます。:

    >>> from ctypes import *
    >>> TenIntegers = c_int * 10
    >>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    >>> print(ii)
    <c_long_Array_10 object at 0x...>
    >>> for i in ii: print(i, end=" ")
    ...
    1 2 3 4 5 6 7 8 9 10
    >>>

### 16.16.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 <module>
    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
    >>>

### 16.16.1.15. 型変換

たいていの場合、 ctypes は厳密な型チェックを行います。これが意味するのは、関数の `argtypes` リスト内に、もしくは、構造体定義におけるメンバーフィールドの型として `POINTER(c_int)` がある場合、厳密に同じ型のインスタンスだけを受け取るということです。このルールには ctypes が他のオブジェクトを受け取る場合に例外がいくつかあります。例えば、ポインタ型の代わりに互換性のある配列インスタンスを渡すことができます。このように、 `POINTER(c_int)` に対して、 ctypes は c_int の配列を受け取ります。:

    >>> class Bar(Structure):
    ...     _fields_ = [("count", c_int), ("values", POINTER(c_int))]
    ...
    >>> bar = Bar()
    >>> bar.values = (c_int * 3)(1, 2, 3)
    >>> bar.count = 3
    >>> for i in range(bar.count):
    ...     print(bar.values[i])
    ...
    1
    2
    3
    >>>

それに加えて、 `argtypes` で関数の引数が明示的に (`POINTER(c_int)` などの) ポインタ型であると宣言されていた場合、ポインタ型が指し示している型のオブジェクト (この場合では `c_int`) を関数に渡すことができます。この場合 ctypes は、必要となる `byref()` での変換を自動的に適用します。

POINTER型フィールドを `NULL` に設定するために、 `None` を代入してもかまいません。:

    >>> bar.values = None
    >>>

時には、非互換な型のインスタンスであることもあります。 C では、ある型を他の型へキャストすることができます。 `ctypes` は同じやり方で使える `cast()` 関数を提供しています。上で定義した `Bar` 構造体は `POINTER(c_int)` ポインタまたは `c_int` 配列を `values` フィールドに対して受け取り、他の型のインスタンスは受け取りません:

    >>> bar.values = (c_byte * 4)()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance
    >>>

このような場合には、 `cast()` 関数が便利です。

`cast()` 関数は ctypes インスタンスを異なる ctypes データ型を指すポインタへキャストするために使えます。 `cast()` は二つのパラメータ、ある種のポインタかそのポインタへ変換できる ctypes オブジェクトと、 ctypes ポインタ型を取ります。そして、第二引数のインスタンスを返します。このインスタンスは第一引数と同じメモリブロックを参照しています:

    >>> a = (c_byte * 4)()
    >>> cast(a, POINTER(c_int))
    <ctypes.LP_c_long object at ...>
    >>>

したがって、 `cast()` を `Bar` 構造体の `values` フィールドへ代入するために使うことができます:

    >>> bar = Bar()
    >>> bar.values = cast((c_byte * 4)(), POINTER(c_int))
    >>> print(bar.values[0])
    0
    >>>

### 16.16.1.16. 不完全型

不完全型 はメンバーがまだ指定されていない構造体、共用体もしくは配列です。 C では、前方宣言により指定され、後で定義されます。:

    struct cell; /* forward declaration */

    struct cell {
        char *name;
        struct cell *next;
    };

ctypes コードへの直接的な変換ではこうなるでしょう。しかし、動作しません:

    >>> class cell(Structure):
    ...     _fields_ = [("name", c_char_p),
    ...                 ("next", POINTER(cell))]
    ...
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in cell
    NameError: name 'cell' is not defined
    >>>

なぜなら、新しい `class cell` はクラス文自体の中では利用できないからです。 `ctypes` では、 `cell` クラスを定義して、 `_fields_` 属性をクラス文の後で設定することができます。:

    >>> from ctypes import *
    >>> class cell(Structure):
    ...     pass
    ...
    >>> cell._fields_ = [("name", c_char_p),
    ...                  ("next", POINTER(cell))]
    >>>

試してみましょう。 `cell` のインスタンスを二つ作り、互いに参照し合うようにします。最後に、つながったポインタを何度かたどります。:

    >>> c1 = cell()
    >>> c1.name = "foo"
    >>> c2 = cell()
    >>> c2.name = "bar"
    >>> c1.next = pointer(c2)
    >>> c2.next = pointer(c1)
    >>> p = c1
    >>> for i in range(8):
    ...     print(p.name, end=" ")
    ...     p = p.next[0]
    ...
    foo bar foo bar foo bar foo bar
    >>>

### 16.16.1.17. コールバック関数

`ctypes` は C の呼び出し可能な関数ポインタを Python 呼び出し可能オブジェクトから作成できるようにします。これらは コールバック関数 と呼ばれることがあります。

最初に、コールバック関数のためのクラスを作る必要があります。そのクラスには呼び出し規約、戻り値の型およびこの関数が受け取る引数の数と型についての情報があります。

`CFUNCTYPE()` ファクトリ関数は通常の `cdecl` 呼び出し規約を用いてコールバック関数のための型を作成します。 Windows では、 `WINFUNCTYPE()` ファクトリ関数が `stdcall` 呼び出し規約を用いてコールバック関数の型を作成します。

これらのファクトリ関数はともに最初の引数に戻り値の型、残りの引数としてコールバック関数が想定する引数の型を渡して呼び出されます。

標準 C ライブラリの `qsort()` 関数を使う例を示します。これはコールバック関数の助けをかりて要素をソートするために使われます。 `qsort()` は整数の配列をソートするために使われます:

    >>> IntArray5 = c_int * 5
    >>> ia = IntArray5(5, 1, 7, 33, 99)
    >>> qsort = libc.qsort
    >>> qsort.restype = None
    >>>

`qsort()` はソートするデータを指すポインタ、データ配列の要素の数、要素の一つの大きさ、およびコールバック関数である比較関数へのポインタを引数に渡して呼び出さなければなりません。そして、コールバック関数は要素を指す二つのポインタを渡されて呼び出され、一番目が二番目より小さいなら負の数を、等しいならゼロを、それ以外なら正の数を返さなければなりません。

コールバック関数は整数へのポインタを受け取り、整数を返す必要があります。まず、コールバック関数のための `type` を作成します。:

    >>> CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
    >>>

まず初めに、これが受け取った変数を表示するだけのシンプルなコールバックです:

    >>> def py_cmp_func(a, b):
    ...     print("py_cmp_func", a[0], b[0])
    ...     return 0
    ...
    >>> cmp_func = CMPFUNC(py_cmp_func)
    >>>

結果は以下の通りです:

    >>> qsort(ia, len(ia), sizeof(c_int), cmp_func)
    py_cmp_func 5 1
    py_cmp_func 33 99
    py_cmp_func 7 33
    py_cmp_func 5 7
    py_cmp_func 1 7
    >>>

ここで 2 つの要素を実際に比較し、役に立つ結果を返します:

    >>> def py_cmp_func(a, b):
    ...     print("py_cmp_func", a[0], b[0])
    ...     return a[0] - b[0]
    ...
    >>>
    >>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func))
    py_cmp_func 5 1
    py_cmp_func 33 99
    py_cmp_func 7 33
    py_cmp_func 1 7
    py_cmp_func 5 7
    >>>

簡単に確認できるように、配列を次のようにソートしました:

    >>> for i in ia: print(i, end=" ")
    ...
    1 5 7 33 99
    >>>

関数ファクトリはデコレータファクトリとしても使えるので、次のようにも書けます:

    >>> @CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
    ... def py_cmp_func(a, b):
    ...     print("py_cmp_func", a[0], b[0])
    ...     return a[0] - b[0]
    ...
    >>> qsort(ia, len(ia), sizeof(c_int), py_cmp_func)
    py_cmp_func 5 1
    py_cmp_func 33 99
    py_cmp_func 7 33
    py_cmp_func 1 7
    py_cmp_func 5 7
    >>>

注釈

C コードから `CFUNCTYPE()` オブジェクトが使用される限り、そのオブジェクトへの参照を確実に保持してください。 `ctypes` は参照を保持しないため、あなたが参照を保持しないと、オブジェクトはガベージコレクションの対象となり、コールバックが行われたときにプログラムをクラッシュさせる場合があります。

同様に、コールバック関数が Python の管理外 (例えば、コールバックを呼び出す外部のコード) で作られたスレッドで呼び出された場合、 ctypes は全ての呼び出しごとに新しいダミーの Python スレッドを作成することに注意してください。 この動作はほとんどの目的に対して正しいものですが、同じ C スレッドからの呼び出しだったとしても、 `threading.local` で格納された値は異なるコールバックをまたいで生存は しません 。

### 16.16.1.18. dllからエクスポートされた値へアクセスする

共有ライブラリの一部は関数だけでなく変数もエクスポートしています。 Python ライブラリにある例としては `Py_OptimizeFlag` 、起動時の `-O` または `-OO` フラグに依存して、 0 , 1 または 2 が設定される整数があります。

`ctypes` は型の `in_dll()` クラスメソッドを使ってこのように値にアクセスできます。 pythonapi はPython C api へアクセスできるようにするための予め定義されたシンボルです。:

    >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
    >>> print(opt_flag)
    c_long(0)
    >>>

インタープリタが `-O` を指定されて動き始めた場合、サンプルは `c_long(1)` を表示するでしょうし、 `-OO` が指定されたならば `c_long(2)` を表示するでしょう。

ポインタの使い方を説明する拡張例では、 Python がエクスポートする `PyImport_FrozenModules` ポインタにアクセスします。

この値のドキュメントから引用すると:

> このポインタは `struct _frozen` のレコードからなり、終端の要素のメンバが NULL かゼロになっているような配列を指すよう初期化されます。フリーズされたモジュールをインポートするとき、このテーブルを検索します。サードパーティ製のコードからこのポインタに仕掛けを講じて、動的に生成されたフリーズ化モジュールの集合を提供するようにできます。

これで、このポインタを操作することが役に立つことを証明できるでしょう。例の大きさを制限するために、このテーブルを `ctypes` を使って読む方法だけを示します。:

    >>> from ctypes import *
    >>>
    >>> class struct_frozen(Structure):
    ...     _fields_ = [("name", c_char_p),
    ...                 ("code", POINTER(c_ubyte)),
    ...                 ("size", c_int)]
    ...
    >>>

私たちは `struct _frozen` データ型を定義済みなので、このテーブルを指すポインタを得ることができます:

    >>> FrozenTable = POINTER(struct_frozen)
    >>> table = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules")
    >>>

`table` が `struct_frozen` レコードの配列への `pointer` なので、その配列に対して反復処理を行えます。しかし、ループが確実に終了するようにする必要があります。なぜなら、ポインタに大きさの情報がないからです。遅かれ早かれ、アクセス違反か何かでクラッシュすることになるでしょう。 NULL エントリに達したときはループを抜ける方が良いです。:

    >>> for item in table:
    ...     if item.name is None:
    ...         break
    ...     print(item.name.decode("ascii"), item.size)
    ...
    _frozen_importlib 31764
    _frozen_importlib_external 41499
    __hello__ 161
    __phello__ -161
    __phello__.spam 161
    >>>

標準 Python はフローズンモジュールとフローズンパッケージ (負のサイズのメンバーで表されています) を持っているという事実はあまり知られておらず、テストにだけ使われています。例えば、 `import __hello__` を試してみてください。

### 16.16.1.19. びっくり仰天

There are some edges in `ctypes` where you might expect something other than what actually happens.

次に示す例について考えてみてください。:

    >>> 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 インスタンスはメモリと、メモリの内容にアクセスするいくつかの descriptor (記述子)を含むオブジェクトです。メモリブロックに Python オブジェクトを保存してもオブジェクト自身が保存される訳ではなく、オブジェクトの `contents` が保存されます。その contents に再アクセスすると新しい Python オブジェクトがその度に作られます。

### 16.16.1.20. 可変サイズのデータ型

`ctypes` は可変サイズの配列と構造体をサポートしています。

`resize()` 関数は既存の ctypes オブジェクトのメモリバッファのサイズを変更したい場合に使えます。この関数は第一引数にオブジェクト、第二引数に要求されたサイズをバイト単位で指定します。メモリブロックはオブジェクト型で指定される通常のメモリブロックより小さくすることはできません。これをやろうとすると、 `ValueError` が送出されます。:

    >>> short_array = (c_short * 4)()
    >>> print(sizeof(short_array))
    8
    >>> resize(short_array, 4)
    Traceback (most recent call last):
        ...
    ValueError: minimum size is 8
    >>> resize(short_array, 32)
    >>> sizeof(short_array)
    32
    >>> sizeof(type(short_array))
    8
    >>>

これはこれで上手くいっていますが、この配列の追加した要素へどうやってアクセスするのでしょうか? この型は要素の数が 4 個であるとまだ認識しているので、他の要素にアクセスするとエラーになります。:

    >>> short_array[:]
    [0, 0, 0, 0]
    >>> short_array[7]
    Traceback (most recent call last):
        ...
    IndexError: invalid index
    >>>

`ctypes` で可変サイズのデータ型を使うもう一つの方法は、必要なサイズが分かった後に Python の動的性質を使って一つ一つデータ型を(再)定義することです。

## 16.16.2. ctypesリファレンス

### 16.16.2.1. 共有ライブラリを見つける

コンパイルされる言語でプログラミングしている場合、共有ライブラリはプログラムをコンパイル/リンクしているときと、そのプログラムが動作しているときにアクセスされます。

ctypes ライブラリローダーはプログラムが動作しているときのように振る舞い、ランタイムローダーを直接呼び出すのに対し、 `find_library()` 関数の目的はコンパイラまたはランタイムローダーが行うのと似た方法でライブラリを探し出すことです。 (複数のバージョンの共有ライブラリがあるプラットホームでは、一番最近に見つかったものがロードされます)。

`ctypes.util` モジュールはロードするライブラリを決めるのに役立つ関数を提供します。

`ctypes.util.``find_library`(name)

  ライブラリを見つけてパス名を返そうと試みます。 name は `lib` のような接頭辞、 `.so`, `.dylib` のような接尾辞、あるいは、バージョン番号が何も付いていないライブラリの名前です (これは posix リンカのオプション `-l` に使われている形式です)。 ライブラリが見つからないときは `None` を返します。

厳密な機能はシステムに依存します。

Linux では、 `find_library()` はライブラリファイルを見つけるために外部プログラム (`/sbin/ldconfig`, `gcc`, `objdump` と `ld`) を実行しようとします。ライブラリファイルのファイル名を返します。

バージョン 3.6 で変更: Linux では、ライブラリを検索する際に、他の方法でライブラリが見つけられない場合は、 `LD_LIBRARY_PATH` 環境変数の値が使われます

ここに例があります:

    >>> from ctypes.util import find_library
    >>> find_library("m")
    'libm.so.6'
    >>> find_library("c")
    'libc.so.6'
    >>> find_library("bz2")
    'libbz2.so.1.0'
    >>>

OS X では、 `find_library()` はライブラリの位置を探すために、予め定義された複数の命名方法とパスを試し、成功すればフルパスを返します。:

    >>> from ctypes.util import find_library
    >>> find_library("c")
    '/usr/lib/libc.dylib'
    >>> find_library("m")
    '/usr/lib/libm.dylib'
    >>> find_library("bz2")
    '/usr/lib/libbz2.dylib'
    >>> find_library("AGL")
    '/System/Library/Frameworks/AGL.framework/AGL'
    >>>

Windows では、 `find_library()` はシステムの探索パスに沿って探し、フルパスを返します。しかし、予め定義された命名方法がないため、 `find_library("c")` のような呼び出しは失敗し、 `None` を返します。

`ctypes` で共有ライブラリをラップする場合、 `find_library()` を使って実行時にライブラリの場所を特定するのではなく、共有ライブラリの名前を開発時に決めておいて、ラッパーモジュールにハードコードする方が良い かもしれません 。

### 16.16.2.2. 共有ライブラリをロードする

共有ライブラリを Python プロセスへロードする方法はいくつかあります。一つの方法は下記のクラスの一つをインスタンス化することです:

class `ctypes.``CDLL`(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

  このクラスのインスタンスはロードされた共有ライブラリをあらわします。これらのライブラリの関数は標準 C 呼び出し規約を使用し、 `int` を返すと仮定されます。

class `ctypes.``OleDLL`(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

  Windows 用: このクラスのインスタンスはロードされた共有ライブラリをあらわします。これらのライブラリの関数は `stdcall` 呼び出し規約を使用し、 windows 固有の `HRESULT` コードを返すと仮定されます。 `HRESULT` 値には関数呼び出しが失敗したのか成功したのかを特定する情報とともに、補足のエラーコードが含まれます。戻り値が失敗を知らせたならば、 `OSError` が自動的に送出されます。

  バージョン 3.3 で変更: 以前は `WindowsError` を送出していました。

class `ctypes.``WinDLL`(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

  Windows 用: このクラスのインスタンスはロードされた共有ライブラリをあらわします。これらのライブラリの関数は `stdcall` 呼び出し規約を使用し、デフォルトでは `int` を返すと仮定されます。

  Windows CE では標準呼び出し規約だけが使われます。便宜上、このプラットフォームでは、 `WinDLL` と `OleDLL` が標準呼び出し規約を使用します。

これらのライブラリがエクスポートするどの関数でも呼び出す前に Python GIL (global interpreter lock) は解放され、後でまた獲得されます。

class `ctypes.``PyDLL`(name, mode=DEFAULT_MODE, handle=None)

  Python GIL が関数呼び出しの間解放 されず 、関数実行の後に Python エラーフラグがチェックされるということを除けば、このクラスのインスタンスは `CDLL` インスタンスのように振る舞います。エラーフラグがセットされた場合、 Python 例外が送出されます。

  要するに、これは Python C api 関数を直接呼び出すのに便利だというだけです。

これらすべてのクラスは少なくとも一つの引数、すなわちロードする共有ライブラリのパスを渡して呼び出すことでインスタンス化されます。すでにロード済みの共有ライブラリへのハンドルがあるなら、 `handle` 名前付き引数として渡すことができます。土台となっているプラットフォームの `dlopen` または `LoadLibrary` 関数がプロセスへライブラリをロードするために使われ、そのライブラリに対するハンドルを得ます。

mode パラメータを使うと、ライブラリがどうやってロードされたかを特定できます。 詳細は dlopen(3) マニュアルページを参考にしてください。 Windows では mode は無視されます。 POSIX システムでは RTLD_NOW が常に追加され、設定変更はできません。

use_errno 変数が真に設定されたとき、システムの `errno` エラーナンバーに安全にアクセスする ctypes の仕組みが有効化されます。 `ctypes` はシステムの `errno` 変数のスレッド限定のコピーを管理します。もし、 `use_errno=True` の状態で作られた外部関数を呼び出したなら、関数呼び出し前の `errno` 変数は ctypes のプライベートコピーと置き換えられ、同じことが関数呼び出しの直後にも発生します。

`ctypes.get_errno()` 関数は ctypes のプライベートコピーの値を返します。そして、 `ctypes.set_errno()` 関数は ctypes のプライベートコピーを置き換え、以前の値を返します。

use_last_error パラメータは、真に設定されたとき、 `GetLastError()` と `SetLastError()` Windows API によって管理される Windows エラーコードに対するのと同じ仕組みが有効化されます。 `ctypes.get_last_error()` と `ctypes.set_last_error()` は Windows エラーコードの ctypes プライベートコピーを変更したり要求したりするのに使われます。

`ctypes.``RTLD_GLOBAL`

  mode パラメータとして使うフラグ。このフラグが利用できないプラットフォームでは、整数のゼロと定義されています。

`ctypes.``RTLD_LOCAL`

  mode パラメータとして使うフラグ。これが利用できないプラットフォームでは、 RTLD_GLOBAL と同様です。

`ctypes.``DEFAULT_MODE`

  共有ライブラリをロードするために使われるデフォルトモード。 OSX 10.3 では RTLD_GLOBAL であり、そうでなければ RTLD_LOCAL と同じです。

これらのクラスのインスタンスには公開メソッドはありません。共有ライブラリからエクスポートされた関数は、属性として、もしくは添字でアクセスできます。属性を通した関数へのアクセスは結果がキャッシュされ、従って繰り返しアクセスされると毎回同じオブジェクトを返すことに注意してください。それとは反対に、添字を通したアクセスは毎回新しいオブジェクトを返します:

    >>> libc.time == libc.time
    True
    >>> libc['time'] == libc['time']
    False

次に述べる公開属性が利用できます。それらの名前はエクスポートされた関数名に衝突しないように下線で始まります。:

`PyDLL.``_handle`

  ライブラリへのアクセスに用いられるシステムハンドル。

`PyDLL.``_name`

  コンストラクタに渡されたライブラリの名前。

共有ライブラリは (`LibraryLoader` クラスのインスタンスである) 前もって作られたオブジェクトの一つを使うことによってロードすることもできます。それらの `LoadLibrary()` メソッドを呼び出すか、ローダーインスタンスの属性としてライブラリを取り出すかのどちらかによりロードします。

class `ctypes.``LibraryLoader`(dlltype)

  共有ライブラリをロードするクラス。 dlltype は `CDLL` 、 `PyDLL` 、 `WinDLL` もしくは `OleDLL` 型の一つであるべきです。

  `__getattr__()` は次のような特別なはたらきをします。ライブラリローダーインスタンスの属性として共有ライブラリにアクセスするとそれがロードされるということを可能にします。結果はキャッシュされます。そのため、繰り返し属性アクセスを行うといつも同じライブラリが返されます。

  `LoadLibrary`(name)

    共有ライブラリをプロセスへロードし、それを返します。このメソッドはライブラリの新しいインスタンスを常に返します。

これらの前もって作られたライブラリローダーを利用することができます。:

`ctypes.``cdll`

  `CDLL` インスタンスを作ります。

`ctypes.``windll`

  Windows 用: `WinDLL` インスタンスを作ります。

`ctypes.``oledll`

  Windows 用: `OleDLL` インスタンスを作ります。

`ctypes.``pydll`

  `PyDLL` インスタンスを作ります。

C Python api に直接アクセスするために、すぐに使用できる Python 共有ライブラリオブジェクトが次のように用意されています。

`ctypes.``pythonapi`

  属性として Python C api 関数を公開する `PyDLL` のインスタンス。これらすべての関数は C `int` を返すと仮定されますが、もちろん常に正しいとは限りません。そのため、これらの関数を使うためには正しい `restype` 属性を代入しなければなりません。

### 16.16.2.3. 外部関数

前節で説明した通り、外部関数はロードされた共有ライブラリの属性としてアクセスできます。デフォルトではこの方法で作成された関数オブジェクトはどんな数の引数でも受け取り、引数としてどんな ctypes データのインスタンスをも受け取り、そして、ライブラリローダーが指定したデフォルトの結果の値の型を返します。関数オブジェクトはプライベートクラスのインスタンスです。:

class `ctypes.``_FuncPtr`

  C の呼び出し可能外部関数のためのベースクラス。

  外部関数のインスタンスも C 互換データ型です。それらは C の関数ポインタを表しています。

  この振る舞いは外部関数オブジェクトの特別な属性に代入することによって、カスタマイズすることができます。

  `restype`

    外部関数の結果の型を指定するために ctypes 型を代入する。何も返さない関数を表す `void` に対しては `None` を使います。

    ctypes 型ではない呼び出し可能な Python オブジェクトを代入することは可能です。このような場合、関数が C `int` を返すと仮定され、呼び出し可能オブジェクトはこの整数を引数に呼び出されます。さらに処理を行ったり、エラーチェックをしたりできるようにするためです。これの使用は推奨されません。より柔軟な後処理やエラーチェックのためには `restype` として ctypes 型を使い、 `errcheck` 属性へ呼び出し可能オブジェクトを代入してください。

  `argtypes`

    関数が受け取る引数の型を指定するために ctypes 型のタプルを代入します。`stdcall` 呼び出し規約を使う関数はこのタプルの長さと同じ数の引数で呼び出されます。C 呼び出し規約を使う関数は、追加の不特定の引数も取ります。

    外部関数が呼ばれたとき、それぞれの実引数は `argtypes` タプルの要素の `from_param()` クラスメソッドへ渡されます。このメソッドは実引数を外部関数が受け取るオブジェクトに合わせて変えられるようにします。例えば、 `argtypes` タプルの `c_char_p` 要素は、 ctypes 変換規則にしたがって引数として渡された文字列をバイト列オブジェクトへ変換するでしょう。

    新: ctypes 型でない要素を argtypes に入れることができますが、個々の要素は引数として使える値 (整数、文字列、 ctypes インスタンス) を返す `from_param()` メソッドを持っていなければなりません。これにより関数パラメータとしてカスタムオブジェクトを適合するように変更できるアダプタが定義可能となります。

  `errcheck`

    Python 関数または他の呼び出し可能オブジェクトをこの属性に代入します。呼び出し可能オブジェクトは三つ以上の引数とともに呼び出されます。

    `callable`(result, func, arguments)

      result は外部関数が返すもので、 `restype` 属性で指定されます。

      func は外部関数オブジェクト自身で、これにより複数の関数の処理結果をチェックまたは後処理するために、同じ呼び出し可能オブジェクトを再利用できるようになります。

      arguments は関数呼び出しに最初に渡されたパラメータが入ったタプルです。これにより使われた引数に基づいた特別な振る舞いをさせることができるようになります。

    この関数が返すオブジェクトは外部関数呼び出しから返された値でしょう。しかし、戻り値をチェックして、外部関数呼び出しが失敗しているなら例外を送出させることもできます。

exception `ctypes.``ArgumentError`

  この例外は外部関数呼び出しが渡された引数を変換できなかったときに送出されます。

### 16.16.2.4. 関数プロトタイプ

外部関数は関数プロトタイプをインスタンス化することによって作成されます。 関数プロトタイプは C の関数プロトタイプと似ています。実装は定義せずに、関数 (返り値の型、引数の型、呼び出し規約) を記述します。 ファクトリ関数は、その関数に要求される返り値の型と引数の型とともに呼び出されます。そしてこの関数はデコレータファクトリとしても使え、 `@wrapper` 構文で他の関数に適用できます。 例については コールバック関数 を参照してください。

`ctypes.``CFUNCTYPE`(restype, *argtypes, use_errno=False, use_last_error=False)

  返された関数プロトタイプは標準 C 呼び出し規約をつかう関数を作成します。関数は呼び出されている間 GIL を解放します。 use_errno が真に設定されれば、呼び出しの前後で System 変数 `errno` の ctypesプライベートコピーは本当の `errno` の値と交換されます。 use_last_error も Windows エラーコードに対するのと同様です。

`ctypes.``WINFUNCTYPE`(restype, *argtypes, use_errno=False, use_last_error=False)

  Windows のみ: 返された関数プロトタイプは `stdcall` 呼び出し規約を使う関数を作成します。ただし、 `WINFUNCTYPE()` が `CFUNCTYPE()` と同じである Windows CE を除きます。関数は呼び出されている間 GIL を解放します。 use_errno と use_last_error は前述と同じ意味を持ちます。

`ctypes.``PYFUNCTYPE`(restype, *argtypes)

  返された関数プロトタイプは Python 呼び出し規約を使う関数を作成します。関数は呼び出されている間 GIL を解放 しません。

ファクトリ関数によって作られた関数プロトタイプは呼び出しのパラメータの型と数に依存した別の方法でインスタンス化することができます。 :

> `prototype`(address)

>   指定されたアドレス(整数でなくてはなりません)の外部関数を返します。

> `prototype`(callable)

>   Python の callable から C の呼び出し可能関数(コールバック関数) を作成します。

> `prototype`(func_spec[, paramflags])

>   共有ライブラリがエクスポートしている外部関数を返します。 func_spec は 2 要素タプル `(name_or_ordinal, library)` でなければなりません。第一要素はエクスポートされた関数の名前である文字列、またはエクスポートされた関数の序数である小さい整数です。第二要素は共有ライブラリインスタンスです。

> `prototype`(vtbl_index, name[, paramflags[, iid]])

>   COM メソッドを呼び出す外部関数を返します。 vtbl_index は仮想関数テーブルのインデックスで、非負の小さい整数です。 name は COM メソッドの名前です。 iid はオプションのインターフェイス識別子へのポインタで、拡張されたエラー情報の提供のために使われます。

>   COM メソッドは特殊な呼び出し規約を用います。このメソッドは `argtypes` タプルに指定されたパラメータに加えて、第一引数として COM インターフェイスへのポインタを必要とします。

> オプションの paramflags パラメータは上述した機能より多機能な外部関数ラッパーを作成します。

> paramflags は `argtypes` と同じ長さのタプルでなければなりません。

> このタプルの個々の要素はパラメータについてのより詳細な情報を持ち、 1 、 2 もしくは 3 要素を含むタプルでなければなりません。

> 第一要素はパラメータについてのフラグの組み合わせを含んだ整数です。

> > 1

> >   入力パラメータを関数に指定します。

> > 2

> >   出力パラメータ。外部関数が値を書き込みます。

> > 4

> >   デフォルトで整数ゼロになる入力パラメータ。

> オプションの第二要素はパラメータ名の文字列です。これが指定された場合は、外部関数を名前付きパラメータで呼び出すことができます。

> オプションの第三要素はこのパラメータのデフォルト値です。

この例では、デフォルトパラメータと名前付き引数をサポートするために Windows の `MessageBoxW` 関数をラップする方法を示します。 windows のヘッダファイルの C の宣言は次の通りです:

    WINUSERAPI int WINAPI
    MessageBoxW(
        HWND hWnd,
        LPCWSTR lpText,
        LPCWSTR lpCaption,
        UINT uType);

`ctypes` を使ってラップします。:

    >>> from ctypes import c_int, WINFUNCTYPE, windll
    >>> from ctypes.wintypes import HWND, LPCWSTR, UINT
    >>> prototype = WINFUNCTYPE(c_int, HWND, LPCWSTR, LPCWSTR, UINT)
    >>> paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", "Hello from ctypes"), (1, "flags", 0)
    >>> MessageBox = prototype(("MessageBoxW", windll.user32), paramflags)

これで外部関数の `MessageBox` を次のような方法で呼び出すことができるようになりました:

    >>> MessageBox()
    >>> MessageBox(text="Spam, spam, spam")
    >>> MessageBox(flags=2, text="foo bar")

二番目の例は出力パラメータについて説明します。 win32 の `GetWindowRect` 関数は、指定されたウィンドウの大きさを呼び出し側が与える `RECT` 構造体へコピーすることで取り出します。 C の宣言はこうです。:

    WINUSERAPI BOOL WINAPI
    GetWindowRect(
         HWND hWnd,
         LPRECT lpRect);

`ctypes` を使ってラップします。:

    >>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError
    >>> from ctypes.wintypes import BOOL, HWND, RECT
    >>> prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
    >>> paramflags = (1, "hwnd"), (2, "lprect")
    >>> GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
    >>>

出力パラメータを持つ関数は、単一のパラメータがある場合にはその出力パラメータ値を、複数のパラメータがある場合には出力パラメータ値が入ったタプルを、それぞれ自動的に返します。そのため、GetWindowRect 関数は呼び出されると RECT インスタンスを返します。

さらに出力処理やエラーチェックを行うために、出力パラメータを `errcheck` プロトコルと組み合わせることができます。 win32 `GetWindowRect` api 関数は成功したか失敗したかを知らせるために `BOOL` を返します。そのため、この関数はエラーチェックを行って、 api 呼び出しが失敗した場合に例外を送出させることができます。:

    >>> def errcheck(result, func, args):
    ...     if not result:
    ...         raise WinError()
    ...     return args
    ...
    >>> GetWindowRect.errcheck = errcheck
    >>>

`errcheck` 関数が受け取った引数タプルを変更なしに返した場合、 `ctypes` は出力パラメータに対する通常の処理を続けます。 `RECT` インスタンスの代わりに window 座標のタプルを返すには、関数のフィールドを取り出し、代わりにそれらを返すことができます。この場合、通常処理は行われなくなります:

    >>> def errcheck(result, func, args):
    ...     if not result:
    ...         raise WinError()
    ...     rc = args[1]
    ...     return rc.left, rc.top, rc.bottom, rc.right
    ...
    >>> GetWindowRect.errcheck = errcheck
    >>>

### 16.16.2.5. ユーティリティー関数

`ctypes.``addressof`(obj)

  メモリバッファのアドレスを示す整数を返します。 obj は ctypes 型のインスタンスでなければなりません。

`ctypes.``alignment`(obj_or_type)

  ctypes 型のアライメントの必要条件を返します。 obj_or_type は ctypes 型またはインスタンスでなければなりません。

`ctypes.``byref`(obj[, offset])

  obj (ctypes 型のインスタンスでなければならない) への軽量ポインタを返します。 offset はデフォルトでは 0 で、内部ポインターへ加算される整数です。

  `byref(obj, offset)` は、 C コードとしては、以下のようにみなされます。:

      (((char *)&obj) + offset)

  返されるオブジェクトは外部関数呼び出しのパラメータとしてのみ使用できます。`pointer(obj)` と似たふるまいをしますが、作成が非常に速く行えます。

`ctypes.``cast`(obj, type)

  この関数は C のキャスト演算子に似ています。obj と同じメモリブロックを指している type の新しいインスタンスを返します。type はポインタ型でなければならず、obj はポインタとして解釈できるオブジェクトでなければなりません。

`ctypes.``create_string_buffer`(init_or_size, size=None)

  この関数は変更可能な文字バッファを作成します。返されるオブジェクトは `c_char` の ctypes 配列です。

  init_or_size は配列のサイズを指定する整数もしくは配列要素を初期化するために使われるバイト列オブジェクトである必要があります。

  バイト列オブジェクトが第一引数として指定されていた場合、配列の最後の要素が NUL 終端文字となるように、バイト列オブジェクトの長さより 1 つ長いバッファを作成します。バイト列の長さを使うべきではない場合は、第二引数として整数を渡して、配列の長さを指定することができます。

`ctypes.``create_unicode_buffer`(init_or_size, size=None)

  この関数は変更可能な Unicode 文字バッファを作成します。返されるオブジェクトは `c_wchar` の ctypes 配列です。

  init_or_size は配列のサイズを指定する整数もしくは配列要素を初期化するために使われる文字列である必要があります。

  第一引数として文字列が指定された場合は、バッファが文字列の長さより一要素分大きく作られます。配列の最後の要素が NUL 終端文字であるためです。文字列の長さを使うべきでない場合は、配列のサイズを指定するために整数を第二引数として渡すことができます。

`ctypes.``DllCanUnloadNow`()

  Windows 用: この関数は ctypes をつかってインプロセス COM サーバーを実装できるようにするためのフックです。_ctypes 拡張 dll がエクスポートしている DllCanUnloadNow 関数から呼び出されます。

`ctypes.``DllGetClassObject`()

  Windows 用: この関数は ctypes をつかってインプロセス COM サーバーを実装できるようにするためのフックです。`_ctypes` 拡張 dll がエクスポートしている DllGetClassObject 関数から呼び出されます。

`ctypes.util.``find_library`(name)

  ライブラリを検索し、パス名を返します。 name は `lib` のような接頭辞、 `.so` や `.dylib` のような接尾辞、そして、バージョンナンバーを除くライブラリ名です (これは posix のリンカーオプション `-l` で使われる書式です) 。もしライブラリが見つからなければ、 `None` を返します。

  厳密な機能はシステムに依存します。

`ctypes.util.``find_msvcrt`()

  Windows 用: Python と拡張モジュールで使われる VC ランタイムライブラリのファイル名を返します。もしライブラリ名が同定できなければ、 `None` を返します。

  もし、例えば拡張モジュールにより割り付けられたメモリを `free(void *)` で解放する必要があるなら、メモリ割り付けを行ったのと同じライブラリの関数を使うことが重要です。

`ctypes.``FormatError`([code])

  Windows 用: エラーコード code の説明文を返します。エラーコードが指定されない場合は、 Windows api 関数 GetLastError を呼び出して、もっとも新しいエラーコードが使われます。

`ctypes.``GetLastError`()

  Windows 用: 呼び出し側のスレッド内で Windows によって設定された最新のエラーコードを返します。この関数は Windows の GetLastError() 関数を直接実行します。 ctypes のプライベートなエラーコードのコピーを返したりはしません。

`ctypes.``get_errno`()

  システムの `errno` 変数の、スレッドローカルなプライベートコピーを返します。

`ctypes.``get_last_error`()

  Windows 用: システムの `LastError` 変数の、スレッドローカルなプライベートコピーを返します。

`ctypes.``memmove`(dst, src, count)

  標準 C の memmove ライブラリ関数と同じものです。: count バイトを src から dst へコピーします。 dst と src はポインタへ変換可能な整数または ctypes インスタンスでなければなりません。

`ctypes.``memset`(dst, c, count)

  標準 C の memset ライブラリ関数と同じものです。: アドレス dst のメモリブロックを値 c を count バイト分書き込みます。 dst はアドレスを指定する整数または ctypes インスタンスである必要があります。

`ctypes.``POINTER`(type)

  このファクトリ関数は新しい ctypes ポインタ型を作成して返します。ポインタ型はキャッシュされ、内部で再利用されます。したがって、この関数を繰り返し呼び出してもコストは小さいです。type は ctypes 型でなければなりません。

`ctypes.``pointer`(obj)

  この関数は obj を指す新しいポインタインスタンスを作成します。戻り値は `POINTER(type(obj))` 型のオブジェクトです。

  注意: 外部関数呼び出しへオブジェクトへのポインタを渡したいだけなら、はるかに高速な `byref(obj)` を使うべきです。

`ctypes.``resize`(obj, size)

  この関数は obj の内部メモリバッファのサイズを変更します。 obj は ctypes 型のインスタンスでなければなりません。バッファを `sizeof(type(obj))` で与えられるオブジェクト型の本来のサイズより小さくすることはできませんが、バッファを拡大することはできます。

`ctypes.``set_errno`(value)

  システム変数 `errno` の、呼び出し元スレッドでの ctypes のプライベートコピーの現在値を value に設定し、前の値を返します。

`ctypes.``set_last_error`(value)

  Windows 用: システム変数 `LastError` の、呼び出し元スレッドでの ctypes のプライベートコピーの現在値を value に設定し、前の値を返します。

`ctypes.``sizeof`(obj_or_type)

  ctypes の型やインスタンスのメモリバッファのサイズをバイト数で返します。C の `sizeof` 演算子と同様の動きをします。

`ctypes.``string_at`(address, size=-1)

  この関数はメモリアドレス address から始まる C 文字列を返します。size が指定された場合はサイズとして使われます。指定されなければ、文字列がゼロ終端されていると仮定します。

`ctypes.``WinError`(code=None, descr=None)

  Windows 用: この関数はおそらく ctypes の中で最悪の名前でしょう。これは OSError のインスタンスを作成します。 code が指定されていなかった場合、エラーコードを判別するために `GetLastError` が呼び出されます。 descr が指定されていなかった場合、エラーの説明文を得るために `FormatError()` が呼び出されます。

  バージョン 3.3 で変更: 以前は `WindowsError` インスタンスが作成されていました。

`ctypes.``wstring_at`(address, size=-1)

  この関数は文字列としてメモリアドレス address から始まるワイドキャラクタ文字列を返します。size が指定されたならば、文字列の文字数として使われます。指定されなければ、文字列がゼロ終端されていると仮定します。

### 16.16.2.6. データ型

class `ctypes.``_CData`

  この非公開クラスはすべての ctypes データ型の共通のベースクラスです。他のことはさておき、すべての ctypes 型インスタンスは C 互換データを保持するメモリブロックを内部に持ちます。このメモリブロックのアドレスは `addressof()` ヘルパー関数が返します。別のインスタンス変数が `_objects` として公開されます。これはメモリブロックがポインタを含む場合に存続し続ける必要のある他の Python オブジェクトを含んでいます。

  ctypes データ型の共通メソッド、すべてのクラスメソッドが存在します (正確には、 メタクラス のメソッドです):

  `from_buffer`(source[, offset])

    このメソッドは source オブジェクトのバッファを共有する ctypes のインスタンスを返します。 source オブジェクトは書き込み可能バッファインターフェースをサポートしている必要があります。オプションの offset 引数では source バッファのオフセットをバイト単位で指定します。デフォルトではゼロです。もし source バッファが十分に大きくなければ、 `ValueError` が送出されます。

  `from_buffer_copy`(source[, offset])

    このメソッドは source オブジェクトの読み出し可能バッファをコピーすることで、ctypes のインスタンスを生成します。オプションの offset 引数では source バッファのオフセットをバイト単位で指定します。デフォルトではゼロです。もし source バッファが十分に大きくなければ、 `ValueError` が送出されます。

  `from_address`(address)

    このメソッドは address で指定されたメモリを使って ctypes 型のインスタンスを返します。 address は整数でなければなりません。

  `from_param`(obj)

    このメソッドは obj を ctypes 型に適合させます。外部関数の `argtypes` タプルに、その型があるとき、外部関数呼び出しで実際に使われるオブジェクトと共に呼び出されます。

    すべての ctypes のデータ型は、それが型のインスタンスであれば、 obj を返すこのクラスメソッドのデフォルトの実装を持ちます。いくつかの型は、別のオブジェクトも受け付けます。

  `in_dll`(library, name)

    このメソッドは、共有ライブラリによってエクスポートされた ctypes 型のインスタンスを返します。 name はエクスポートされたデータの名前で、 library はロードされた共有ライブラリです。

  ctypes データ型共通のインスタンス変数:

  `_b_base_`

    ctypes 型データのインスタンスは、それ自身のメモリブロックを持たず、基底オブジェクトのメモリブロックの一部を共有することがあります。 `_b_base_` 読み出し専用属性は、メモリブロックを保持する ctypes の基底オブジェクトです。

  `_b_needsfree_`

    この読み出し専用の変数は、 ctypes データインスタンスが、それ自身に割り当てられたメモリブロックを持つとき true になります。それ以外の場合は false になります。

  `_objects`

    このメンバは `None` 、または、メモリブロックの内容が正しく保つために、生存させておかなくてはならない Python オブジェクトを持つディクショナリです。このオブジェクトはデバッグでのみ使われます。決してディクショナリの内容を変更しないで下さい。

### 16.16.2.7. 基本データ型

class `ctypes.``_SimpleCData`

  この非公開クラスは、全ての基本的な ctypes データ型の基底クラスです。これは基本的な ctypes データ型に共通の属性を持っているので、ここで触れておきます。 `_SimpleCData` は `_CData` の子クラスなので、そのメソッドと属性を継承しています。ポインタでないかポインタを含まない ctypes データ型は、現在は pickle 化できます。

  インスタンスは一つだけ属性を持ちます:

  `value`

    この属性は、インスタンスの実際の値を持ちます。整数型とポインタ型に対しては整数型、文字型に対しては一文字のバイト列オブジェクト、文字へのポインタに対しては Python のバイト列オブジェクトもしくは文字列となります。

    `value` 属性が ctypes インスタンスより参照されたとき、大抵の場合はそれぞれに対し新しいオブジェクトを返します。 `ctypes` はオリジナルのオブジェクトを返す実装にはなって おらず 新しいオブジェクトを構築します。同じことが他の ctypes オブジェクトインスタンスに対しても言えます。

基本データ型は、外部関数呼び出しの結果として返されたときや、例えば構造体のフィールドメンバーや配列要素を取り出すときに、ネイティブの Python 型へ透過的に変換されます。言い換えると、外部関数が `c_char_p` の `restype` を持つ場合は、 `c_char_p` インスタンスでは なく 常に Python バイト列オブジェクトを受け取ることでしょう。

基本データ型のサブクラスはこの振る舞いを継承 しません 。したがって、外部関数の `restype` が `c_void_p` のサブクラスならば、関数呼び出しからこのサブクラスのインスタンスを受け取ります。もちろん、 `value` 属性にアクセスしてポインタの値を得ることができます。

これらが基本 ctypes データ型です:

class `ctypes.``c_byte`

  C の `signed char` データ型を表し、小整数として値を解釈します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class `ctypes.``c_char`

  C `char` データ型を表し、単一の文字として値を解釈します。コンストラクタはオプションの文字列初期化子を受け取り、その文字列の長さちょうど一文字である必要があります。

class `ctypes.``c_char_p`

  C `char *` データ型を表し、ゼロ終端文字列へのポインタでなければなりません。バイナリデータを指す可能性のある一般的なポインタに対しては `POINTER(c_char)` を使わなければなりません。コンストラクタは整数のアドレスもしくはバイト列オブジェクトを受け取ります。

class `ctypes.``c_double`

  C `double` データ型を表します。コンストラクタはオプションの浮動小数点数初期化子を受け取ります。

class `ctypes.``c_longdouble`

  C `long double` データ型を表します。コンストラクタはオプションで浮動小数点数初期化子を受け取ります。 `sizeof(long double) == sizeof(double)` であるプラットフォームでは `c_double` の別名です。

class `ctypes.``c_float`

  C `float` データ型を表します。コンストラクタはオプションの浮動小数点数初期化子を受け取ります。

class `ctypes.``c_int`

  C `signed int` データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。 `sizeof(int) == sizeof(long)` であるプラットフォームでは、 `c_long` の別名です。

class `ctypes.``c_int8`

  C 8-bit `signed int` データ型を表します。たいていは、 `c_byte` の別名です。

class `ctypes.``c_int16`

  C 16-bit `signed int` データ型を表します。たいていは、 `c_short` の別名です。

class `ctypes.``c_int32`

  C 32-bit `signed int` データ型を表します。たいていは、 `c_int` の別名です。

class `ctypes.``c_int64`

  C 64-bit `signed int` データ型を表します。たいていは、 `c_longlong` の別名です。

class `ctypes.``c_long`

  C `signed long` データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class `ctypes.``c_longlong`

  C `signed long long` データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class `ctypes.``c_short`

  C `signed short` データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class `ctypes.``c_size_t`

  C `size_t` データ型を表します。

class `ctypes.``c_ssize_t`

  C `ssize_t` データ型を表します。

  バージョン 3.2 で追加.

class `ctypes.``c_ubyte`

  C の `unsigned char` データ型を表し、小さな整数として値を解釈します。コンストラクタはオプションの整数初期化子を受け取ります; オーバーフローのチェックは行われません。

class `ctypes.``c_uint`

  C の `unsigned int` データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります; オーバーフローのチェックは行われません。これは、 `sizeof(int) == sizeof(long)` であるプラットフォームでは `c_ulong` の別名です。

class `ctypes.``c_uint8`

  C 8-bit `unsigned int` データ型を表します。たいていは、 `c_ubyte` の別名です。

class `ctypes.``c_uint16`

  C 16-bit `unsigned int` データ型を表します。たいていは、 `c_ushort` の別名です。

class `ctypes.``c_uint32`

  C 32-bit `unsigned int` データ型を表します。たいていは、 `c_uint` の別名です。

class `ctypes.``c_uint64`

  C 64-bit `unsigned int` データ型を表します。たいていは、 `c_ulonglong` の別名です。

class `ctypes.``c_ulong`

  C `unsigned long` データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class `ctypes.``c_ulonglong`

  C `unsigned long long` データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class `ctypes.``c_ushort`

  C `unsigned short` データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class `ctypes.``c_void_p`

  C `void *` データ型を表します。値は整数として表されます。コンストラクタはオプションの整数初期化子を受け取ります。

class `ctypes.``c_wchar`

  C `wchar_t` データ型を表し、値は Unicode 文字列の単一の文字として解釈されます。コンストラクタはオプションの文字列初期化子を受け取り、その文字列の長さはちょうど一文字である必要があります。

class `ctypes.``c_wchar_p`

  C `wchar_t *` データ型を表し、ゼロ終端ワイド文字列へのポインタでなければなりません。コンストラクタは整数のアドレスもしくは文字列を受け取ります。

class `ctypes.``c_bool`

  C の `bool` データ型 (より正確には、 C99 以降の `_Bool`) を表します。 `True` または `False` の値を持ち、コンストラクタは真偽値と解釈できるオブジェクトを受け取ります。

class `ctypes.``HRESULT`

  Windows用: `HRESULT` 値を表し、関数またはメソッド呼び出しに対する成功またはエラーの情報を含んでいます。

class `ctypes.``py_object`

  C `PyObject *` データ型を表します。引数なしでこれを呼び出すと `NULL` `PyObject *` ポインタを作成します。

`ctypes.wintypes` モジュールは他の Windows 固有のデータ型を提供します。例えば、 `HWND`, `WPARAM`, `DWORD` です。 `MSG` や `RECT` のような有用な構造体も定義されています。

### 16.16.2.8. 構造化データ型

class `ctypes.``Union`(*args, **kw)

  ネイティブのバイトオーダーでの共用体のための抽象ベースクラス。

class `ctypes.``BigEndianStructure`(*args, **kw)

  ビックエンディアン バイトオーダーでの構造体のための抽象ベースクラス。

class `ctypes.``LittleEndianStructure`(*args, **kw)

  リトルエンディアン バイトオーダーでの構造体のための抽象ベースクラス。

ネイティブではないバイトオーダーを持つ構造体にポインタ型フィールドあるいはポインタ型フィールドを含む他のどんなデータ型をも入れることはできません。

class `ctypes.``Structure`(*args, **kw)

  ネイティブ のバイトオーダーでの構造体のための抽象ベースクラス。

  具象構造体型と具象共用体型はこれらの型の一つをサブクラス化することで作らなければなりません。少なくとも、 `_fields_` クラス変数を定義する必要があります。 `ctypes` は、属性に直接アクセスしてフィールドを読み書きできるようにする記述子 (descriptor) を作成するでしょう。これらは、

  `_fields_`

    構造体のフィールドを定義するシーケンス。要素は2要素タプルか3要素タプルでなければなりません。第一要素はフィールドの名前です。第二要素はフィールドの型を指定します。それはどんな ctypes データ型でも構いません。

    `c_int` のような整数型のために、オプションの第三要素を与えることができます。フィールドのビット幅を定義する正の小整数である必要があります。

    一つの構造体と共用体の中で、フィールド名はただ一つである必要があります。これはチェックされません。名前が繰り返しでてきたときにアクセスできるのは一つのフィールドだけです。

    Structure サブクラスを定義するクラス文の 後で 、 `_fields_` クラス変数を定義することができます。これにより、次のように自身を直接または間接的に参照するデータ型を作成できるようになります:

        class List(Structure):
            pass
        List._fields_ = [("pnext", POINTER(List)),
                         ...
                        ]

    しかし、 `_fields_` クラス変数はその型が最初に使われる (インスタンスが作成される、それに対して `sizeof()` が呼び出されるなど) より前に定義されていなければなりません。その後 `_fields_` クラス変数へ代入すると AttributeError が送出されます。

    構造体型のサブクラスを定義することができ、もしあるならサブクラス内で定義された `_fields_` に加えて、ベースクラスのフィールドも継承します。

  `_pack_`

    インスタンスの構造体フィールドのアライメントを上書きできるようにするオブションの小整数。 `_pack_` は `_fields_` が代入されたときすでに定義されていなければなりません。そうでなければ、何の効果もありません。

  `_anonymous_`

    無名 (匿名) フィールドの名前が並べあげられたオプションのシーケンス。 `_fields_` が代入されたとき、 `_anonymous_` がすでに定義されていなければなりません。そうでなければ、何ら影響はありません。

    この変数に並べあげられたフィールドは構造体型もしくは共用体型フィールドである必要があります。構造体フィールドまたは共用体フィールドを作る必要なく、入れ子になったフィールドに直接アクセスできるようにするために、 `ctypes` は構造体型の中に記述子を作成します。

    型の例です (Windows):

        class _U(Union):
            _fields_ = [("lptdesc", POINTER(TYPEDESC)),
                        ("lpadesc", POINTER(ARRAYDESC)),
                        ("hreftype", HREFTYPE)]

        class TYPEDESC(Structure):
            _anonymous_ = ("u",)
            _fields_ = [("u", _U),
                        ("vt", VARTYPE)]

    `TYPEDESC` 構造体はCOMデータ型を表現しており、 `vt` フィールドは共用体フィールドのどれが有効であるかを指定します。 `u` フィールドは匿名フィールドとして定義されているため、 TYPEDESC インスタンスから取り除かれてそのメンバーへ直接アクセスできます。 `td.lptdesc` と `td.u.lptdesc` は同等ですが、前者がより高速です。なぜなら一時的な共用体インスタンスを作る必要がないためです。:

        td = TYPEDESC()
        td.vt = VT_PTR
        td.lptdesc = POINTER(some_type)
        td.u.lptdesc = POINTER(some_type)

  構造体のサブ-サブクラスを定義することができ、ベースクラスのフィールドを継承します。サブクラス定義に別の `_fields_` 変数がある場合は、この中で指定されたフィールドはベースクラスのフィールドへ追加されます。

  構造体と共用体のコンストラクタは位置引数とキーワード引数の両方を受け取ります。位置引数は `_fields_` の中に現れたのと同じ順番でメンバーフィールドを初期化するために使われます。コンストラクタのキーワード引数は属性代入として解釈され、そのため、同じ名前をもつ `_fields_` を初期化するか、 `_fields_` に存在しない名前に対しては新しい属性を作ります。

### 16.16.2.9. 配列とポインタ

class `ctypes.``Array`(*args)

  配列のための抽象基底クラスです。

  具象配列型を作成するための推奨される方法は、任意の `ctypes` データ型に正の整数を乗算することです。代わりに、この型のサブクラスを作成し、 `_length_` と `_type_` のクラス変数を定義することもできます。配列の要素は、標準の添え字とスライスによるアクセスを使用して読み書きを行うことができます。スライスの読み込みでは、結果のオブジェクト自体は `Array` ではありません。

  `_length_`

    配列の要素数を指定する正の整数。範囲外の添え字を指定すると、 `IndexError` が送出されます。`len()` がこの整数を返します。

  `_type_`

    配列内の各要素の型を指定します。

  配列のサブクラスのコンストラクタは、位置引数を受け付けて、配列を順番に初期化するために使用します。

class `ctypes.``_Pointer`

  ポインタのためのプライベートな抽象基底クラスです。

  具象ポインタ型は、ポイント先の型を持つ `POINTER()` を呼び出すことで、作成できます。これは、 `pointer()` により自動的に行われます。

  ポインタが配列を指す場合、その配列の要素は、標準の添え字とスライスによるアクセスを使用して読み書きが行えます。ポインタオブジェクトには、サイズがないため、 `len()` 関数は `TypeError` を送出します。負の添え字は、(C と同様に) ポインタの 前 のメモリから読み込み、範囲外の添え字はおそらく (幸運な場合でも) アクセス違反によりクラッシュを起こします。

  `_type_`

    ポイント先の型を指定します。

  `contents`

    ポインタが指すオブジェクトを返します。この属性に割り当てると、ポインタが割り当てられたオブジェクトを指すようになります。