[python]ctypesモジュールを使ってみる

オライリーの『リバースエンジニアリング』のデバッガ自作の触りで登場した、pythonのctypesというモジュールに関して、ちゃんと使えるようになったら、もっと色々と便利そうなので、試してみました。

 

公式リファレンス

python2.5で追加され、C言語と互換性のあるデータ型を提供、動的リンクライブラリの関数呼び出しを可能にしてくれます。

 

サンプルコードはこちら(全てgithubにもアップロードしてあります)

サンプル1(windowsで動作させています)

これをwindowsで実行すると、ちゃんとWinAPIのsleep()とc標準ライブラリのprintfが呼び出されます。

C言語で提供されているデータ型はctypesモジュール内でラップされています。以下が提供されているデータ型です。

c_char char 1文字の 文字列
c_wchar wchar_t 1文字の ユニコード文字列
c_byte char 整数/長整数
c_ubyte unsigned char 整数/長整数
c_short short 整数/長整数
c_ushort unsigned short 整数/長整数
c_int int 整数/長整数
c_uint unsigned int 整数/長整数
c_long long 整数/長整数
c_ulong unsigned long 整数/長整数
c_longlong __int64 or long long 整数/長整数
c_ulonglong unsigned __int64 or unsigned long long 整数/長整数
c_float float 浮動小数点数
c_double double 浮動小数点数
c_char_p char * (NUL 終端) 文字列または None
c_wchar_p wchar_t * (NUL 終端) ユニコードまたは None
c_void_p void * 整数/長整数 またはNone

引用:公式リファレンス

 

pythonとCの大きな違いとして、

1.構造体がない

2.ポインタがない

 

ということがありますが、ctypesモジュールなら、ちゃんとそこもカバーしてくれます。

例えば

というC言語で書かれた構造体をpythonのctypesで表現するには

というようにclass 構造体名(Structure):の形式で宣言すれば利用できます。メンバは_fields_のなかに、リストで渡せばOKです。(メンバ名, データ型)です。

 

ポインタに関してはbyref()関数を使って

 

とすることでint型の変数iのポインタが変数pに代入されます。

これでC言語の機能を補完することができたと思います。

 

次に既存のdllを読み込んで関数を呼び出してみます。

サンプルはこちら

呼び出すと “hello world!”と出力するだけのhello()関数を作成します。

これをコンパイルして動的リンクライブラリ(dll)にしてあげます

これでdllファイルができあがります。(-cオプションなしにコンパイルするとmain()関数がないよ!ってエラーがでます)

これをpythonから読み込んでみます。

コードがこちら

CDLL()関数はファイルを指定して動的リンクライブラリを読み込む関数です。これで先ほどコンパイルしてできあがったdllファイルを読み込んであげます。

これを実行すると標準出力に”hello world!”が出力されるはずです。

要は今までC言語で作られた動的リンクライブラリがリソースとして再利用ができる、ということですね。これはワクワクします。

 

もうひとつサンプルとして、WinAPIのMessageBox()関数を呼び出してみたいと思います。

まずはMessageBox()関数の仕様を確認します。

MSDN-MessageBox()

ということらしいです。普段C言語でプログラミングしている方でも、ちょっと見慣れない型かもしれません。(Windowsプログラミングしているならお馴染みだと思いますが。)

それはこちらを参考にさせていただきました。

データ型について

MSDN-Windows Data Types

関数の引数だけでなく、どのライブラリを使っているかも重要です。MSDNのページの一番したのほうに書いてあります。ヘッダーファイルのほうではなくて、インポートライブラリのほうです。MessageBoxの場合はUser32ですね。それをctypesで読み込んであげます。

一つ目の引数は親ウィンドウがなければNULLで問題ないので、あとは文字列を二つと、スタイルを定義した定数を与えてあげるだけです。(これは種類がたくさんあるので、別に覚える必要はないと思いますが)

コードはこちら

 

これをwindowsから実行することで、メッセージボックスが表示されたかと思います。

 

ctypesの使い方の触りとしては、こんな感じですかね。

 

先日友達とバスケしに都内の体育会に行ったんですが、そこで知り合った同じ学校のゲーム学科の人からc++で書かれた面白いプログラム見せてもらったんで、それをctypesを使ってpythonで書きなおしたらまた紹介したいと思います。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です