サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]
#define BOOST_PYTHON_STATIC_LIB //← Boost.Pythonを静的リンクする場合。
// これなしだとBoost.PythonのDLLに依存した実行ファイルになります
#include <iostream>
#include <boost/python.hpp>
using namespace std;
// てきとーな関数
int cppFun( int x )
{
cout << "Inside C++" << endl;
return x+3;
}
int main()
{
using namespace boost::python;
// Python インタプリタ初期化
Py_Initialize();
// グローバルの名前空間を取得
object global_ns = import("__main__").attr("__dict__");
// C++ で定義した関数 cppFun を、Pythonから f という名前で使う
global_ns["f"] = &cppFun;
// Python のコードを実行
exec( "print( 'Inside Python' ) \n"
"def g(x): \n"
" return f(x)**3 \n", global_ns, global_ns );
// Python で定義した関数 g を、C++ から pythonFun という名前で使う
object pythonFun = global_ns["g"];
// (2+3)**3 = 125 が計算される
object v = pythonFun(2);
cout << extract<int>(v) << endl;
}
Inside Python Inside C++ 125
サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]
#define BOOST_PYTHON_STATIC_LIB
#include <string>
#include <boost/python.hpp>
using namespace std;
// てきとーな関数
string add_hello( string s )
{
return "Hello, " + s;
}
int square( int n )
{
return n * n;
}
// モジュールの初期化ルーチン:モジュール名=my_sample
BOOST_PYTHON_MODULE( my_sample )
{
// C++のadd_hello関数を、greetという名前でpython用に公開
boost::python::def( "greet", add_hello );
// C++のsquare関数を、squareという名前でpython用に公開
boost::python::def( "square", square );
}
## 拡張子 .pyd の共有ライブラリとしてコンパイルして、インストール
> cl my_sample.cpp /Femy_sample.pyd /LD
> copy my_sample.pyd %PYTHONDIR%\DLLs
※ VC++ on Windowsの場合のサンプルです。
>>> import my_sample >>> print my_sample.greet( "Taro" ) Hello, Taro >>> print my_sample.square( 50 ) 2500 >>>
ご存じの方も多いと思われますが、Python というオブジェクト指向なスクリプト言語があります。
この Python を C++ から使ったり、 あるいは逆にPythonから使うための拡張モジュールをC++で実装したりするときの、 色々面倒なところを上手く処理してくれるのが Boost.Pythonであります。 上の例では関数しか扱っていませんが、勿論クラスを扱うこともOK。 一から拡張モジュールを書くと、(私はやったことないので詳しくは知りませんが、) ガーベジコレクト用の参照カウント管理や、引数の解析、 型チェックなどなどの面倒な処理をモジュール側でやらないといけないらしいのですが、 その辺りをラッピングしてあるそうです。