pybind11中std::map绑定跨模块类型不匹配问题求助
问题原因
- 两个模块(
dt和vp)对同一C++类型std::map<platform::String, platform::String>的绑定未共享类型信息:dt模块通过pybind11/stl_bind.h的bind_map创建了模块局部的自定义类型dt.ssmap,并通过PYBIND11_MAKE_OPAQUE标记为不透明类型。vp模块未导入该不透明绑定信息,pybind11默认将std::map<platform::String, platform::String>解析为Python标准Dict类型,导致dt.ssmap与vp.reset期望的类型不匹配。
- 默认情况下
bind_map创建的是模块局部类型,跨模块无法识别为同一类型。
解决方法
步骤1:共享不透明类型声明
将PYBIND11_MAKE_OPAQUE移到公共头文件(如ssmap.h),让dt和vp模块都能共享该声明:
// ssmap.h #include <pybind11/pybind11.h> #include <map> #include "platform/String.h" PYBIND11_MAKE_OPAQUE(std::map<platform::String, platform::String>)
步骤2:将dt模块的ssmap设为全局可见
修改dt.cpp中的bind_ssmap函数,添加py::module_local(false)参数,让自定义map类型全局可见:
void bind_ssmap(py::module &m) { py::bind_map<std::map<platform::String, platform::String>>(m, "ssmap", py::module_local(false)); }
步骤3:修复vp模块的类型关联
在vp.cpp中确保包含pybind11/stl_bind.h和公共头文件,无需重复绑定(pybind11会自动关联全局的ssmap类型):
// vp.cpp #include <pybind11/stl_bind.h> #include "./ssmap.h" #include "./vp.h" void bind_vp(py::module &m) { py::class_<vp> pyClass(m, "vp", py::module_local()); pyClass.def("reset", &vp::reset, py::arg("val")); }
可选替代方案(如果无法全局共享类型)
若必须保持模块局部类型,可在vp模块绑定reset方法时,显式指定参数类型为dt.ssmap对应的C++类型:
void bind_vp(py::module &m) { py::module dt_module = py::module::import("dt"); py::object ssmap_type = dt_module.attr("ssmap"); py::class_<vp> pyClass(m, "vp", py::module_local()); pyClass.def("reset", &vp::reset, py::arg("val").cast<std::map<platform::String, platform::String>>() ); }
内容的提问来源于stack exchange,提问作者user17582260
相关产品推荐
相关产品推荐

