一、linux系统中的库
库在linux系统中是一个二进制文件,它是由XXX.c(不包含main函数)文件编译而来的,分为静态库和动态库。
库在系统中的内容是不可见的,是一个二进制乱码
当程序需要使用库中的相关函数时,直接链接对应的库即可,无需跟对应的 源文件一起联合编译
作用:能够保证源代码的安全性
库在不同的系统中的表现方式也是不同的
windows下:
静态库:XXX.lib
动态库:XXX.dll
linux下
静态库:libXXX.a
动态库:libXXX.so
库的生成过程:printf ---> stdio.c -----> libc.so <----- -lc ---- a.out
二、静态库
2.1 概念
所谓静态库,就是将一个XXX.c的源文件,编译生成一个libXXX.a的二进制文件。
当程序需要使用源文件中的函数时,只需要链接上该源文件生成的静态库文件即可直接调用相关函数,无需跟源文件联合编译
静态体现在:静态库在跟主程序一起生成可执行程序时,会将静态库完整的放入可执行程序中,每个可执行程序中都独立拥有整个静态库。函数调用时,效率比较高,但是,可执行程序的体积比较大。
2.2 静态库的制作
1> 准备文件
/********************************test.h**************************/
#define TEST_H
#include<myhead.h>
//声明求和函数
int qiuhe(int m, int n);
//声明求最值函数
int qiuzuida(int m, int n);
#endif
/********************************test.c**************************/
//声明求和函数
int qiuhe(int m, int n)
{
return m+n;
}
//声明求最值函数
int qiuzuida(int m, int n)
{
return m>n?m:n;
}
/********************************main.c**************************/
#include"test.h"
int main(int argc, const char *argv[])
{
printf("sum = %d\n", qiuhe(3,5));
printf("max = %d\n", qiuzuida(3,5));
printf("%lf\n", pow(2,3));
return 0;
}
2> 编译生成静态库
1、gcc -c XXX.c -o XXX.o //只编译不链接生成二进制文件
2、ar -crs libXXX.a XXX.o //将XXX.o的二进制文件编译生成libXXX.a的静态库
一个静态库依赖多个.o文件:ar -crs libXXX.a XXX.o AAA.o BBB.o //将XXX.o的二进制文件编译生成libXXX.a的静态库
ar :指令表示要编译生成静态库
-c:create,表示创建静态库
-r:replace,表示如果XXX.o文件已经存在,则被新的文件替换
-s:重置静态库索引
3> 静态库的使用
gcc main.c -L 库的路径 -I 头文件路径 -l库名 -o 可执行程序
4> 分文件情况下的操作
三、动态库
3.1 概念
所谓动态库,就是将一个XXX.c的源文件,编译生成一个libXXX.so的二进制文件。
当程序需要使用源文件中的函数时,只需要链接上该源文件生成的动态库文件即可直接调用相关函数,无需跟源文件联合编译
动态体现在:动态库在跟主程序一起生成可执行程序时,只是将相关函数的入口地址列表编译到可执行程序中,当执行到对应的函数调用时,会根据该函数的入口地址,找到对应的动态库,执行该库中的函数。不会将整个库封装到可执行程序中。多个可执行程序可以连接同一个动态库,所以动态库也称为共享库。动态库的体积较小,但是,执行效率没有静态库高。
3.2 动态库的制作
1、gcc -fPIC -c XXX.c -o XXX.o //只编译不链接生成二进制文件, -fPIC表示忽略文件位置进行编译
2、gcc -shared XXX.o -o libXXX.so //编译生成动态库
多个程序共同生成动态库:gcc -shared XXX.o AAA.o BBB.o -o libXXX.so
s也可以将上面的两个操作合成一个
gcc -fPIC -shared XXX.c -o libXXX.so
3.3 动态库的使用
gcc main.c -L 库的路径 -I 头文件路径 -l库名 -o 可执行程序
3.4 如何解决上述问题
1> 修改当前终端的路径常量为库的路径
export LD_LIBRARY_PATH=库的路径
注意:该方式只能对当前终端有效,其他终端无效
2> 直接将自定义的动态库放入到系统中的库中
/lib /usr/lib