静态库和动态库------>函数工具库
1、什么是库?
本质上是一个代码的二进制形式,可以被载入到内存中执行。
库一般是别人写好的,现成的,成熟的
***linux中的库与win中的库不通用,二者二进制计算不一样。
*** stm32:寄存器开发,标准外设库开发,HAL库开发
2、库的分类
静态库和动态库
二者不同点在于代码被载入的时刻不同。
静态库的特点
静态库在程序编译时会被链接到目标代码中
程序运行时将不再需要该静态库,因此体积较大
动态库的特点
动态库在程序编译时并不会被连接到目标代码中,
而是在程序运行时才被载入,因此在程序运行
时还需要动态库存在,因此代码体积较小(相对静态库)。
***程序和静态库产生链接就只有一个时刻:编译时期
***静态库是临界资源,只能被一个进程使用
***程序和动态库发生链接的时刻在程序执行实时时期
***动态库是公共资源,可以被多个进程调用
***头文件就是c库,就是静态库。
***库文件移动不会被损坏,移植性强。.c文件可能会被损坏。
3、实操编写静态库与动态库
gcc编译4个步骤:预处理---编译---汇编---链接
静态库://静态库命名必须 lib库名.a lib开头 .a结尾。
1、写一个.c文件,里面是运行逻辑等函数
2、把这个.c文件,编译汇编成.o文件
gcc -c 文件.c -o 文件.o
-c : 对源文件进行编译汇编 但不做链接--->不会产生可执行文件
3、将.o文件制作成静态库文件
ar crs lib文件.a 文件.o
ar crs 制作静态库的命令
4、编写一个测试代码:文件.c 用与测试
#include <stdio.h>
#include "mylib.h"
int main(){
int a,b;
printf("请输入a和b");
scanf("%d%d",&a,&b);
printf("%d+%d=%d\n",a,b,myplus(a,b));
printf("%d-%d=%d\n",a,b,myusb(a,b));
return 0;
}
5、编译测试文件.c 的同时链接静态库
gcc -static -Wall -o test test.c -L. -lmylib
-static:指定生成静态链接库。
-L 找库的路径 -L.找到当前 .
-l 指定库名
动态库://动态库命名必须 lib库名.so lib开头 .so结尾。
1、写一个.c文件,里面是运行逻辑等函数
2、将库源文件编译.o的目标文件
gcc -fPIC -Wall -c 文件.c -o 文件.o //P I C W是大写
-fPIC 创建与地址无关的编译程序
-fPIC:表示编译为位置独立的代码,用于编译共享库。目标文件需要创建成位置无关码,
概念上就是在可执行程序装载它们的时候,它们可以放在可执行程序的内存里的任何地方。
3、将.o文件制作成动态库文件
gcc -shared -fPIC -o lib.so 文件.o
-shared:指定生成动态链接库。
4、编写测试自己写的.c文件
5、编译自己写的.c文件同时链接到动态库
gcc -Wall -o 别名 自己写的.c -L. -l库名
6、发现无法执行---如何让系统认识动态库
1.1 直接将动态库文件放到 /lib 或 /usr/lib 中
(推荐)1.2 在系统配置文件中声明路径
1.2.1 打开配置文件 sudo vim /etc/ld.so.conf
1.2.2 在该文件新行中添加动态库路径 使用pwd命令查看路径 复制到文件中
1.2.3 保存退出后执行 sudo ldconfig
(不推荐)1.3 将动态库的路径声明到环境变量中
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: 填写pwd命令查看到的绝对路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. 这是相对路径写法
export --- 声明环境变量
LD_LIBRARY_PATH --- 声明的变量类型是库文件
7、再测试就得了。