error while loading shared libraries 找不到动态库问题如何解决

在使用 c 或 c++ 开发应用时,在启动程序时,有时会遇到这个错误,找不到动态库。这个时候,我们使用 ldd 来查看,发现可执行文件依赖的动态库显示为 not found。

1 实验代码

使用如下 3 个文件做实验。

hello.h 中声明了函数 say_hello()。

hello.c 中实现了函数 say_hallo(), 在函数中打印 hello,hello.c 编译出一个动态库。

main.c 中调用 hello.c 中的函数 say_hello(),main.c 编译出可执行文件。

hello.h:

void say_hello();

hello.c

#include <stdio.h>
#include "hello.h"void say_hello() {printf("hello\n");
}

main.c

#include "hello.h"int main() {say_hello();return 0;
}

使用 gcc -fPIC -shared hello.c -o libhello.so 编译出动态库,使用 gcc main.c libhello.so 编译可执行文件,编译之后的文件目录如下,libhello.so 是动态库,a.out 是可执行文件。

这个时候直接执行 a.out 却无法执行,打印错误信息是找不到动态库。

除了使用 ldd 查看文件依赖的动态库之外,还可以使用 objdump 或 readelf 来查看可执行文件依赖的动态库。

objdump -x a.out |grep NEED

readelf -d a.out |grep NEED

2 动态库路径配置

有几种方式可以配置动态库的路径,这几种方式都是可行的,其中 LD_LIBRARY_PATH 是工作中最常使用的。

2.1 LD_LIBRARY_PATH 

工作中,我们常用的是设置一个环境变量 LD_LIBRARY_PATH,将依赖的动态库路径追加到这个环境变量中,可执行文件就可以执行了。在执行可执行文件时,linux 加载器会从这个环境变量所包含的路径中找动态库。

如下图所示,将 libhello.so 追加到环境变量,使用 ldd 查看 a.out 依赖的库,也不会显示 not found 了,执行 a.out 也可以正确执行。

2.2 /etc/ld.so.conf.d/

先看看这个目录下,默认有什么文件。可以看到,有 3 个 .conf 文件,文件中的内容分别是 /usr/local/lib,/lib/x86_64-linux-gnu、/usr/lib/x86_64-linux-gnu,/usr/lib/x86_64-linux-gnu/libfakeroot。这个目录下配置的路径下的动态库会被查找到。

在该目录下配置的路径下的动态库,可以通过 ldconfig -p 查看到。

如果要把本文中的 libhello.so 也加入到这个目录下,操作如下:

(1)首先在目录下增加一个 .conf 文件,文件名没有要求,只要不重复就可以,文件里写入 libhello.so 所在的目录

(2)执行 ldconfig,添加配置之后执行 ldconfig 才会生效

执行完两个步骤之后,使用 ldconfig -p 就可以看到 libhello.so 出现在缓存里了。

2.3 编译时添加路径

在编译的时候使用 -Wl,rpath  来添加动态库路径。其中 rpath 是 run path 的意思,使用 rpath 指定的路径,在加载时会到这个路径下查找动态库。

gcc main.c -lhello -L. -Wl,-rpath /home/wyl/test/libtest/

使用上边的命令编译之后,使用 ldd 查看 a.out 依赖的动态库,能够找到 libhello.so。

使用 objdump 可以看到,这个路径被直接写到了 a.out 文件中。

3 不同配置下的动态库查找顺序

LD_DEBUG 可以用来查看链接和加载过程的信息,用来调试。LD_DEBUG 可以赋不同的值,不同的值可以查看不同的调试信息。

我们使用 libs 来显示库的加载信息。在实验之前,做如下工作:

(1)编译时使用 rpath 选项

这样的话,就会将 /home/wyl/test/libtest/ 写到编译的目标文件中

gcc main.c -lhello -L. -Wl,-rpath /home/wyl/test/libtest/

(2)配置 LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/home/wyl/test/libtest/lib1:$LD_LIBRARY_PATH

(3)配置 /etc/ld.so.conf.d/hello.conf

这样的话,3 种方式都做了配置,但是 3 个方式配置的路径是不一样的。同时我们只让 libhello.so 存在于 /home/wyl/test/libtest/lib2 中,另外两个目录下不放 libhello.so。

使用 LD_DEBUG 的打印信息如下,从打印信息可以看出来:

(1)首先查找的路径是 LD_LIBRARY_PATH 中的路径

(2)LD_LIBRARY_PATH 路径找不到,从 rpath 选项中的路径查找

(3)rpath 路径找不到,则从 /etc/ld.so.cache 中查找,该文件中保存的就是配置在 /etc/ld.so.conf.d/ 中配置的目录下的动态库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/25448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Vue】修改数量

文章目录 底部总价展示完整代码 注意&#xff1a;前端 vuex 数据&#xff0c;后端数据库数据都要 注册点击事件 页面中dispatch action 提供action函数 提供mutation处理函数 底部总价展示 提供getters 动态渲染 完整代码 main.js import Vue from vue import App from…

Linux:基础开发工具

文章目录 Linux 软件包管理器 yum什么是软件包关于rzsz查看软件包安装软件卸载软件安装扩展源 Linux 编辑器 vimvim的基本概念正常/普通/命令模式(Normal mode)插入模式(Insert mode)底行模式(last line mode) vim的基本操作[命令模式]切换至[插入模式][插入模式]切换至[命令模…

【面经总结】Java基础 - 语言特性

参数传递 形参和实参的区别是什么&#xff1f; 形参&#xff1a;方法定义的参数 实参&#xff1a;调用方法实际传入的参数 Java是值传递还是引用传递&#xff1f; Java是值传递&#xff1a;将数据拷贝一份传递 基本参数类型&#xff1a;拷贝字面量引用类型(对象)&#xf…

【CW32F030CxTx StartKit开发板】开发资料

本来是参加21ic的评测活动&#xff0c;不知道为什么评测文章一直被提示有不良内容&#xff0c;所以只好先在此记录一下相关的资料。 此次测试的是CW32F030CxTxStartKit 评估板。该开发板为用户提供一种经济且灵活的方式使用 CW32F030CxTx 芯片构建系统原型&#xff0c;可进行性…

RV32I指令集

RV32I指令集 一、简介指令集总览:扩展指令集:提供整数乘法/除法(M)、原子操作(A)以及单精度(F)和双精度浮点(D)还有压缩指令集(C)内存:二、操作数相关常见操作数类型汇编代码分段文本段(text section)数据段(data section)BSS段三、RV32I寄存器基础指令格式立…

sm2证书生成(openssl3.0)

1、下载安装包 https://www.openssl.org/source/openssl-3.0.14.tar.gz 2、解压到指定位置 /appserver/openssl-3.0.14 3、安装依赖包 yum -y install gcc perl make zlib-devel perl-CPAN 4、编译 ./config shared --prefix/appserver/SM make depend make make install 5…

A52 STM32_HAL库函数 之 TIM通用驱动 -- B -- 所有函数的介绍及使用

A53 STM32_HAL库函数 之 TIM通用驱动 -- B -- 所有函数的介绍及使用 1 该驱动函数预览1.12 HAL_TIM_OC_DeInit1.13 HAL_TIM_OC_MspInit1.14 HAL_TIM_OC_MspDeInit1.15 HAL_TIM_OC_Start1.16 HAL_TIM_OC_Stop1.17 HAL_TIM_OC_Start_IT1.18 HAL_TIM_OC_Stop_IT1.19 HAL_TIM_OC_St…

Java学习-JDBC(三)

JDBC扩展 实体类和ORM 在使用JDBC操作数据库时&#xff0c;会发现数据是零散的&#xff0c;明明在数据库中是一行完整的数据&#xff0c;到了Java中变成一个个变量&#xff0c;不利于维护和管理&#xff0c;Java是面向对象的&#xff0c;一个表对应一个类&#xff0c;一行数据…

激活乡村振兴新动能:推动农村产业融合发展,打造具有地方特色的美丽乡村,实现乡村全面振兴

目录 一、推动农村产业融合发展 1、农业产业链条的延伸 2、农业与旅游业的结合 二、挖掘地方特色&#xff0c;打造美丽乡村 1、保护和传承乡村文化 2、发展特色农业 三、加强基础设施建设&#xff0c;提升乡村品质 1、改善农村交通条件 2、提升农村水利设施 四、促进…

使用【AbortController】终止请求

AbortController 是一个 Web API&#xff0c;用于终止一个或多个 Web 请求。当你使用 fetch API 发送异步请求时&#xff0c;你可能需要在某些情况下主动终止这些请求。使用 AbortController 可以实现这一功能。 基本用法&#xff1a; 创建一个 AbortController 实例: const co…

JavaEE——声明式事务管理案例:实现用户登录

一、案例要求 本案例要求在控制台输入用户名密码&#xff0c;如果用户账号密码正确则显示用户所属班级&#xff0c;如果登录失败则显示登录失败。实现用户登录项目运行成功后控制台效果如下所示。 欢迎来到学生管理系统 请输入用户名&#xff1a; zhangsan 请输入zhangsan的密…

吴恩达2022机器学习专项课程C2W2:2.23 选修_反向传播算法的工作原理(什么是导数图计算大型神经网络)

目录 引言一.导数的计算1.epsilon与导数的关系2.其它导数符号形式3.导数小结 二.小型神经网络的计算图1.什么是计算图&#xff08;前向传播过程&#xff09;2.反向传播计算过程3.验证反向传播的计算结果4.为什么用反向传播计算导数&#xff1f; 三.扩大神经网络的计算图1.计算反…

笔记本充电出现了问题。

不知道为什么。电池充电图片一直显示的空。谁能救救我&#xff01;

C51学习归纳9 --- I2C通讯学习(重点)

首先&#xff0c;我自己学习过以后的直观感觉&#xff0c;通信协议是单片机的灵魂之一&#xff0c;只有规定好了通信协议我们才能够正确的接收到信息&#xff0c;才能实现更加深入的研究。所以这一部分是需要好好学习的。 本节借助一个可存储的芯片AT24C02&#xff0c;进行在I2…

docker国内被墙,有什么可以平替的公有云仓库?

目前有两个&#xff1a; 1、一个是红帽 quay.io 2、一个是Github的仓库 ghcr.io 红帽的不是那么全&#xff0c; Github的比较全&#xff0c;基本满足日常使用。

C语言怎样初始化图形模式?

一、问题 在C语⾔中&#xff0c;initgraph( ) 函数⽤于初始化图形模式。初始化时&#xff0c;那么多参数都是⼲什么的&#xff1f;怎样设置&#xff1f; 二、解答 initgraph( ) 函数⽤于初始化图形模式&#xff0c;其语法格式如下。 void far initgraph(int far * gdriver, i…

ACM算法学习路线、清单

入门 模拟、暴力、贪心、高精度、排序 图论 搜索 BFS、DFS、IDDFS、IDA*、A*、双向BFS、记忆化 最短路 SPFA、bellman-fort(队列优化)、Dijkstra(堆优化)、Johnson、Floyd、差分约束、第k短路 树 树的重心和直径、dfs序、树链刨分与动态树、LCA、Prufer编码及Cayley定理…

对象存储OSS 客户端签名直传的安全风险和解决方法

1. 前言 阿里云对象存储OSS&#xff08;Object Storage Service&#xff09;是一款海量、安全、低成本、高可靠的云存储服务&#xff0c;可提供99.9999999999%&#xff08;12个9&#xff09;的数据持久性&#xff0c;99.995%的数据可用性。多种存储类型供选择&#xff0c;全面…

mysql批量修改列备注

--把表名&#xff0c;字段名&#xff0c;备注导入到这个表里&#xff0c;表明和字段名一定要一致&#xff01;&#xff01;&#xff01; CREATE TABLE supplement_clumn_comment ( table varchar(200) DEFAULT NULL COMMENT 表名, columns varchar(200) DEFAULT NULL COMME…

11.链表

数组的分类&#xff1a;便于遍历 静态数组&#xff1a;int arr[10]数据过多造成空间溢出&#xff0c;数据过小空间浪费 动态数组&#xff1a;malloc calloc realloc 合理利用空间不能快捷的插入或删除数据&#xff08;会涉及到大量的数据移动&#xff09; 知识点一&#xff1…