加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

【Linux】解决动态库无法加载问题

发布时间:2023-01-08 10:01:36 所属栏目:Linux 来源:网络
导读: 注:如果ldd能够显示所有库路径,但是程序执行依然报错,可以尝试执行
sudo ldconfig
2.4.1 库的工作原理
静态库如何被加载
在程序编译的最后一个阶段也就是链接阶段,提供的静态库会被打包

注:如果ldd能够显示所有库路径,但是程序执行依然报错,可以尝试执行
sudo ldconfig

2.4.1 库的工作原理

静态库如何被加载

在程序编译的最后一个阶段也就是链接阶段,提供的静态库会被打包到可执行程序中。当可执行程序被执行,静态库中的代码也会一并被加载到内存中,因此不会出现静态库找不到无法被加载的问题。

动态库如何被加载

在程序编译的最后一个阶段也就是链接阶段:

在 gcc 命令中虽然指定了库路径 (使用参数 -L ), 但是这个路径并没有记录到可执行程序中linux动态库,只是检查了这个路径下的库文件是否存在。

同样对应的动态库文件也没有被打包到可执行程序中,只是在可执行程序中记录了库的名字。

可执行程序被执行起来之后:

程序执行的时候会先检测需要的动态库是否可以被加载,加载不到就会提示上边的错误信息

当动态库中的函数在程序中被调用了, 这个时候动态库才加载到内存,如果不被调用就不加载

动态库的检测和内存加载操作都是由动态连接器来完成的

2.4.2 动态链接器

动态链接器是一个独立于应用程序的进程,属于操作系统,当用户的程序需要加载动态库的时候动态连接器就开始工作了,很显然动态连接器根本就不知道用户通过 gcc 编译程序的时候通过参数 -L 指定的路径。

那么动态链接器是如何搜索某一个动态库的呢,在它内部有一个默认的搜索顺序,按照优先级从高到低的顺序分别是:

可执行文件内部的 DT_RPATH 段

系统的环境变量 LD_LIBRARY_PATH

系统动态库的缓存文件 /etc/ld.so.cache

存储动态库 / 静态库的系统目录 /lib/, /usr/lib 等

按照以上四个顺序,依次搜索,找到之后结束遍历,最终还是没找到,动态连接器就会提示动态库找不到的错误信息。

2.4.3 解决方案

可执行程序生成之后,根据动态链接器的搜索路径,我们可以提供三种解决方案,我们只需要将动态库的路径放到对应的环境变量或者系统配置文件中,同样也可以将动态库拷贝到系统库目录(或者是将动态库的软链接文件放到这些系统库目录中)。

方案 1: 将库路径添加到环境变量 LD_LIBRARY_PATH 中

找到相关的配置文件

用户级别: ~/.bashrc —> 设置对当前用户有效

系统级别: /etc/profile —> 设置对所有用户有效

使用 vim 打开配置文件,在文件最后添加这样一句话

# 自己把路径写进去就行了
export LIBRARY_PATH=$LIBRARY_PATH:动态库的绝对路径

让修改的配置文件生效

修改了用户级别的配置文件,关闭当前终端,打开一个新的终端配置就生效了

动态库调用静态库_linux动态库_汉克库动态壁纸

修改了系统级别的配置文件,注销或关闭系统,再开机配置就生效了

不想执行上边的操作,可以执行一个命令让配置重新被加载

# 修改的是哪一个就执行对应的那个命令
# source 可以简写为一个 . , 作用是让文件内容被重新加载
$ source ~/.bashrc ? ? ? ? ?(. ~/.bashrc)
$ source /etc/profile ? ? ? (. /etc/profile)

方案 2: 更新 /etc/ld.so.cache 文件

找到动态库所在的绝对路径(不包括库的名字)比如:/home/robin/Library/

使用 vim 修改 /etc/ld.so.conf 这个文件,将上边的路径添加到文件中 (独自占一行)

# 1. 打开文件
$ sudo vim /etc/ld.so.conf

# 2. 添加动态库路径, 并保存退出

更新 /etc/ld.so.conf 中的数据到 /etc/ld.so.cache 中

# 必须使用管理员权限执行这个命令
$ sudo ldconfig ??

方案 3: 拷贝动态库文件到系统库目录 /lib/ 或者 /usr/lib 中 (或者将库的软链接文件放进去)

# 库拷贝
sudo cp /xxx/xxx/libxxx.so /usr/lib
# 创建软连接
sudo ln -s /xxx/xxx/libxxx.so /usr/lib/libxxx.so

2.4.4 验证

在启动可执行程序之前,或者在设置了动态库路径之后,我们可以通过一个命令检测程序能不能够通过动态链接器加载到对应的动态库,这个命令叫做 ldd

# 语法:
$ ldd 可执行程序名
# 举例:
$ ldd app
?? ?linux-vdso.so.1 => ?(0x00007ffe8fbd6000)
? ? libcalc.so => /home/robin/Linux/3Day/calc/test/libcalc.so (0x00007f5d85dd4000)
? ? libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5d85a0a000)
? ? /lib64/ld-linux-x86-64.so.2 (0x00007f5d85fd6000) ?==> 动态链接器, 操作系统提供

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!