一、库的概念

库在系统中是一个二进制文件,他是由XXX.c(不包含main函数)的原文件编译而来,其他程序要使用该源文件中的函数时,只需要在编译时链接上该库即可,无需使用该源文件进行联合编译。这样可以保证知识产权的安全性。

库分为静态库和动态库,在不同的操作系统中,静态库和动态库的格式不同

在windows下:

静态库:XXX.lib

动态库:XXX.dll

在linux下:

静态库:libXXX.a

动态库:libXXX.so

1
2
3
4
5
printf   --> stdio.c  --> libc.so
gcc XXX.c -o XXX -lc //编译指令

abs --> math.c --> libm.so
gcc XXX.c -o XXX -lm

二、静态库

2.1 概念

静态库是由XXX.c(不包含main)的源文件编译生成的一个名为 libXXX.a 的二进制文件,当需要使用该源文件中的相关函数时,只需在编译时链接上该库,无需使用源文件进行联合编译,也能生成可执行程序。

静态体现在:当编译生成可执行程序时,会将静态库整体全部放入可执行程序中,也就是每个可执行程序都完整拥有静态库。使用库中函数时,无需到其他地方找函数实现,直接使用即可。效率较高,但是,可执行程序体积较大

2.2 静态库的制作

1> 准备程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
test.h
#ifndef __TEST_H__
#define __TEST_H__

int sum(int m, int n);


#endif


test.c
int sum(int m, int n)
{
return m+n;
}


main.c
#include<myhead.h>
#include"test.h"

int main(int argc, const char *argv[])
{

printf("sum = %d\n", sum(3,7)); //10

return 0;
}


2> 静态库的制作

1
2
3
4
5
6
7
8
9
10
gcc -c test.c -o test.o                       //只编译不链接,生成二进制文件
ar -crs libtest.a test.o //依赖于二进制文件生成静态库

如果使用多个二进制文件生成一个静态库
ar -crs libtest.a test.o test1.o test2.o ...

ar:用于创建或操作静态库
c:创建静态库
r:替换或覆盖库中同名文件
s:重置静态库

3> 使用静态库

1
2
gcc 主程序.c -L 库的路径 -l库名 -I 头文件路径
例如:gcc main.c -L . -ltest -I .

img

4> 多文件夹存放文件编译

img

三、动态库

3.1 概念

动态库是由XXX.c(不包含main)的源文件编译生成的一个名为 libXXX.so 的二进制文件,当需要使用该源文件中的相关函数时,只需在编译时链接上该库,无需使用源文件进行联合编译,也能生成可执行程序。

动态体现在:当编译生成可执行程序时,会将动态库中的函数索引编译到可执行程序中,当使用该库中的函数时,需要通过索引找到动态库所在的位置,然后调用该库中的函数。多个可执行程序可以共享同一个动态库,所以动态库也叫共享库。效率较低,单可执行程序体积较小。

3.2 动态库的制作

1> 准备文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
test.h
#ifndef __TEST_H__
#define __TEST_H__

int sum(int m, int n);


#endif


test.c
int sum(int m, int n)
{
return m+n;
}


main.c
#include<myhead.h>
#include"test.h"

int main(int argc, const char *argv[])
{

printf("sum = %d\n", sum(3,7)); //10

return 0;
}


2> 生成动态库

1
2
3
4
5
6
7
gcc -fPIC -c test.c -o test.o            //-fPIC忽略文件位置,将test.c只编译不链接生成test.o
gcc -shared test.o -o libtest.so //生成动态库
gcc -shared test.o test1.o test2.o -o libtest.so //多个.o文件共同生成一个动态库

也可以将上述两条指令合成一条
gcc -fPIC -shared test.c -o libtest.so

3> 使用动态库

1
2
gcc 主程序.c -L 库的路径 -l库名 -I 头文件路径
例如:gcc main.c -L . -ltest -I .

img

4> 执行可执行程序时会出现如下错误

img

解决以上错误有两种方式

1、在命令行中,修改库的路径,该方式只能在该终端上起效果,新的终端不受影响

1
export LD_LIBRARY_PATH=库的路径

2、将当前库直接放入根目录下的lib目录下 ( /lib /usr/lib )

1
2
sudo mv libtest.so /lib
sudo mv libtest.so /usr/lib

img

本章完