※単にPythonでCのDLLの関数を呼びたいのならctypesのほうがいいかも知れません。
VC8でSWIGを使ってC++でPython用の拡張モジュールを作る。
SWIGというのは各種スクリプト言語(Perl, Python, Rubyなど結構たくさん)の拡張ライブラリをC++で書くためのグルーライブラリ。
C/C++で書かれたライブラリをSWIGを使ってPerlやPythonなどのスクリプト言語で使えるようにできる。
ここではVC8でSWIGを使ってC++でPython用の拡張モジュールを作る手順をざっとメモ。
SWIGの情報
- 英語公式:http://www.swig.org/
- いっつもくそ重い。InternetArchiveから見たほうが早いかも
- SWIG Basics
- SWIG and Python
- Typemaps
- 日本語:http://swig.shibu.jp/
- なくなった。。。?
- http://swig.shibu.jp/doc1319/index.html
- ドキュメント日本語
- http://swig.shibu.jp/doc1319/Windows.html
- Windowsでの導入
- http://radiofly.to/nishi/programming/swig.html
- http://www.02.246.ne.jp/~torutk/cxx/swig/install.html
- swigでpythonとcでunix
- http://chasen.org/~taku/blog/archives/2005/09/post_812.html
- Dartsを使ったはてなキーワードを高速に付与するサンプルをSWIGでPerlモジュール化。
- Pythonのモジュールもついてくる。ただしMakefileで構成
ダウンロード
以下のようにリンクをたどれば落とせる。
- ↓英語公式:http://www.swig.org/
- ↓Download:http://www.swig.org/survey.html
- ↓DownloadArea?:http://www.swig.org/download.html
- ↓All Releases:http://sourceforge.net/project/showfiles.php?group_id=1645
- ↓swigwin:http://sourceforge.net/project/showfiles.php?group_id=1645&package_id=8156&release_id=363719
- ↓swigwin-*.zip:http://prdownloads.sourceforge.net/swig/swigwin-*.zip?download
インストール
解凍したライブラリを展開してどっかにおく。
拡張ライブラリの作成
ここではVC8で作る。とりあえずよくあるhello worldっぽいのを作る。 具体的には以下のような仕様
import hello_world print hello_world.get()
とすると
Hello World!
と表示されるようなhello_worldモジュール。
今回具体的に作成するのは主にhello_world.pyと_hello_world.pyd
- VC8を起動
- ファイル→新規作成→プロジェクト→新しいプロジェクト
- プロジェクトの種類→Visual C++ プロジェクト→テンプレート→Win32プロジェクト
- プロジェクト名→_hello_worldと入力→OK
- アプリケーションの設定→DLL→空のプロジェクト→完了
- ファイル→新しい項目の追加→テンプレート→C++ファイル(テキストなら何でもよい)
- ファイル名→hello_world.iと入力→開く
- 開かれたhello_world.iに以下を入力
%module hello_world %include hello_world.h
- プロジェクト→プロパティ→_hello_worldプロパティページ
- 構成→すべての構成
- 構成プロパティ→カスタムビルドステップ→コマンドライン→"swig.exe" -python -o "$$(ProjectDir)\$$(InputName)_python_wrap.c" "$$(InputPath)"
- 出力ファイル→"$$(ProjectDir)\$$(InputName)_python_wrap.c"
- プロパティを開いたままソリューションエクスプローラで_hello_worldを選択
- 構成→Release
- 構成プロパティ→ビルドイベント→ビルド後のイベント→
copy "$(TargetPath)" "$(SolutionDir)..\$(TargetFileName)" copy "$(SafeInputName).py" "$(SolutionDir)..\$(SafeInputName).py"
- プロパティを閉じる。
- ファイル→新しい項目の追加→テンプレート→テキスト系のファイル→hello_world.hと入力→開く
extern "C" { const char* get(); } - 構成→Debug
- 構成プロパティ→デバッグ→コマンド→python_d.exe
- コマンド引数→test.py
- 作業ディレクトリ→$$(OutDir)
- 構成プロパティ→リンカ→入力→追加の依存ファイル→"python24_d.lib"
- 構成プロパティ→リンカ→全般→出力ファイル→$$(OutDir)\$$(ProjectName)_d.dll
- ここで一回ビルド
- ファイル→既存の項目→hello_world_python_wrap.c
- hello_world_python_wrap.cを右クリック→プロパティ→C/C++→全般→追加のインクルードディレクトリ→Python\include
- RTLでなくSDKの場合はさらにPython\PCも追加
- 詳細→指定の警告を無効にする→4244;4013;4312
- ファイル→新しい項目の追加→テンプレート→テキスト系のファイル→hello_world.cppと入力→開く
const char* get() { return "Hello World!"; }
- ビルド→構成マネージャー→アクティブソリューション構成→Release→OK
- ビルド
以上でhello_world.pyと_hello_world.dllが作成できた。
test_hello_world.pyで
import hello_world print hello_world.get()
として
Hello World!
となればOk
デバッグ用の設定
まずスクリプトエラーをチェック
- プロジェクト→プロパティ→_hello_worldプロパティページ→構成→Debug
- 構成プロパティ→デバッグ
に、
- コマンド cmd
- コマンド引数 /k ""C:\Documents and Settings\All Users\Documents\Libs\python24\python_d.exe" "$$(SolutionDir)test_$$(SafeInputName).py""
- 作業ディレクトリ $$(OutDir)
と設定。
スクリプトエラーなしで動いたら
- コマンド "C:\Documents and Settings\All Users\Documents\Libs\python24\python_d.exe"
- コマンド引数 "$$(SolutionDir)test_$$(SafeInputName).py"
- 作業ディレクトリ $$(OutDir)
と設定。