Linux 动态库跨库调用 symbol lookup error原因详解

这篇具有很好参考价值的文章主要介绍了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 <stdlib.h>
#include <stdio.h>
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的符号。文章来源地址https://www.toymoban.com/news/detail-686363.html

到了这里,关于Linux 动态库跨库调用 symbol lookup error原因详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • flutter release 报错 Error: SocketException: Failed host lookup:

    flutter release 报错 Error: SocketException: Failed host lookup:

    flutter 的 debug 模式没有任何问题 ,打了release 包后一直报下面的错,查了一下是 因为没有网络权限 Error: SocketException: Failed host lookup: \\\'yomi-test-aws-sg.yomigame.games\\\' (OS Error: No address associated with hostname, errno = 7) 按照下面的来解决 Flutter 网络请求报错 Failed host lookup: 一、如果是iOS真机

    2024年04月27日
    浏览(8)
  • netcore工程在linux下调用linux动态库

    netcore工程在linux下调用linux动态库

    文章的内容可能看着枯燥,排版也存在一些问题,但是如果你遇到相关问题,真的无法解决的时候,不妨沉下心来好好阅读一下这篇文章,你会有所收获,也可以先跳到文章最后,看看是不是对你的问题有价值。。 使用P/invoke方式 如果出现调用失败的情况,可能是so文件缺少

    2023年04月26日
    浏览(7)
  • 【问题解决】 Extrapolation Error: Lookup would require extrapolation -0.044000000s into the future

    【问题解决】 Extrapolation Error: Lookup would require extrapolation -0.044000000s into the future

    有时候当配置完move_base各个文件,准备开启move_base节点愉快的进行导航时,打开Rviz,使用2D Nav Goal工具发布了一个目标点,会出现全局规划路径,但机器人不动,开启move_base节点的终端出现以下错误: [ERROR] [1669281693.716503087, 871.669000000]: Extrapolation Error: Lookup would require extra

    2024年02月02日
    浏览(8)
  • MASM32连接程序时error A2006: undefined symbol : u

    MASM32连接程序时error A2006: undefined symbol : u

    为了检测Windows操作系统是32位还是64位的,用MASM32编写了一个调用Windows API函数GetNativeSystemInfo的程序(完整代码附后),GetNativeSystemInfo函数会将指向SYSTEM_INFO结构体的地址存到GetNativeSystemInfo传递的参数中。 微软官网中的STEM_INFO定义为: SYSTEM_INFO中的wProcessorArchitecture存储了已

    2024年02月07日
    浏览(5)
  • Android Studio里的C/C++返回: ld: error: undefined symbol

    Android Studio里的C/C++进行编译时返回: ld: error: undefined symbol 的错误,进行了解决。 编译环境突然出现了这个问题,尝试解决,终于找到一个解决办法:卸载 ndkVersion = \\\"23.1.7779620\\\" ,再进行重新安装 。 I removed both NDK versions from Android Studio - Tools - SDK Manager - SDK Tools, reinstalled them

    2024年02月03日
    浏览(7)
  • Linux 下编译实现C/Fortran调用动态库

    Linux 下编译实现C/Fortran调用动态库

    目录 Fortran语言 格式 Windows Linux下动态库介绍 windows下obj, lib, dll, exe的关系 linux .o, .a, .so 生成动态库Demo 查看动态库中的函数 FORTRAN语言是Formula Translation的缩写,意为“公式翻译”。它是为科学、工程问题或企事业管理中的那些能够用数学公式表达的问题而设计的,其数值计算

    2024年02月04日
    浏览(6)
  • Flutter 网络请求报错 Failed host lookup: ‘ 地址‘ (OS Error: No address associated with hostname, errno =

    设备无网络 检查设备有网络 没有配置网络权限 在android/src/main/AndroidManifest.xml中 manifest 标签中配置一下权限: 注意:不要填写到 application 标签中

    2024年02月02日
    浏览(11)
  • ubuntu: acpi bios error (bug) could not resolve symbol解决

    ubuntu: acpi bios error (bug) could not resolve symbol解决

    联想拯救者R9000P ubuntu20.04 + windows11 ubuntu内核版本:5.15.0.97 开机时报错,然后疯狂重启: ` 链接: link ACPI(高级配置和电源接口)是一种电源管理技术,用于控制计算机的硬件设备和节能。ACPI+BIOS错误是指在计算机的BIOS配置中存在一些问题,导致ACPI无法正常工作。 个人猜测(

    2024年04月23日
    浏览(11)
  • 【c++ debug】core dump调用栈不显示行号 & no debugging symbols found

    1. 问题 问题1 gdb ./project显示没有debug符号 Reading symbols from project_name (no debugging symbols found) …done 问题2 core dump调用栈不显示行号 … #1 0x00007ffff70ac795 in feature() const at /xxx/.so_path/xxx/project.so 2. 原因 编译没有加 -g 选项。-g用于gdb调试 3. 解决方法 CMakeLists.txt加编译选项 -g 4. 修改后

    2023年04月09日
    浏览(7)
  • Linux 内核函数kallsyms_lookup_name

    内核模块开发的基本规则之一是,模块只能访问已显式导出的符号(函数和数据结构),内核使用EXPORT_SYMBOL宏和EXPORT_SYMBOL_GPL宏来导出符号。 关于EXPORT_SYMBOL宏和EXPORT_SYMBOL_GPL宏请参考:Linux EXPORT_SYMBOL宏详解 即便如此,许多符号也受到限制,因此只有具有GPL兼容许可证的模块

    2024年02月11日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包