Boost Python指针转Python对象报错:缺少MT类型按值转换器
核心原因是:你访问F3MT.underlying时,Boost Python当前尝试将MT值类型转换为Python对象,但你只注册了MT指针类型的转换器,二者不匹配。
为什么会触发值类型转换?
如果你的F3MT类中underlying是MT类型的成员变量(而非MT*或MT&),或者你在Boost Python封装时直接用def_readonly暴露这个值类型成员,Boost Python会默认尝试把整个MT对象按值拷贝到Python侧,这时候就需要MT值类型的转Python转换器,你注册的指针转换器根本不会被触发。
解决办法分两种场景:
场景1:你想暴露MT的指针/引用(而非拷贝值)
修改Boost Python的封装代码,把underlying声明为返回引用或指针的属性,同时指定内存管理策略:
#include <boost/python.hpp> using namespace boost::python; // 假设F3MT的underlying是MT&或MT类型(你想返回引用) class_<F3MT>("F3MT") .add_property("underlying", make_getter(&F3MT::underlying, return_value_policy<reference_existing_object>()) );
reference_existing_object策略告诉Boost Python:这个引用/指针指向的对象由C++侧管理,Python只拿引用,不负责销毁,同时会用你已注册的MT指针/引用转换器。
如果underlying本身就是MT*类型,直接用def_readonly即可,但要确保你已经注册了MT*的转换器(比如用class_<MT>("MT").def(...)同时注册指针转换器):
class_<MT>("MT"); // 自动注册MT和MT*的转换器 class_<F3MT>("F3MT") .def_readonly("underlying", &F3MT::underlying); // underlying是MT*类型
场景2:你确实需要按值传递MT到Python
直接把MT类也封装成Python类,Boost Python会自动生成值类型的转换器:
// 先封装MT类 class_<MT>("MT") .def(init<...>()) // 根据你的MT构造函数添加 .def("some_method", &MT::some_method); // 暴露MT的方法 // 再封装F3MT class_<F3MT>("F3MT") .def_readonly("underlying", &F3MT::underlying); // 此时underlying是MT值类型,会自动转换
关键总结
Boost Python的转换器是按类型匹配的:指针转换器只处理MT*类型,值转换器处理MT类型。访问成员时触发的转换类型,完全取决于你封装时声明的成员类型和方式,和你注册了哪种转换器无关——你得让触发的转换类型和已注册的转换器对应上。
内容的提问来源于stack exchange,提问作者MMM

