什么是库文件
单一模型
将程序中所有功能全部实现于一个单一的源文件内部。
编译时间长,不易于维护和升级,不易于协作开发。
分离模型
将程序中的不同的功能模块划分到不同的源文件中。
缩短编译时间,易于维护和升级,易于协作开发。
库文件
对多个目标文件的管理比较麻烦,可以将多个目标文件统一整理成一个库文件。
库文件可以直接在其他C语言程序中直接调用。
可以简单的把库文件理解成一种代码仓库,它提供给使用者一些可以直接拿来用的变量,函数或者类。
库文件一般指的是计算机上的一类文件,分为两种,一种叫做静态库,一种叫做动态库。
静态库
概述
静态库的本质是将多个目标文件打包成一个文件。
链接静态库就是将库中被调用的代码复制到调用模块中。
静态库的扩展名是.a
,比如libxxx.a
。
静态库的构建
1、编辑库的实现代码和接口声明
- 计算模块:calc.h,calc.c
- 显示模块:show.h,show.c
- 接口文件:math.h
2、编译成目标文件
gcc -c calc.c
gcc -c show.c
3、打包成静态库
ar -r libmath.a calc.o show.o
实战案例:构建 libmath.a 静态库
准备源文件
calc.h
- 定义加法:
int add(int a, int b);
- 定义减法:
int sub(int a, int b);
#ifndef __CALC_H_
#define __CALC_H_int add(int a, int b);
int sub(int a, int b);#endif // __CALC_H_
calc.c
- 简单的实现加法
- 简单的实现减法
#include "calc.h"int add(int a, int b){return a + b;
}int sub(int a, int b){return a - b;
}
show.h
#ifndef __SHOW_H_
#define __SHOW_H_void show(int a, char* op, int b, int res);#endif // __SHOW_H_
show.c
#include <stdio.h>
#include "show.h"void show(int a, char* op, int b, int res){printf("%d %s %d = %d\n", a, op, b, res);
}
编译C源文件
gcc -c calc.c
gcc -c show.c
构建静态库
ar -r libmath.a calc.o show.o
使用静态库文件
main.c
#include <stdio.h>
#include "calc.h"
#include "show.h"int main(){int a = 11;int b = 22;int res = add(a, b);show(a, "+", b, res);return 0;
}
编译并运行文件,此时把静态库文件也带上:
gcc main.c libmath.a -o main && ./main
输出结果如下:
11 + 22 = 33
使用接口文件优化
当我们的库越来越大的时候,头文件也会越来越多,这个是让用户分别引入每个头文件是不人性化的。
这个时候,我们可以给库配套一个相应的头文件,这个头文件中引入需要的所有其他头文件这个。这个与库对应的头文件就是我们这个库的接口文件。
math.h
#ifndef __MATH_H_
#define __MATH_H_#include "calc.h"
#include "show.h"#endif // __MATH_H_
main.c
#include <stdio.h>
#include "math.h"int main(){int a = 11;int b = 22;int res = add(a, b);show(a, "+", b, res);return 0;
}
动态库
概述
动态库的扩展名是.so。
动态库是被加载,调用的时候是根据内存地址去调用,而不是将代码复制到文件中。
动态库可以同时被多个进程使用。
实战案例:构建 libmath.so 动态库
准备源文件
calc.h
- 定义加法:
int add(int a, int b);
- 定义减法:
int sub(int a, int b);
#ifndef __CALC_H_
#define __CALC_H_int add(int a, int b);
int sub(int a, int b);#endif // __CALC_H_
calc.c
- 简单的实现加法
- 简单的实现减法
#include "calc.h"int add(int a, int b){return a + b;
}int sub(int a, int b){return a - b;
}
show.h
#ifndef __SHOW_H_
#define __SHOW_H_void show(int a, char* op, int b, int res);#endif // __SHOW_H_
show.c
#include <stdio.h>
#include "show.h"void show(int a, char* op, int b, int res){printf("%d %s %d = %d\n", a, op, b, res);
}
编译C源文件
gcc -c -fpic calc.c
gcc -c -fpic show.c
构建动态库
gcc -shared calc.o show.o -o libmath.so
使用动态库
main.c
#include <stdio.h>
#include "calc.h"
#include "show.h"int main(){int a = 11;int b = 22;int res = add(a, b);show(a, "+", b, res);return 0;
}
编译并运行文件,此时把静态库文件也带上:
# 先配置库所在的环境变量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.# 编译执行
gcc main.c libmath.so -o main && ./main
输出结果如下:
11 + 22 = 33