Linux 动态库跨库调用 symbol lookup error原因详解
创始人
2025-01-21 10:03:35
0次

1、起因

今天调试了一个程序,发现symbol lookup error,本想网上找一下方法解决算了怎料找了半天都没写根因的文章,好不容易找到一篇类似的,竟然要收费!

自此打算分析一下,symbol lookup error无非就是链接和库的查找问题。

先说我的应用场景(简化):

主程序(main)调用A(libefg.so)库,A库调用B库(libabc.so),main没有直接调用B库。

运行main程序的时候尽然报symbol lookup error!明明我的libabc.so也在同级目录。

./main: symbol lookup error: ./libefg.so: undefined symbol: _Z9print_abcv

2、分析

2.1 代码结构

编写B库libabc.so,包含test_abc.cpp和test_abc.h

2.1.1 libabc.so

// test_abc.cpp #include "test_abc.h" void print_abc() {         printf("abc\n"); }
// test_abc.h #ifndef __TEST_ABC__ #define __TEST_ABC__ 1 #include  #include  void print_abc(); #endif /* ifndef __TEST_ABC__ */

2.1.2 libefg.so

// test_efg.cpp #include "test_efg.h" void print_def() {         printf("output def\n");         print_abc(); }
// test_efg.h #ifndef __TEST_EFG__ #define __TEST_EFG__ 1 #include "test_abc.h" void print_def(); #endif /* ifndef __TEST_EFG__ */

2.1.3 main

// main.cpp #include "test_efg.h" int main(int argc, char *argv[]) {         printf("main...\n");         print_def();         return 0; }

2.2 代码编译

cat Makefile all:         g++ test_abc.cpp -shared -fPIC -o libabc.so         g++ test_efg.cpp -shared -fPIC -o libefg.so         g++ main.cpp -L. -Wl,-rpath=./ -lefg -o main -labc  .PHONY: clean  clean:         rm -rf libabc.so libefg.so main

编译完成后运行报错

main... output def ./main: symbol lookup error: ./libefg.so: undefined symbol: _Z9print_abcv

纳闷了,明明libabc.so 和libefg.so都在本目录,不可能找得到libefg找不到libabc。

使用ldd查看二进制文件main,看看是不是找不到libabc

ldd ./main         linux-vdso.so.1 (0x00007ffd069b1000)         libefg.so => ./libefg.so (0x00007f0c19bc7000)         libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0c195b7000)         /lib64/ld-linux-x86-64.so.2 (0x00007f0c199a8000)

原来不只是找不到,而是压根没有libabc.so,可以看到libefg.so是可以认到的了,难怪没有abc的符号,再次确认了一下-labc也是已经加入了。

这次尝试去掉-labc看看能否编译通过

g++ main.cpp -L. -Wl,-rpath=./ -lefg -o main

竟然毫无压力的通过了。所以abc的符号在libefg上。

我们再回头看看libefg的编译参数

g++ test_efg.cpp -shared -fPIC -o libefg.so

这也没提醒我们链接libabc啊,因此尝试让libefg加上libabc的依赖

g++ test_efg.cpp -shared -fPIC -o libefg.so -Wl,-rpath=./ -L. -labc

再次整编译,运行正常!

2.3 CMake

以下写法是可以生成库和执行文件,但是运行还是出错。

cmake_minimum_required(VERSION 2.8)  set(name cmain) project(name)  link_directories(${CMAKE_CURRENT_SOURCE_DIR})  ## add libabc add_library(abc SHARED test_abc.cpp)  ## add libefg add_library(efg SHARED test_efg.cpp)  ## add main add_executable(${name} main.cpp) target_link_libraries(${name} efg abc)  

改为以下的写法,libefg增加libabc的支持后正常

cmake_minimum_required(VERSION 2.8)  set(name cmain) project(name)  link_directories(${CMAKE_CURRENT_SOURCE_DIR})  ## add libabc add_library(abc SHARED test_abc.cpp)  ## add libefg add_library(efg SHARED test_efg.cpp) target_link_libraries(efg abc)  ## add main add_executable(${name} main.cpp) target_link_libraries(${name} efg abc)  

3. 结论

通过上述可以看到,中间的so(libefg)被main引用,main并不直接引用libabc的,所以中间编译的so也要加入相应的依赖,即使它能正常编译通过,实际是它找不到libabc的符号。

相关内容

热门资讯

实测交流透视挂!宝玛大厅ai智... 实测交流透视挂!宝玛大厅ai智能透视挂教程,宝玛大厅破解软件经验(本来有挂辅助)1、每一步都需要思考...
总算了解辅助器!朱雀吴江三缺一... 总算了解辅助器!朱雀吴江三缺一ai智能透视辅助挂技巧,朱雀吴江三缺一好像是有挂(有辅助挂细节)朱雀吴...
今日公布透视!九五至尊大厅ai... 今日公布透视!九五至尊大厅ai智能透视插件,九五至尊大厅有没有透视挂窍门(切实有挂技术)1、在九五至...
玩家必看科普开挂!聚闲麻将ai... 玩家必看科普开挂!聚闲麻将ai智能透视辅助挂软件,聚闲麻将总是真的有挂(有辅助挂方式)聚闲麻将能透视...
据报道开挂!旅游娱乐ai智能开... 据报道开挂!旅游娱乐ai智能开挂工具,旅游娱乐辅助工具演示(一直有挂教学)1、全新机制【旅游娱乐ai...
一分钟揭秘开挂!决胜朋来麻将a... 一分钟揭秘开挂!决胜朋来麻将ai智能透视辅助挂教程,决胜朋来麻将真是真的是有挂(有辅助挂总结)1、首...
如何分辨真伪透视!红牛ai智能... 如何分辨真伪透视!红牛ai智能透视攻略,红牛是不是有挂经验(真是有挂技术)1、操作简单,无需红牛手机...
2分钟细说辅助器!江湖大庆麻将... 2分钟细说辅助器!江湖大庆麻将ai智能透视辅助挂攻略,江湖大庆麻将竟然是真的有挂(有辅助挂头条)1、...
总算清楚透视挂!老夫子厅ai智... 总算清楚透视挂!老夫子厅ai智能透视挂技巧,老夫子厅怎么开挂课程(好像发现有挂)老夫子厅破解侠是真的...
解密关于辅助!菜鸟麻将ai智能... 解密关于辅助!菜鸟麻将ai智能透视辅助挂脚本,菜鸟麻将总是存在有挂(有辅助挂存在)1、用户打开应用后...