Boost.python学习笔记(2)

折腾了一会,先看怎么wrap吧。。。
#include <boost/python.hpp>

using namespace boost::python;

class World
{
public:
  void set(std::string msg)
  {
    this->msg=msg;
  };
  std::string get()
  {
    return this->msg;
  };
private:
  std::string msg;
};

class CppClass {
public:
  int getNum() {
    return 7;
  }
};
int main( int argc, char ** argv ) {
  try {
    Py_Initialize();

    object main_module((
      handle<>(borrowed(PyImport_AddModule("__main__")))));

    object main_namespace = main_module.attr("__dict__");
    main_namespace["World"]=class_<World>("World")
      .def("get", &World::get)
      .def("set", &World::set);
    main_namespace["CppClass"] = class_<CppClass>("CppClass")
      .def("getNum",&CppClass::getNum);
    handle<> ignored(( PyRun_String(
				    "cpp = CppClass()\n"
				    "print cpp.getNum()\n"
				    "test = World()\n"
				    "test.set('hello world')\n"
				    "print test.get()\n",
                                     Py_file_input,
                                     main_namespace.ptr(),
                                     main_namespace.ptr() ) ));
  } catch( error_already_set ) {
    PyErr_Print();
  }
}


解释一下:

定义了两个C++的类,然后在main里面注册一个main的module,把C++类加入main的name space,这样在 python interpreter里面就可以创建和调用C++类和他们的方法了。


这样做其实对于embed来说,不是很实用。 首先你不知道什么时候拥护会导入哪个module,其次,这种动态注入space在类多了之后会很麻烦。


然后就要做下改进


#include <boost/python.hpp>

using namespace boost::python;

class World
{
public:
  World(const std::string& msg="")
  {
    this->msg=msg;
  }
  void set(std::string msg)
  {
    this->msg=msg;
  };
  std::string get()
  {
    return this->msg;
  };
private:
  std::string msg;
};


class CppClass {
public:
  int getNum() {
    return 7;
  }
};

BOOST_PYTHON_MODULE(hello)
{
  class_<World>("World",init<std::string>())
    .def("get", &World::get)
    .def("set", &World::set);
  class_<CppClass>("CppClass")
    .def("getNum",&CppClass::getNum);
};


int main( int argc, char ** argv ) {
  try {
    PyImport_AppendInittab( "hello", &inithello );
    Py_Initialize();
    World test2("hello world2");
    std::cout<<test2.get()<<std::endl;
    object main_module((
      handle<>(borrowed(PyImport_AddModule("__main__")))));

    object main_namespace = main_module.attr("__dict__");
    object hello_module( (handle<>(PyImport_ImportModule("hello"))) );
    main_namespace["hello"] = hello_module;
    scope(hello_module).attr("test2") = ptr(&test2);
    handle<> ignored(( PyRun_String(
				    "cpp = hello.CppClass()\n"
				    "print cpp.getNum()\n"
				    "test = hello.World('')\n"
				    "test.set('hello world')\n"
				    "print test.get()\n"
				    "hello.test2.set('hello world3')\n",
                                     Py_file_input,
                                     main_namespace.ptr(),
                                     main_namespace.ptr() ) ));
     std::cout<<test2.get()<<std::endl;
  } catch( error_already_set ) {
    PyErr_Print();
  }
}


这个例子让我弄得有些nested,因为要测试很多乱七八糟的玩意。不过可以简单说下。这里面做了三个测试:

1. 用boost宏静态包装类

2. 导入module可以用两种方法, 在脚本种导入 (import hello), 或者静态导入

3. python 与C++共享object, 这里面的test2是在main里面创建的,然后在python里面进行set. 通过boost::python::ptr来存入python,并阻止python做copy.


做到3的要求其实挺麻烦,组里大牛说pythonQT,(不是pyqt)可以很轻松做到,不过还是继续学习。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值