2014年5月25日日曜日

とりあえずBoost.Pythonを使う(4) pythonのリストと関数のオーバーライド

前にも書いた気がするけど、Boost PythonでC++のベクトルを返すときにvector_index_suiteを使えば受け渡しが簡単だ。だけど、Pythonのリストとして渡したり、返したりしたほうがPython側からすればシームレスに扱えてよい。そんな時はboost::python::listを使う。
例えば
void Hoge::setX(std::vector<double> &x) {
    _x = x;
}

というC++のメソッドがあった場合Pythonでは
>>> hoge.setX([1,2,3])
としたい。

そんなときはboost::python::listを引数にして、boost::python::extrac<>で値を抽出すればよい。
void Hoge::setX(boost::python::list &x) {
    std::vector<double> tmp;
    int len = boost::python::len(x);
    for(int i=0; i<len; i++) {
        tmp.push_back(boost::python::extract<double>(x[i]));
    }
    _x = tmp;
}

こうやってしまうと元の関数を書きなおしてしまうでのC++を使う場合には使いにくい。
同じ名前のメソッドを作ってその内1つをPythonのWrapperに登録する。
static void hoge_set_x(Hoge &h, boost::python::list &x){hoge.setX(x);}

boost::python::class_<Hoge>("Hoge")
               .def("setX", &hoge_set_x)
               ;

ただ、このやり方だと、Wrapperを2つも各のでちょっと周りくどい。しかもlistとvectorをいちいちコピーしないといけない。index_suiteを使った良いやり方がありそうな気がするけど、std::vector<std::vector<> >でエラーがでたので、今回は諦めて上のようにしてみた。

containerのラッパーを書いている以下のようなサイトも見つかった。
https://wiki.python.org/moin/boost.python/StlContainers
大変なので今後の参考としておこう。





0 件のコメント:

コメントを投稿