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

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

    >>> from ctypes import *
    >>> libc.printf
    <_FuncPtr object at 0x...>
    >>> print windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
    <_FuncPtr object at 0x...>
    >>> print windll.kernel32.MyOwnFunction # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      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") # doctest: +WINDOWS
    <_FuncPtr object at 0x...>
    >>>

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

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