###
18 dllからエクスポートされている値へアクセスする

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`ポインタにアクセスします。

Pythonドキュメントからの引用すると: このポインタは メンバーがすべてNULLまたはゼロであるレコードを最後に持つ``struct _frozen``レコードの 配列を指すように初期化されます。 フローズン(frozen)モジュールがインポートされたとき、このテーブルから探索されます。 サードパーティ製コードは動的に作成されたフローズンモジュールの集合を提供するためと、 これにいたずらすることができます。

これで、このポインタを操作することが役に立つことを証明できるでしょう。 例の大きさを制限するために、このテーブルを`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:
    ...    print item.name, item.size
    ...    if item.name is None:
    ...        break
    ...
    __hello__ 104
    __phello__ -104
    __phello__.spam 104
    None 0
    >>>

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