2014年5月13日火曜日

とりあえずBoost.Pythonを使う(1)

Boost.PythonをつかってC++のクラスをPythonへ渡す方法。
この例では、

  1. メンバ変数
  2. メソッド
  3. コンストラクタ
  4. オペレータ
  5. Pythonリストの受け渡し

が分かる仕組みになっている。
例えば3次元ベクトルクラスVector3dをC++で書いたとする。Pythonで扱うとしたら以下のようにしたい。

 v1 = vector3d(1,2,3)   #constructor
 v2 = vector3d([1,2,3]) #constructor with list
 v1.x                   #member
 v1.norm()              #method
 v1+v2                  #operator


ラッパーは以下のように作ってみた。
Pythonのlistとやり取りするクラスが始めから備わっているようだ。
extract<>についてはhttps://wiki.python.org/moin/boost.python/extract


#include <math.h>
#include <boost/python.hpp>

class Vector3d {
public:
    double x;
    double y;
    double z;

    //constructor
    inline Vector3d(double x, double y, double z):
            x(x), y(y), z(z) {}

    //constructor with python linst
    inline Vector3d(boost::python::list pl)
    {
        x = boost::python::extract<double>(pl[0]);
        y = boost::python::extract<double>(pl[1]);
        z = boost::python::extract<double>(pl[2]);

    }
    
    inline Vector3d operator+(const Vector3d &v) const
    {
        return Vector3d(x+v.x, y+v.y, z+v.z);
    }

    inline Vector3d& operator+=(const Vector3d &v)
    {
        x += v.x;
        y += v.y;
        z += v.z;
        return *this;
    }

    //return l2 norm
    inline double norm() const
    {
        return sqrt(x*x + y*y + z*z);
    }

    //to python list
    inline boost::python::list toList() const
    {
        boost::python::list pl;
        pl.append(x);
        pl.append(y);
        pl.append(z);
        return pl;
    }

};



BOOST_PYTHON_MODULE(hoge)
{
 class_<Vector3d>("vector3d", init<double, double, double>())
  .def(init<boost::python::list>())
  .def_readwrite("x", &Vector3d::x) //member variables
  .def_readwrite("y", &Vector3d::y)
  .def_readwrite("z", &Vector3d::z)
  .def(self + self)    //operator
  .def(self += self)
  .def("norm",     &Vector3d::norm) //method
  .def("tolist", &Vector3d::toList) //to python list
  ;
}






0 件のコメント:

コメントを投稿