1、前言
库一般都是将写好的比较成熟的代码进行封装,它的作用是方便代码重复利用、移植,不需要每次使用这些代码时都从零开始写起。编译C源码成可执行程序包括四个步骤:预处理->编译->汇编->链接(参考地址)。库是在链接阶段编进程序中,可以分为静态链接和动态链接两种方式:
使用静态库是将 .a 文件包含的内容一起编译到可执行文件中,正是因为这样,如果我们需要编译多个不同的程序,这些程序各自都包含静态库的内容,导致可执行程序也会变大,而且多个程序在内存中就会存在多份。
如果使用动态库,把 .so 文件放到指定的路径中,编译时指定路径去链接。配置环境后,程序运行的时后就会对这些动态库的内容进行加载,不管有多少个可执行程序,它在内存中只有一份,因为它是被动态地去加载。
使用静态库会导致可执行程序体积变大,但是它的效率会比动态库高,因为动态库需要进行跳转去加载,两者就是在时间与空间两者的取舍。
2、前期准备
① 前期准备:首先编写好.c文件,例如
// file: add.c
int add(int a, int b)
{
return (a+b);
}
// file: sub.c
int sub(int a, int b)
{
return (a-b);
}
② 前期准备:编写.h头文件声明函数
// file: mymath.h
#ifndef __MYMATH_H
#define __MYMATH_H
int add(int, int);
int sub(int, int);
#endif
③ 前期准备:编写测试文件main.c
// file: main.c
#include <stdio.h>
#include "mymath.h" // 用" "包含头文件,与<>区别看下面链接
int main()
{
int a = 2;
int b = 1;
printf("a + b = %d\n", add(a, b));
printf("a - b = %d\n", sub(a, b));
return 0;
}
#include “”与<>包含头文件区别:
3、制作静态库
① 制作静态库:将前面的.c通过gcc进行预处理,编译,汇编
格式:gcc -c xxx.c -o xxx.o
book@book:/work/mystaticlib$ gcc -c add.c -o add.o
book@book:/work/mystaticlib$ gcc -c sub.c -o sub.o
② 制作静态库:将.o文件生成静态库文件
格式:ar rcs lib库名.a xxx.o yyy.o
book@book:/work/mystaticlib$ ar rcs libmymath.a sub.o add.o
③ 使用静态库:编译测试文件
格式:gcc <程序.c源码> lib库名.a -o <输出可执行文件名> -I 头文件目录
book@book:/work/mystaticlib$ gcc main.c libmymath.a -o main -I ./
④ 使用静态库:执行程序
book@book:/work/mystaticlib$ ./main
a + b = 3
a - b = 1
4、制作动态库
这里直接使用前期准备的源文件,包括add.c sub.c mymath.h main.c。
① 制作动态库:将 .c 文件生成与位置无关的代码.o文件
格式:gcc -c xxx.c -o xxx.o -fPIC
book@book:/work/mydynamiclib$ gcc -c add.c -o add.o -fPIC
book@book:/work/mydynamiclib$ gcc -c sub.c -o sub.o -fPIC
② 制作动态库:使用gcc -shared命令
格式:gcc -shared -o lib库名.so xxx.o yyy.o
book@book:/work/mydynamiclib$ gcc -shared -o libmymath.so sub.o add.o
③ 使用动态库:编译时,指定库和头文件所在目录
格式:gcc <.c程序源码> -o <输出可执行文件名> -l库名 -L库路径 -I头文件路径
book@book:/work/mydynamiclib$ gcc main.c -o main -lmymath -L ./ -I ./
④ 使用动态库:配置运行环境,有多种方法,选其中一种即可
1)临时生效:命令行执行export LD_LIBRARY_PATH=动态链接路径
2)永久生效:
a)vi ~/.bashrc
b)LD_LIBRARY_PATH=动态链接路径
c)重启终端 . .bashrc/ 或 source .bashrc/
3)拷贝库文件到/lib (标准C库所在目录位置,头文件的拷贝原理也一样)
4)修改配置文件
a)sudo vi /etc/ld.so.conf
b)写入动态库路径
c)保存后命令行输入“sudo ldconfig -v”使文件生效
d)(可选)使用命令“ldd 可执行程序”查看是否生效
⑤ 使用动态库:执行程序
book@book:/work/mydynamiclib$ ./main
a + b = 3
a - b = 1