动态库和静态库
- 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
- 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
- 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文 件的整个机器码
- 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
- 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚 拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
测试程序
[ggg@localhost staticandlib]$ ls
add.c add.h mymath.c sub.c sub.h
[ggg@localhost staticandlib]$ cat add.h
#include<stdio.h>
int add(int x,int y);
[ggg@localhost staticandlib]$ cat add.c
#include"add.h"
int add(int x,int y)
{
return x+y;
}
[ggg@localhost staticandlib]$ cat sub.h
#include<stdio.h>
int sub(int x,int y);
[ggg@localhost staticandlib]$ cat sub.c
#include<stdio.h>
int sub(int x,int y)
{
return x-y;
}
[ggg@localhost staticandlib]$ cat mymath.c
#include<stdio.h>
#include"add.h"
#include"sub.h"
int main()
{
int a=2;
int b=3;
printf("add(%d,%d)=%d\n",a,b,add(a,b));
printf("add(%d,%d)=%d\n",a,b,sub(a,b));
return 0;
}
生成静态库
[ggg@localhost staticandlib]$ ls
add.c add.h mymath.c sub.c sub.h
[ggg@localhost staticandlib]$ gcc -c add.c -o add.o
[ggg@localhost staticandlib]$ gcc -c sub.c -o sub.o
[ggg@localhost staticandlib]$ ls
add.c add.h add.o mymath.c sub.c sub.h sub.o
[ggg@localhost staticandlib]$ ar -rc libmath.a *.o
[ggg@localhost staticandlib]$ ls
add.c add.h add.o libmath.a mymath.c sub.c sub.h sub.o
[ggg@localhost staticandlib]$ ar -tv libmath.a// t:列出静态库中的文件 v:verbose 详细信息
rw-rw-r-- 1000/1000 1240 Jul 10 23:26 2024 add.o
rw-rw-r-- 1000/1000 1240 Jul 10 23:26 2024 sub.o
[ggg@localhost staticandlib]$ gcc mymath.c -o mymath.exe -L ./ -l math// -L 指定库路径 -l 指定库名 (第一个是大写,第二个是小写)
[ggg@localhost staticandlib]$ ls
add.c add.h add.o libmath.a mymath.c mymath.exe sub.c sub.h sub.o
[ggg@localhost staticandlib]$ ./mymath.exe
add(2,3)=5
add(2,3)=-1
库搜索路径
- 从左到右搜索-L指定的目录。
- 由环境变量指定的目录 (LIBRARY_PATH)
- 由系统指定的目录
- /usr/lib
- /usr/local/lib
生成动态库
[ggg@localhost staticandlib]$ ls
add.c add.h libmath.a mymath.c mymath.exe sub.c sub.h
[ggg@localhost staticandlib]$ gcc -fPIC -c add.c sub.c//fPIC:产生位置无关码
[ggg@localhost staticandlib]$ ls
add.c add.h add.o libmath.a mymath.c mymath.exe sub.c sub.h sub.o
[ggg@localhost staticandlib]$ gcc -shared -o libmath.so *.o//shared: 表示生成共享库格式
[ggg@localhost staticandlib]$ ls
add.c add.h add.o libmath.a libmath.so mymath.c mymath.exe sub.c sub.h sub.o
[ggg@localhost staticandlib]$ gcc mymath.c -o lmymath.exe -L ./ -l math
[ggg@localhost staticandlib]$ ls
add.c add.h add.o libmath.a libmath.so lmymath.exe mymath.c mymath.exe sub.c sub.h sub.o
[ggg@localhost staticandlib]$ ./lmymath.exe
add(2,3)=5
add(2,3)=-1
错误
如果遇到无法运行的时候解决方案:
- 拷贝.so文件到系统共享库路径下, 一般指/usr/lib
- 更改 LD_LIBRARY_PATH 执行 :export LD_LIBRARY_PATH = .
- ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新