- 作用
- 分离编译
- 代码重用
- 分类
分类 | 作用 | 后缀Linux/Windows |
---|---|---|
静态库 | 一个或多个.o 目标文件归档在一个文件中 | .a / .lib |
共享库 | 没有main 函数的可执行文件 | .so / ./dll |
动态加载库 | 没有main 函数的可执行文件,接口复合API | .so / .dll |
库
库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a
、.lib
)和动态库(.so
、.dll
)。
所谓静态、动态是指链接。
将一个程序编译成可执行程序的步骤:
0.前提(文件内容)
- test.cpp
#include <iostream>
#include "test.h"
using namespace std;
void Func(int i){
cout << __func__ << "(" << i << ")" << endl;
}
- test.h
#ifndef __TEST_H_
#define __TEST_H_
void Func(int i);
#endif
- main.cpp
#include "test.h"
int main(){
Func();
return 0;
}
1 静态库
1.1静态库是什么
之所以称为“静态库”,是因为在链接阶段,会将汇编生成的目标文件.o
与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
静态库与汇编生成的目标文件一起链接为可执行文件,静态库必定跟.o
文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj
文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。
1.2 静态库特点:
-
静态库对函数库的链接在编译时期完成。
-
程序在运行时与函数库无关了,移植方便。
-
缺点:浪费空间和资源(所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件)。
1.3 静态库的制作与使用
1.3.1 Linux:
1.3.1.1 创建静态库
- Linux静态库命名规则
Linux静态库命名规范,必须是lib名字.a
:lib
为前缀,中间是静态库名,扩展名为.a
。 - 编译源文件
g++ -c -o test.o test.cpp
- 生成静态库
ar -rcs libtest.a test.o
ar
选项
命令选项 | 作用 |
---|---|
r | 替换模块(replace) |
c | 创建库(create) |
s | 建立索引 |
tar
和ar
都是归档工具
tar
用于创建.tar
归档文件。ar
用于创建归档文件,并且为归档的目标文件中的符号建立索引。
- 查看目标文件的符号(symbol)信息
nm 目标文件
目标文件可以是.o
、.a
,也可以是可执行文件。
1.3.1.2 使用静态库
Linux下使用静态库,只需要在编译的时候,指定静态库的搜索路径(-L静态库的路径)、指定静态库名(不需要lib
前缀和.a
后缀,-l静态库名)。
- 链接静态库
g++ -o main main.cpp -L. -ltest
或者
g++ -o main main.cpp ./libtest.a
-
-L
:表示要连接的库所在目录 -
-l
:指定链接时需要的库,编译器查找库时有隐含的命名规则,即在给出的名字前面加上lib
,后面加上.a
或.so
来确定库的名称。
注意:库一定要放在命令行的末尾
- 测试
./main
- 结果
Func(100)
1.3.2 windows
1.3.2.1 创建静态库
使用VS
命令行生成静态库,分两步:
-
通过使用带编译器选项 /c 的 Cl.exe 编译代码 (
cl /c main.cpp
),创建名为main.obj
的目标文件。 -
使用库管理器 Lib.exe 链接代码 (
lib main.obj
),创建静态库main.lib。
当然一般不这么用,使用VS工程设置更方便。创建win32控制台程序时,勾选静态库类型;打开工程**“属性面板”->”配置属性”->”常规”,配置类型选择静态库**。
Build
项目即可生成静态库。
1.3.2.2 使用静态库
测试代码Linux下面的一样。有3种使用方法:
方法一:
在VS中使用静态库方法:
-
工程“属性面板”->“通用属性”->“框架和引用”->”添加引用”,将显示“添加引用”对话框。 “项目”选项卡列出了当前解决方案中的各个项目以及可以引用的所有库。 在“项目”选项卡中,选择要使用的静态库。 单击“确定”。
-
添加.h 头文件目录,必须修改包含目录路径。打开工程“属性面板”->”配置属性”-> “C/C++”->” 常规”,在“附加包含目录”属性值中,键入.h 头文件所在目录的路径或浏览至该目录。
编译运行OK。
如果引用的静态库不是在同一解决方案下的子工程,而是使用第三方提供的静态库lib和头文件,上面的方法设置不了。还有2中方法设置都可行。
方法二:
打开工程“属性面板”->”配置属性”->“链接器”->”命令行”,输入静态库的完整路径即可。
方法三:
-
“属性面板”->”配置属性”-> “链接器”->”常规”,附加依赖库目录中输入,静态库所在目录;
-
“属性面板”->”配置属性”-> “链接器”->”输入”,附加依赖库中输入静态库名.lib。