一、什么是库
- 库文件是计算机上的一类文件,可以简单的把库文件看成一种代码仓库(二进制),它提供给使用者一些可以直接拿来用的变量、函数或类;
- 库是特殊的一种程序,编写库的程序和编写一般的程序区别不大,只是库不能单独运行。(因为要提供给别人使用)
- 库文件有两种,静态库和动态库(共享库),二者的区别是:静态库在程序的链接阶段被复制到了程序中;(根据GCC编译的原理,预处理—编译—汇编—链接(链接成可执行程序);其实静态库和动态库都是在链接阶段做的处理)动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。
- 库的好处:1. 代码保密(反编译);2. 方便部署和分发;
二、静态库的制作
1. 命名规则:
(1)Linux:libxxx.a
- lib:前缀(固定)【library库】;
- xxx:库的名字,自己起;
- .a:后缀(固定);
(2)Windows:libxxx.lib
2. 静态库的制作:最新版本7.5的GCC,链接静态库时不能加前缀lib和后缀.a,否则就会一直找不到库文件。所以看到最后,会给出解决方案
- gcc 获得.o文件(比如有10个文件,把10个文件打成一个库,就得先通过gcc获得.o文件);
- 将.o文件打包,使用ar工具(archive);
- ar rcs libxxx.a(要生成的库名) xxx.o xxx.o (要把哪些.o文件打包到库中,就都列出来);
- r:将文件插入备存文件中(往库文件中插入.o文件);
- c:建立备存文件(即库文件);
- s:索引(创建索引,因为静态库中里面的文件很多,通过s参数,会生成这些文件的索引,方便查找);
3. 静态库的制作操作
(1)通过vscode来连接Ubuntu 虚拟机
vscode 中下载Remote Development插件,之后一步一步操作,连接IP等等(这里略过,重点不是这个);
(2)创建lesson04文件夹
可以直接在虚拟机中用mkdir lesson04来创建文件夹(创建前 pwd看一下当前目录在哪里,可以专门建一个综合文件夹来做这些)
(3)接着再通过xftp将calc和library两个文件上传到服务器中
链接:calc+library
提取码:1234
1. calc文件包括:关于计算的一些操作
- add.c:做加法运算;
- div.c:做除法运算;
- mult.c:做乘法运算;
- sub.c:做减法运算;
- main.c:对这些运算做一套测试;
- head.h:如下
#ifndef _HEAD_H
#define _HEAD_H
// 加法
int add(int a, int b);
// 减法
int subtract(int a, int b);
// 乘法
int multiply(int a, int b);
// 除法
double divide(int a, int b);
#endif
2. 而我们现在就是想把加减乘除这四个操作打包成一个静态库,让别人使用,那么怎么做?
我们用xshell来连接服务器,这样比较好操作;
定位到该去的文件夹下,查看当前文件夹的目录树
- step one:生成这些文件的.o文件:(只进行汇编不去链接它)gcc -c add.c sub.c mult.c div.c
生成了对应的.o文件,注意head.h头文件不需要打成.o文件,因为头文件在预编译的时候就会直接包含到源文件中,main.c是测试代码也不需要生成.o文件;
- step two:创建静态库:

以上就制作完成了,接下来就是介绍一下使用;
4. 静态库的使用
先创建lesson05
calc:是制作静态库要使用的文件;
library:是要去使用刚才制作的静态库(libcalc.a)的一些代码;
把这两个文件,复制到上一级目录下的lesson05文件夹下;(记得 -r 递归去拷贝)
比如说library是我们自己写的项目,开发项目我们会进行分包(分文件夹)
1. 介绍library文件
- include目录下,放的都是要用到的头文件,例如head.h(即calc里面的头文件);
- lib目录(即library):需要使用到的一些库文件;
- main.c:测试文件;
- src目录下:放的都是源代码文件
2. 把libcalc.a库文件放入lib目录下
cp ../calc/libcalc.a ./lib [把calc目录下的libcalc.a 放入当前目录下的lib文件夹中]

分发时,要把头文件和库一起给(若是只有库,没有.h文件,就不知道库里面有什么;头文件里面有函数声明)
3. 编译main.c程序(未加 -I参数会报什么错)
首先会报错,因为预处理的时候,会把head.h里面的内容拷贝到main.c里面进行头文件的展开;但是找不到,因为代码里面#include "head.h"用了相对路径,是指相对当前main.c这个路径,所以找不到head.h(看一下上面的tree结果)
4. 编译main.c程序(加了 -I 参数后会报什么错):-I 指定头文件搜索路径
为什么会报未定义的引用?
在编译的时候,在main.c中用到了libcalc.a库里面的东西,虽然-I提供了头文件,但是具体的函数的定义是在库文件中的,在编译的时候就不会找到,会报错;
5. 编译main.c程序(-l指定加载哪个库,-L指定库搜索路径):注意跟的是库的名称(calc),而不是库文件的名字(libcalc.a)
- 到此为止, 就是静态库的使用了;
- 但是,在静态库的制作过程中,要注意的是,gcc .o文件的时候,要注意给出头文件的搜索路径,前面lesson04举例子能成功,是因为他们在一个目录下;


版权声明:本文为weixin_43306271原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。














