外部関数は関数プロトタイプをインスタンス化することによって作成されます。 関数プロトタイプはCの関数プロトタイプと似ています。実装を定義せずに、 関数(戻り値、引数の型、呼び出し規約)を記述します。 ファクトリ関数は関数に要求する戻り値の型と引数の型とともに呼び出されます。
restype, *argtypes) |
restype, *argtypes) |
stdcall
呼び出し規約を
つかう関数を作成します。ただし、WINFUNCTYPEが
CFUNCTYPEと同じであるWindows CEを除く。
関数は呼び出されている間GILを解放します。
restype, *argtypes) |
ファクトリ関数によって作られた関数プロトタイプは呼び出しのパラメータの型と数に依存した 別の方法でインスタンス化することができます。
address) |
callable) |
callable
からCの呼び出し可能関数(コールバック関数)を作成します。
func_spec[, paramflags]) |
func_spec
は2要素タプル(name_or_ordinal, library)
でなければなりません。
第一要素はエクスポートされた関数の名前である文字列、またはエクスポートされた関数の
序数である小さい整数です。第二要素は共有ライブラリインスタンスです。
vtbl_index, name[, paramflags[, iid]]) |
vtbl_index
は仮想関数テーブルのインデックスで、非負の小さい整数です。
nameはCOMメソッドの名前です。iidはオプションの
インターフェイス識別子へのポインタで、拡張されたエラー情報の提供のために
使われます。
COMメソッドは特殊な呼び出し規約を用います。このメソッドは argtypesタプルに指定されたパラメータに加えて、 第一引数としてCOMインターフェイスへのポインタを必要とします。
オプションのparamflagsパラメータは上述した機能より多機能な 外部関数ラッパーを作成します。
paramflagsはargtypesと同じ長さのタプルでなければならない。
このタプルの個々の要素はパラメータについてのより詳細な情報を持ち、 1、2もしくは3要素を含むタプルでなければならない。
第一要素はパラメータについてのフラグを含んだ整数です。
オプションの第二要素はパラメータ名の文字列です。これが指定された場合は、 外部関数を名前付きパラメータで呼び出すことができます。
オプションの第三要素はこのパラメータのデフォルト値です。
この例では、デフォルトパラメータと名前付き引数をサポートするために
Windows MessageBoxA
関数をラップする方法を示します。
windowsヘッダファイルのCの宣言はこれです:
WINUSERAPI int WINAPI MessageBoxA( HWND hWnd , LPCSTR lpText, LPCSTR lpCaption, UINT uType);
ctypes
を使ってラップします:
>>> from ctypes import c_int, WINFUNCTYPE, windll >>> from ctypes.wintypes import HWND, LPCSTR, UINT >>> prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT) >>> paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0) >>> MessageBox = prototype(("MessageBoxA", 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 >>>
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。