dlopen加载libtest_main.so遇未定义符号_Z6launchv问题求助
问题解答
核心结论
前缀_Z6和后缀v本身不是问题根源,但它们反映的C++名字修饰与C风格符号的不匹配才是导致dlopen报错的核心原因。
符号修饰含义解析
_Z6launchv是GCC/Clang等编译器对C++函数进行**名字修饰(Name Mangling)**后的结果,各部分具体含义:
_Z:C++符号修饰的起始标记,用来区分C风格的未修饰符号6:表示后续紧跟的函数名长度,这里launch恰好是6个字符v:表示函数的参数类型为void(即无参函数)
问题原因分析
libtest_main.so中调用launch()时,编译器将其当作C++函数处理,生成了修饰后的符号_Z6launchv(nm输出的U表示该符号未定义,需要外部依赖)- 但
libhost.so中导出的launch是C风格的未修饰符号(nm输出的T表示该符号已定义在代码段) - 动态链接器无法将修饰后的C++符号与未修饰的C符号匹配,因此抛出
undefined symbol错误
解决方法
方案1:在调用端强制使用C风格符号声明
在libtest_main.so的代码中,用extern "C"包裹launch()的声明,让编译器生成C风格的符号引用:
extern "C" { void launch(); }
重新编译链接libtest_main.so后,nm会显示未定义符号为U launch,与libhost.so中的符号完全匹配,dlopen即可成功加载。
方案2:修改依赖库的符号导出(若有权限)
如果libhost.so是你维护的代码,也可以在其函数声明中添加extern "C",确保导出C风格符号(不过当前libhost.so已经是T launch,此方案非必须):
// libhost.so的代码中 extern "C" void launch() { // 函数实现 }
内容的提问来源于stack exchange,提问作者hyperion007
相关产品推荐
相关产品推荐

