pybind11 wrapper链接自定义so文件后无法调用库内API问题
问题解答
疑问1:是否必须将项目全部源码与wrapper.cpp共同编译,而不能直接链接预编译好的so文件?
不需要,完全支持直接链接预编译动态库。
从给出的ldd输出可以确认,pywrapper.cpython-37m-aarch64-linux-gnu.so已正确关联libcore.so,动态链接环节配置无误,触发的属性不存在报错和链接预编译so的操作无关。
疑问2:如果支持直接链接预编译so文件,是否仍需要在wrapper模块中通过m.def()注册所有需要在Python侧调用的API?
必须注册。
pybind11的核心作用是生成C/C++与Python之间的桥接代码,完成两侧符号映射、类型转换、参数校验工作:
- 通过
target_link_libraries链接预编译so,仅能保证wrapper二进制运行时可以找到op_init这类库函数的内存地址,不会触发链接器错误 - Python解释器加载扩展模块时,只能识别通过pybind11接口显式注册到模块对象上的属性,未注册的C/C++原生函数不会自动暴露到Python侧,自然会触发
AttributeError。哪怕将所有核心源码和wrapper.cpp共同编译,不做m.def()注册一样无法从Python侧调用对应API。
现有代码修正参考
- 现有代码未绑定
option枚举,且inputs类绑定中flag字段的绑定代码存在语法错误(<>为无效占位),需先补充枚举绑定:
py::enum_<option>(m, "option") .value("E_FLAG_ON", E_FLAG_ON) .value("E_FLAG_OFF", E_FLAG_OFF) .export_values();
- 补充
op_init接口的注册逻辑,由于接口参数为const inputs*,可通过lambda做一层简单适配:
m.def("op_init", [](const inputs& input_obj) { return op_init(&input_obj); }, py::arg("input_obj"));
inputs结构体中的float* a和char* file_path为裸指针类型,直接通过def_readwrite暴露会存在内存安全、类型不匹配问题:char*建议绑定阶段做std::string和Pythonstr的自动转换,避免Python侧传入的字符串被GC后出现悬垂指针float*为数组指针,需要明确数组长度,建议封装辅助逻辑完成Python列表/numpy数组到C++浮点数数组的安全转换,不要直接暴露裸指针。
内容的提问来源于stack exchange,提问作者soundarrajan v
相关产品推荐
相关产品推荐

