如何通过Boost Python从C++修改Python中类成员变量的值?
问题描述
我有一个通过Boost Python框架暴露给Python的C++类,代码如下:
struct Var { Var(std::string name) : name(name), value() {} std::string const name; float value; }; BOOST_PYTHON_MODULE(hello) { class_<Var>("Var", init<std::string>()) .def_readonly("name", &Var::name) .def_readwrite("value", &Var::value); }
对应的Python使用脚本为:
x = hello.Var("hello") def print_func(): print(x.value)
请问是否可以在C++代码中访问Python中的对象x,为其value成员变量赋值,使得执行Python的print_func()时能打印该值?
解决方案
当然可以做到!Boost Python结合Python的C API,完全能让C++访问并修改Python运行时里的对象。下面是具体的实现步骤:
1. 在C++中编写修改对象的函数
我们可以先写一个C++函数,通过Boost Python获取Python全局命名空间里的x对象,然后直接修改它的value成员:
#include <boost/python.hpp> using namespace boost::python; // 这个函数会修改Python全局变量x的value值 void set_var_value() { // 获取Python的__main__模块,它包含了全局命名空间 object main_module = import("__main__"); object main_namespace = main_module.attr("__dict__"); // 从全局命名空间中取出x对象,并转换为C++的Var引用 Var& x = extract<Var&>(main_namespace["x"]); // 直接修改value成员,Python端会同步看到这个变化 x.value = 3.14f; }
2. 将函数暴露给Python
修改原来的BOOST_PYTHON_MODULE块,把刚才写的set_var_value函数暴露给Python:
BOOST_PYTHON_MODULE(hello) { class_<Var>("Var", init<std::string>()) .def_readonly("name", &Var::name) .def_readwrite("value", &Var::value); // 把C++函数暴露成Python可调用的函数 def("set_var_value", &set_var_value); }
3. 在Python脚本中调用并验证
更新Python脚本,调用C++暴露的函数后再执行print_func,就能看到修改后的值了:
x = hello.Var("hello") def print_func(): print(x.value) # 调用C++函数修改x的value hello.set_var_value() # 执行打印,会输出3.14 print_func()
注意事项
- 要确保
x对象存在于Python的全局命名空间中,否则C++提取对象时会抛出异常,你可以添加try-catch块来处理这种情况。 - 使用
extract<Var&>时要保证类型匹配,如果提取的不是Var对象,也会触发异常。 - 因为
value是通过def_readwrite暴露的,C++和Python操作的是同一块内存,所以修改会立刻同步,不需要额外的同步操作。
内容的提问来源于stack exchange,提问作者sbunny
相关产品推荐
相关产品推荐

