(共享库)动态库制作和使用
动态库的原理
静态库: GCC
进行链接时,会把静态库i代码打包到可执行程序中。
动态库: GCC
进行链接时,动态库的代码不会被打包到可执行程序中。
共享库的代码是在可执行程序运行时才载入内存的,通过ldd (list dynamicdependencies)
命令检查动态库依赖关系,在编译过程中仅简单的引用,因此代码体积较小。
优点
-
节省内存
-
易于更新
缺点
延时绑定速度慢
命名格式
lib开头 固定
.so结尾 固定
中间为动态库名
例如: libadd.so
add 就是动态库的名字
动态库的制作
1.生成 与位置无关 的目标文件
gcc -fPIC *.c -c 得到.o 文件 -fPIC 表示生成与位置无关的代码 *.c 通配符,表示所有以.c结尾的文件
2.制作动态库
gcc -shared *.o -o lib×××.so 或者 gcc -shared -o lib×××.so *.o -shared 制作动态库 -o 重命名生成的新文件
3.使用动态库
gcc main.c -L./ -ladd -I./ -o app -L +指定库所在的路径 -I +头文件所在位置 -l +动态库名
4.执行生成的可执行文件 ./app
如果出现以下错误:
/app: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
解决出错方案
出现错误的原因:
-
找不到依赖的共享库
-
没有给动态链接器指定动态库的路径
有四种解决方法
- 设置临时环境变量:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:+以上制作库的绝对路径
,在终端上设置,退出终端就自动无效。- 设置永久环境变量:将
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:+以上制作库的绝对路径
, 添加到/home目录的.bashrc
文件的末尾- 直接将制作的库文件移动到
/usr/lib
- 将制作的库文件所在的决定路径追加到
/etc/ld.so.conf
中 再使用sudo ldconfig -v
更新
实例
lin@lin-virtual-machine:~/sharedlib$ ls
add.c main.c add.h
lin@lin-virtual-machine:~/sharedlib$ gcc -c -fPIC add.c //得到.o文件
lin@lin-virtual-machine:~/sharedlib$ ls
add.c add.h add.o main.c
lin@lin-virtual-machine:~/sharedlib$ gcc -shared add.o -o libadd.so //得到与位置无关的代码 libadd.so
lin@lin-virtual-machine:~/sharedlib$ ls
add.c add.h add.o libadd.so main.c
lin@lin-virtual-machine:~/sharedlib$ mkdir lib //存放库文件
lin@lin-virtual-machine:~/sharedlib$ mv libadd.so ./lib/
lin@lin-virtual-machine:~/sharedlib$ ls
add.c add.h add.o lib main.c
lin@lin-virtual-machine:~/sharedlib$ gcc main.c -o app -I ./ -L ./lib -l add //使用动态库
lin@lin-virtual-machine:~/sharedlib$ ls
add.c add.h add.o app lib main.c
lin@lin-virtual-machine:~/sharedlib$ ./app //执行app 如果发生以下的错误
./app: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
//以其中一种解决方案解决 临时变量
lin@lin-virtual-machine:~/sharedlib$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/lin/sharedlib/lib
lin@lin-virtual-machine:~/sharedlib$ ./app //添加之后再执行
8