ctypes拡張モジュール

April 5, 2018 | Author: Anonymous | Category: Technology
Report this link


Description

1. ctype拡張モジュール Moriyoshi Koizumi 2. 自己紹介 ● はてな:moriyoshi ● twitter:moriyoshit ● 某研究機関で生物シミュレーションの研究をし ています。 ● 日々PythonとC++を書いてます!! ● 好きなテンプレート言語はPHPです!!!! 3. パーフェクトPHP出ました 4. 月刊Python出ます 5. BeepLoudやってます! 6. はい 7. ctypes拡張モジュールとは ● Python 2.5より追加 ● Thomas Heller作 ● C言語で書かれた共有ライブラリをPythonから 利用するためのライブラリ ● 中身はlibffiのラッパー ● 複数のOSに対応 ● といってもピンときませんよね... 8. C言語で書かれた共有ライブラリを Pythonから利用するための ライブラリ 9. それCythonでできるよ ● CythonはCython拡張を施されたPythonで書か れたコードをCに変換する仕組み ● 生成されたCのコードをPythonのC拡張にコン パイルしない限りは利用できない ● 開発にはCをコンパイル、リンクする環境が必 要 ● 配布時にも、各プラットフォーム用のバイナリ の準備が必要 10. ctypesなら? ● 純粋なPythonスクリプトからCの関数を呼び出 せる – コンパイル不要 – 配布時のバイナリ同梱も不要 ● プロトタイプ作成、C関数のテストコード作成 に威力を発揮 11. Show me what it looks like!import ctypes# 標準Cライブラリを読み込む dll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")# ライブラリの関数を呼び出す dll.printf("Hello, %s world!n", "bucho") 12. 基本的な使い方 ● ctypes.CDLL オブジェクトを、引数として共有 ライブラリ名を渡して生成 ● ctypesオブジェクトの属性にアクセスすると、 C関数を呼び出すためのラッパー関数が自動的 に生成される ● ラッパー関数は普通のPythonの関数として扱え る ● ラッパー関数に渡す引数は自動的にCの型に変 換される 13. デモ 14. 値ラッパー import ctypesdll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")dll.printf("%gn", 3.14)実行結果 Traceback (most recent call last):File , line 3, in dll.printf("%gn", 3.14) ctypes.ArgumentError: argument 2: : Don't know how to convert parameter 2 15. 値ラッパー import ctypesdll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")dll.printf("%gn", ctypes.c_double(3.14))実行結果 3.14 16. 値ラッパー ● 組み込みのPythonの型とCの型は一対一で対応 していない ● Cの型に対応するPython型をctypes側で用意 ● 明示的に型を指定してC関数を呼び出したい場 合は値ラッパーのオブジェクトを渡すと、最終 的に対応するCの型に変換される 17. 値ラッパー 値ラッパークラス対応するCの型 c_byte, c_ubyte, c_short, char, unsigned char, short, c_ushort, c_int, c_uint,unsigned short, int, c_long, c_ulong, c_longlong,unsigned int, long, unsigned c_ulonglong long, long long, unsigned long long c_foat, c_double, foat, double, long double c_longdouble c_char_p, c_wchar_p char *, wchar_t* c_void_pvoid *など 18. もうちょっと複雑な例 import ctypes# 標準Cライブラリを読み込む dll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")# ライブラリの関数を呼び出す dll.getcwd.restype = ctypes.c_char_p print dll.getcwd() # 現在の作業ディレクトリdll.sqrt.restype = ctypes.c_double dll.sqrt.argtypes = (ctypes.c_double, ) print dll.sqrt(16) # 16の平方根 19. もうちょっと複雑な例 ● C関数の戻り値の型は、デフォルトではint型で あるとみなされる ● C関数のシグニチャを指定するときは、 ラッパー関数の以下の属性を指定する。 – restype – argtypes 20. ポインタ渡し import ctypesdll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")retval = ctypes.c_int() dll.scanf("%d", ctypes.byref(retval)) print retval 21. ポインタ渡し ● 引数に指定されたポインタの示す先に戻り値を 返すようなC関数を扱う場合 ● ctypes.byref() 22. ctypes.POINTER ● 任意の型のポインタ型を作る場合は ctypes.POINTER(型) を呼ぶと、対応するポイ ンタ型が作られる ● ctypes.POINTER(ctypes.c_int) → int * 23. ctypes.POINTERimport ctypes c_int_p = ctypes.POINTER(ctypes.c_int) dll =ctypes.CDLL("/usr/lib/libSystem.B.dylib") retval = ctypes.c_int()dll.scanf("%d", c_int_p(retval))print retval※このケースだと、ctypes.byref() 使った方が早いです。 24. 構造体 ● ctypes.Structureクラスを継承したクラスを作る ことで、Cの構造体に対応したラッパー型を作 れる ● _fields_ 属性に (フィールド名, 型) からなるタ プルのリストを渡す 25. 構造体 struct tm { class TMStructure(ctypes.Structure): int tm_sec; _fields_ = [ int tm_min; ('tm_sec', ctypes.c_int), int tm_hour;('tm_min', ctypes.c_int), int tm_mday;('tm_hour', ctypes.c_int), int tm_mon; ('tm_mday', ctypes.c_int), int tm_year;('tm_mon', ctypes.c_int), int tm_wday;('tm_year', ctypes.c_int), int tm_yday;('tm_wday', ctypes.c_int), int tm_isdst; ('tm_yday', ctypes.c_int), char *tm_zone;('tm_isdst', ctypes.c_int), long tm_gmtoff; ('tm_zone', ctypes.c_char_p), };('tm_gmtoff', ctypes.c_long)] 26. コールバック関数 void call_callback(void(*cb)(const char *)) { cb("hoge"); }import ctypesdll = ctypes.CDLL("libcallback.dylib")cfun = ctypes.CFUNCTYPE(None, ctypes.c_char_p)def callback(string): print "Hello, %s world!" % stringdll.call_callback(cfun(callback)) 27. コールバック関数 ● ctypes.CFUNCTYPE(戻り値の型, [引数の型, 引 数の型...]) を呼び出して、コールバック関数の ラッパーオブジェクトを生成する ● ラッパーオブジェクトは、C関数の呼び出し時 に、関数ポインタに変換される 28. クロスプラットフォーム ● MacのPythonでも ● WindowsのPythonでも ● Free UnixのPythonでも ● それからIronPythonでも 29. 複数プラットフォームを サポートするときの注意点 ● たとえば標準C関数のライブラリ名はプラット フォームごとに違う ● sys.platform などでOSを判定して対処 30. まとめ ● dll = ctypes.CDLL()で読み込み ● dll.[関数名]() で関数を呼び出す ● 関数のシグニチャを指定したい場合はrestypeと argtypes ● ラッパー型 c_* ● ポインタ渡しは ctypes.byref() ● 構造体は ctypes.Structure ● コールバック関数は ctypes.CFUNCTYPE() 31. ご清聴ありがとうございました 32. はい 33. 始まって 34. しまいました 35. すべらない話 36. PSP Go® 37. 値下げしました 38. さて 39. P○P Go 40. ○の中に 入る文字は? 41. 1.H 2.S 3.P 42. はい 43. 1. PHP 44. ですね 45. PHP Go 46. 世の中 47. 見渡せば 48. Pythonばかり 49. PHPに日の目を 50. はい 51. PHP in Python 52. プロジェクト始動 53. http://bitbucket.org/moriyoshi/php-in-python


Comments

Copyright © 2024 UPDOCS Inc.