您的位置:首页 > 编程语言 > Python开发

Boost.python学习笔记(2)

2015-01-25 16:57 337 查看
折腾了一会,先看怎么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)可以很轻松做到,不过还是继续学习。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  boost