动态库的制作
1.首先建立三个C文件以及相应的头文件
2. 现将.c文件编译成.o文件
gcc -fpic -c test1.c test2.c
3.将第2步编译的.o文件生成动态库
gcc -shared test1.o test2.o -o libtest.so
动态库的命名方式:libxxx.so
- lib:前缀,固定格式
- xxx:名称,自己确定
- .so: 后缀,固定格式
动态库的使用
1. 编译链接生成可执行文件test,其中“-L”指定库的存储路径,“-l”指定库的名称(不需要“lib”和扩展名“.so”),如果在库的存储路径有同名的动态库和静态库,gcc默认使用动态库
gcc test.c -o test -I ./ -L ./ -l test
2. 运行可执行文件test,出现找不到动态库的问题
3. 通过ldd(list dynamic dependencies)命令检查动态库依赖关系
程序启动之后,动态库会被动态加载到内存中,通过 ldd (list dynamicdependencies)命令检查动态库依赖关系。可以看到libtest.so动态库无法找到。
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是由ld-linux.so来完成的,它先后搜索elf文件的 DT_RPATH段 ——> 环境变量LD_LIBRARY_PATH ——> /etc/ld.so.cache文件列表 ——> /lib/,/usr/lib目录找到库文件后将其载入内存。
4. 解决动态库加载失败的问题
通过以下五种方法可以指定共享库的路径
- 临时修改Linux环境变量LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/动态库的绝对路径:$LD_LIBRARY_PATH
修改完临时变量,动态库加载成功,如下图:
- 用户层次上更改Linux环境变量
在用户目录下有.bashrc(该文件为隐藏文件)文件,在最后一行添加以上语句
sudo vim ~/.bashrc
在最后一行加入:export LD_LIBRARY_PATH=/动态库的绝对路径:$LD_LIBRARY_PATH
在终端还要通过如下命令才能使这个文件的修改生效:
source ~/.bashrc
- 修改系统级别环境变量
通过一下命令直接进入系统级别的配置文件。同样的,在最后一行增加和上面一样的代码
sudo vim /etc/profile
在最后一行加入:export LD_LIBRARY_PATH=/动态库的绝对路径:$LD_LIBRARY_PATH
在终端还要通过如下命令才能使这个文件的修改生效:
source /etc/profile
- 修改/etc/ld.so.cache文件列表
这个文件是一个二进制文件,无法直接修改,需要间接修改,即/ect/ld.so.conf文件。使用sudo打开这个文件,在最后一行增加需要加载的动态库的绝对路径的即可。
sudo vim /etc/ld.so.conf
在最后一行加入:export LD_LIBRARY_PATH=/动态库的绝对路径:$LD_LIBRARY_PATH
编辑完之后需要使之生效:
sudo ldconfig