2012年10月14日日曜日

boost python の導入

C/C++でglade使ってGTKのUI作ってOPENCVも使って、同時にArduinoも(firmataで)動かせればいいな〜と思いつつここ2週間ほど足掻いてきたけど

「もうむりぽ・・・(´ω`)、いまのぼくではpythonでしかopencvとarduinoを繋げないお・・」

 な感じになってきたので、やっぱりpythonで諸問題の解決に当たることにしました。

pythonにおける実行速度の問題解決方法はだいたい以下の路線になります。

1,cpython
2,pypy
3,boost python
4,そもそものアルゴリズムを変更

今回は3の「boost python」とかいうのに(C++勉強したのがもったいなかったので)挑戦したのでメモ

boost python・・・C++のコードを普通にpythonにimportできる神ライブラリ(boostっていうのはC++の準標準ライブラリ群のことらしい)

これでやたら計算時間がかかるベクトルの角度計算のとこだけ高速化できればめでたくHappyENDを迎えることができる。

で、Boostのインストールから(ubuntu 12.04 32bit)

synapticで「boost」で検索→libboost-python1.46.1(2012年10月現在)を インストール(依存関係にあるものも全部)。ほかの方法(apt-getとかtar玉から手動でインストールとかはなぜかうまく行かなかった(インストールはうまく行ったがその後が・・・)。ふつうはうまく行くはずなのでそちらで行けるならどうぞ)

おわり

使い方:
参考文献:
1.「[c++][python][boost]boost::pythonを使ってC++のPythonラッパーを作る」: ttp://d.hatena.ne.jp/sleepy_yoshi/20111120/p1

2.Boost.Python の機能をざっと紹介してみる : 
ttp://d.hatena.ne.jp/moriyoshi/20091214/1260779899

参考文献を参考にさせていただきながら、どうにかhello world的な行為に成功。


□まずc++のソースを書く(ほぼ参考文献2からの引用、コードの解説はそちらでどうぞ)

#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;
}

BOOST_PYTHON_MODULE(kakudo)
{
    // C++のadd_hello関数を、greetという名前でpython用に公開
    boost::python::def( "greet", add_hello );

    // C++のsquare関数を、squareという名前でpython用に公開
    boost::python::def( "square", square );
}

流れとしては、ヘッダ書く→関数書く(クラスもいけるらしい)→pythonの関数名との対応関係を記入という感じ。これだけ見るとわかりやすくて簡単そうだが・・・

□これをpythonで動かす

g++でコンパイル(コンパイルのオプションなんかは参考文献1からのパクr引用)

 g++ -I`python -c 'from distutils.sysconfig import *; print get_python_inc()'` -DPIC -shared -fPIC -o kakudo.so kakudo.cpp -lboost_python

↑何がなんだかわからない。ちょっと調べて簡略化(太字部分)

g++ -I/usr/include/python2.7 -DPIC -shared -fPIC -o kakudo.so kakudo.cpp -lboost_python

どうやらここはこの前の`pkg-config 〜`みたいな感じで「python.h」のおいてあるフォルダの位置(だいたいpythonのインストールフォルダ)と思われる(他のページでpython.hがいるって書いてたきがする) 。

次に、 -DPIC -shared -fPIC の部分。-DPICはよく分からなかった(削除してもとりあえず問題なかった) -shared -fPIC は共用ファイル(〜.so)を作るのにセットで必要なオプションっぽい(-fpicはなくても機能したけど直感的に入れといたほうが良い気がする)

その次は -o (出力ファイル名) (入力ファイル名) 

最後に -lboost_python は-l(ライブラリの検索) とboost_pythonなのでインクルードパス(どこだかしらないけどboostを入れた時にg++のデフォルト探索範囲に設定されてるはず)からboost_pythonを探してくるコマンド。もし無いと


ImportError:〜.so: undefined symbol: _ZN5boost6python6detail11init_moduleEPKcPFvvE

↑python側でこんなエラーが出る(知らずにこんなエラーが出たら泣くね。ライブラリ忘れには注意したいところ)。

〜python側の処理(筆者のオリジナルコード)〜
pythonのインクルードパスにkakudo.so (名前は↑のコマンドで自由に変更できる)のあるフォルダを入れてから以下の高度なpythonプログラムを記述し、実行する。

import kakudo

a=kakudo.greet("hello")

print a







〜出力〜
 Hello, hello

以上、おわり。

来週はベクトルの角度求める関数でも書いて見る予定。これで高速化出来なかったら精神的ダメージを受けそうだわ・・・わりとその可能性もあるし

0 件のコメント:

コメントを投稿