帮助文档
专业提供香港服务器、香港云服务器、香港高防服务器租用、香港云主机、台湾服务器、美国服务器、美国云服务器vps租用、韩国高防服务器租用、新加坡服务器、日本服务器租用 一站式全球网络解决方案提供商!专业运营维护IDC数据中心,提供高质量的服务器托管,服务器机房租用,服务器机柜租用,IDC机房机柜租用等服务,稳定、安全、高性能的云端计算服务,实时满足您的多样性业务需求。 香港大带宽稳定可靠,高级工程师提供基于服务器硬件、操作系统、网络、应用环境、安全的免费技术支持。
服务器资讯 / 香港服务器租用 / 香港VPS租用 / 香港云服务器 / 美国服务器租用 / 台湾服务器租用 / 日本服务器租用 / 官方公告 / 帮助文档
Linux 动态库跨库调用 symbol lookup error原因详解
发布时间:2024-03-11 01:06:49   分类:帮助文档
Linux 动态库跨库调用 symbol lookup error原因详解 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的符号。
香港云服务器租用推荐
服务器租用资讯
·广东云服务有限公司怎么样
·广东云服务器怎么样
·广东锐讯网络有限公司怎么样
·广东佛山的蜗牛怎么那么大
·广东单位电话主机号怎么填写
·管家婆 花生壳怎么用
·官网域名过期要怎么办
·官网邮箱一般怎么命名
·官网网站被篡改怎么办
服务器租用推荐
·美国服务器租用
·台湾服务器租用
·香港云服务器租用
·香港裸金属服务器
·香港高防服务器租用
·香港服务器租用特价