如何使用pybind11在两个不同子模块中导出同一类型?
报错原因
pybind11 对每个唯一的C类型全局仅允许做一次py::class_绑定注册,重复注册同一类型就会触发type is already registered错误。
示例代码中NS2::S1是通过using声明引入的NS1::S1别名,二者在C层面是完全相同的类型,两次调用py::class_注册同一个类型必然触发报错。
正确实现方案
只需要在第一个子模块完成一次S1类型的注册,拿到绑定生成的Python类型对象后,直接将该对象赋值给第二个子模块的同名属性即可,不需要重复执行类型绑定逻辑。这种写法下两个子模块导出的S1是完全同一个Python类型,完全匹配需求。
正确绑定代码:
PYBIND11_MODULE(my_module, m) { py::module_ m1 = m.def_submodule("NS1", ""); py::module_ m2 = m.def_submodule("NS2", ""); // 仅在NS1子模块注册一次S1类型 auto s1_cls = py::class_<NS1::S1>(m1, "S1"); // 将同一个类型对象挂载到NS2子模块的S1属性 m2.attr("S1") = s1_cls; py::class_<NS2::S2>(m2, "S2"); }
Python侧行为验证
编译完成后Python侧调用效果完全符合预期:
import my_module # 两个子模块的S1为完全相同的类型 assert my_module.NS1.S1 is my_module.NS2.S1 # 类型判断、实例化逻辑正常 obj = my_module.NS1.S1() assert isinstance(obj, my_module.NS2.S1)
内容的提问来源于stack exchange,提问作者Nicola Gigante
相关产品推荐
相关产品推荐

