Boost.python使ってみた

ここのところwxWidgetsを使ってc++でごりごり書いていたのだが、やっぱりGUIc++で書くのはめんどくさすぎるのでスクリプトを導入することにした。
速度が必要なところだけc++でモジュールを書く方向。去年の年末微妙に話題になっていたBoost.pythonでやってみることにした。

シンプルなサンプルソースが無いのでポイントだけめも。

多重継承とshared_ptrを混ぜて使う

class ICamera
{
public:
  virtual void apply()=0;
};

class IMouseCallback
{
public:
  virtual void leftDown(int x, int y)=0;
  virtual void leftUp(int x, int y)=0;
};

class TargetCamera : public ICamera, public IMouseCallback
{
  void apply();
  void leftDown(int x, int y);
  void leftUp(int x, int y);

 static boost::shared_ptr<TargetCamera> create();
};

class Driver
{
void setCamera(boost::shared_ptr<ICamera> camera);
void setMouseCallback(boost::shared_ptr<IMouseCallback> mouose);
};

OpenGLのオレオレエンジンの断片であります。


これをboost.pythonでモジュール化する。
Driverの登録。これは特に変わったところなし。

  using namespace boost::python;

  class_<Driver>("Driver")
    .def("setCamera", &Driver::setCamera)
    .def("setMouseCallback", &Driver::setMouseCallback)
    ;

多重継承したクラスの登録

  // shared_ptr用
  register_ptr_to_python<boost::shared_ptr<Camera> >();
  class_<TargetCamera, 
      // basesにスーパークラスを列挙する
      bases<ICamera, IMouseCallback>,
      // shared_ptr用
      boost::noncopyable >(
        "TargetCamera", 
        // shared_ptr用
        no_init)
       // shared_ptr用。生成関数
      .def("create", &Camera::create).staticmethod("create")
    ;

このままだとsetCamera, setMouseCallbackしたときにICamera, IMouseCallbackに変換できないので、変換用にスーパークラスをそれぞれ登録する(抽象クラスでも)。

  register_ptr_to_python<boost::shared_ptr<ICamera> >(); 
  class_<ICamera, boost::noncopyable>("ICamera", no_init)
      ;

  register_ptr_to_python<boost::shared_ptr<IMouseCallback> >(); 
  class_<IMouseCallback, boost::noncopyable>("IMouseCallback", no_init)
      ;

以上で多重継承していても問題なく動いた。
Boost.python地味にいい。