Linux动态库中未定义符号的原因定位及解决方法解决的方法是写这篇论文的目的。可能原因没有找到依赖库这个是最常见的原因,通常是没有指定搜索目录,或者系统搜索目录下没有安装的依赖库不一致。编译的时候用的是高版本,然后在不同的机器上使用时链接的不一样。是低版本,低版本可能会缺少一些api符号如果动态库在编译时默认隐藏,外部代码使用隐藏符号。c++abi版本不一致最典型的例子就是gcc4.x和gcc5.x版本之间的问题。4.x中编辑的动态库不能在5.x中链接使用。解决方法1、没有找到依赖库使用ldd-r判断系统库中是否存在依赖库执行ldconfig命令更新ld缓存执行ldconfig-p|grep{SO_NAME}查看是否对应检查LD_LIBRATY_PATH是否设置了有效路径2.链接库版本不一致如果之前系统安装过同一个库,或者有多个库,需要判断是哪个库已连接。有一个特殊的场景需要注意。,.so文件中有一个默认的rpath路径,用于查找依赖库。此路径优先于系统目录和LD_LIBRARY_PATH。如果rpath中有同名的.so文件,则优先加载该路径下的文件。遇到未定义符号问题时,使用readelf-d|greprpath查看:$readelf-dlibSXVideoEngineJni.so|greprpath0x000000000000000f(RPATH)库rpath:[/home/slayer/workspace/SXVideoEngine-Core/Render/cmake-build-debug:/home/slayer/workspace/SXVideoEngine-Core/Render/../../SXVideoEngine-Core-Lib/blend2d/linux/lib]如果已有路径下有对应的库,可以先重命名该文件再次测试确认。关于连接时的顺序可以查看文档:http://man7.org/linux/man-pag...如果共享对象依赖不包含斜线,则按以下顺序搜索:o使用目录如果存在且DT_RUNPATH属性不存在,则在二进制文件的DT_RPATH动态部分属性中指定。不推荐使用DT_RPATH。o使用环境变量LD_LIBRARY_PATH,除非可执行文件正在安全执行模式下运行(见下文),在这种情况下该变量将被忽略。o使用二进制文件的DT_RUNPATH动态部分属性中指定的目录(如果存在)。搜索此类目录只是为了找到DT_NEEDED(直接依赖项)条目所需的那些对象,而不适用于这些对象的子对象,这些对象本身必须具有自己的DT_RUNPATH条目。这与DT_RPATH不同,DT_RPATH用于搜索依赖项t中的所有子项稀土。o来自缓存文件/etc/ld.so.cache,其中包含以前在扩充库路径中找到的候选共享对象的编译列表。但是,如果二进制文件与-znodeflib链接器选项链接,则会跳过默认路径中的共享对象。安装在硬件功能目录(见下文)中的共享对象优于其他共享对象。o在默认路径/lib中,然后是/usr/lib。(在某些64位架构上,64位共享对象的默认路径是/lib64,然后是/usr/lib64。)如果二进制文件是使用-znodeflib链接器选项链接的,则跳过此步骤。Symbols是隐藏的第三方编译库,在相应的头文件中引入,使用其中一种方法,链接时出现undefinedsymbol。在这种情况下,库的开发人员可能不会导出此方法的符号。#使用nm命令查看导出的函数符号,这里查看License相关的函数$nm-gDClibSXVideoEngineJni.so|grep-ilicense0000000000008110T__ZN13SXVideoEngine6Public7License10SetLicenseEPKc0000000000008130T__ZN13SXVideoEngine6Public7License13LicenseStatusEv0000000000008190T__ZN13SXVideoEngine6Public7License19IsVideoCutSupportedEv0000000000008170T__ZN13SXVideoEngine6Public7License26IsDynamicTemplateSupportedEv0000000000008150T__ZN13SXVideoEngine6Public7License26IsStadardTemplateSupportedEv#nm返回的并不是原始函数名,通过c++filtGettheoriginalname$c++filt__ZN13SXVideoEngine6Public7License10SetLicenseEPKcSXVideoEngine::Public::License::SetLicense(charconst*)c++Abiversionisinconsistent.GccaddsnewfeaturestoC++stepbystep.Ifnewfeaturesareimplemented,Itispossibletomodifytheabiofc++andupgradetheversionofglibc.ThemostcommonerrorsinAbilinkingarecausedbydifferentimplementationsofstd::stringandstd::listingcc4.xandgcc5.x.Ingcc4.x,gcc'simplementationofthestandardstringisplacedunderthestdnamespace,whichisexpandedtostd::basic_stringwhencompiling.Butsincegcc5.x,theimplementationofstringisplacedinthestd::__cxx11space,whichisexpandedtostd::__cxx11::basic_stringaftercompilation.这将生成一个使用gcc4.x编译的动态库。如果某些函数使用字符串作为参数或返回值,则导出的函数参数将是std::basic_string类型。无法在gcc5.x下编译和连接。报错类似:undefinedsymbol:"std::__cxx11***"在这种情况下,妥协是在使用gcc5.x或更高版本编译时添加-D_GLIBCXX_USE_CXX11_ABI=0以禁用c++11abi。当然,最好的办法是保证各大版本的编译器基本一致。如果新开发的程序使用了C++的新特性,升级gcc版本和glibc是非常有必要的。实用命令总结ldd命令用于查找动态库所依赖的库是否存在。#ldd-r#找不到的库会出现notfound$ldd-rlibSXVideoEngine.solinux-vdso.so.1=>(0x00007ffc337d2000)libz.so.1=>/lib64/libz.so.1(0x00007f061cf41000)libX11.so.6=>/lib64/libX11.so.6(0x00007f061cc03000)libEGL.so.1=>/lib64/libEGL.so.1(0x00007f061c9ef000)libGLESv2.so.2=>/lib64/libGLESv2.so.2(0x00007f061c7dd000)libpthread.so.0=>/lib64/libpthread.so.0(0x00007f061c5c1000)libblend2d所以=>/home/seeshion/workspace/SXVideoEngine-Core/Render/../../SXVideoEngine-Core-Lib/blend2d/linux/lib/libblend2d.so(0x00007f061c187000)libfreeimage.so.3=>/lib/libfreeimage.so.3(0x00007f061b8ac000)libavcodec.so.58=>/lib/libavcodec.so.58(0x00007f06198b6000)libavformat.so.58=>/lib/libavformat.so.58(0x00007f06193e1000)libavutil.so.5>/lib/libavutil.so.56(0x00007f06190bd000)...nm命令读取库的导出符号$nm-gDClibSXVideoEngineJni.so|grep-ilicense0000000000008110T__ZN13SXVideoEngine6Public7License10SetLicenseEPKc0000000000008130T__ZN13SXVideoEngine6Public7License13LicenseStatusEv0000000000008190T__ZN13SXVideoEngine6Public7License19IsVideoCutSupportedEv0000000000008170T__ZN13SXVideoEngine6Public7License26IsDynamicTemplateSupportedEv0000000000008150T__ZN13SXVideoEngine6Public7License26IsStadardTemplateSupportedEvreadelf用于读取elf文件的相关信息$readelf-dlibSXVideoEngineJni.so|greprpath0x000000000000000f(RPATH)库rpath:[/home/slayer/workspace/SXVideoEngine-Core/Render/cmake-build-debug:/home/slayer/workspace/SXVideoEngine-Core/Render/../../SXVideoEngine-Core-Lib/blend2d/linux/lib]c++filt获取符号原名$c++filt__ZN13SXVideoEngine6Public7License10SetLicenseEPKcSXVideoEngine::Public::License::SetLicense(charconst*)