※単にPythonでCのDLLの関数を呼びたいのならctypesのほうがいいかも知れません。

VC8でSWIGを使ってC++でPython用の拡張モジュールを作る。

SWIGというのは各種スクリプト言語(Perl, Python, Rubyなど結構たくさん)の拡張ライブラリをC++で書くためのグルーライブラリ。

C/C++で書かれたライブラリをSWIGを使ってPerlやPythonなどのスクリプト言語で使えるようにできる。

ここではVC8でSWIGを使ってC++でPython用の拡張モジュールを作る手順をざっとメモ。

SWIGの情報

ダウンロード

以下のようにリンクをたどれば落とせる。

インストール

解凍したライブラリを展開してどっかにおく。

拡張ライブラリの作成

ここでは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)

と設定。