静态库与动态库相关知识…
库文件分为静态库和动态库(共享库)。
静态库
Linux为.a
,window上为.lib
。
静态库是中间文件的集合,在链接阶段直接将库中的内容合并到最终的可执行文件中,链接完成后,生成的可执行文件的执行不再依赖静态库。
静态库生成的命令
1 | gcc -c *.c # 先将.c文件生成对应的.o文件 |
静态库的使用
- 方法一:
gcc -o run main.c -L(库路径) -l(库名)
,例如:1
gcc -o run main.c -L/home/stu/lib -lList
- 方法二:
gcc -o run main.c 路径/libxxxx.a
,例如:1
gcc -o run main.c /home/stu/lib/libList.a
动态库
Linux上为.so
,Window上为.dll
。
动态库是不可单独执行的可执行文件,链接阶段只在可执行文件中设置使用的的库,运行时由操作系统加载到内存上执行,因此生成的可执行文件在执行时要依赖动态库的存在。
动态库生成的命令
1 | gcc -shared -fPIC -o libxxxx.so *.c |
-fPIC参数,多个应用程序加载动态库时,系统只有一个so代码段。如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位,重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy。每个copy都不一样,取决于这个.so文件代码段和数据段内存映射的位置。
动态库的使用
同静态库一样。
当链接完成后执行时会有问题,问题出现的原因是:动态库需要由操作系统加载到内存上,但操作系统找不到自定的库,因此依赖动态库而的程序不能直接运行会出错!解决这个问题有以下两种方案:
- 将动态库拷贝到 /lib 或 /usr/lib 目录下,但是这个操作需要 root 权限,不建议这么做;
- 设置环境变量export LD_LIBRARY_PATH=动态库所在的绝对路径,或者修改文件:
1
2
3
4
5vi /home/***/.bashrc //进入到.bashrc这个配置文件中
然后在文件的最后加上一句export LD_LIBRARY_PATH=动态库所在的绝对路径
或在/etc/ld.so.conf.d/下新建test.conf文件,文件中添加动态库所在的绝对路径,
sudo ldconfig # 使生效
另外
ldd run
查看可执行文件run中所加载的动态库。
动态库和静态库的区别
- 同样的程序,使用静态库比使用共享库程序更大;
- 静态库在编译链接是,就加入到了可执行程序中,共享库是在运行程序后动态装载;
- 目标主机没有静态库,程序可以运行,没有共享库,运行不了;
- 共享库升级后,程序不需要重新编译,可以直接被使用,静态库需要重新编写程序,链接新方法。