此文转自吴秦先生的C++静态库与动态库。对吴先生此博文只想说,实在是太精彩了!
1. 什么是库
库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。
所谓静态、动态是指链接。回顾一下,将一个程序编译成可执行程序的步骤:
图:编译过程
2. 静态库
之所以成为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。
静态库特点总结:
[1] 静态库对函数库的链接是放在编译时期完成的。
[2] 程序在运行时与函数库再无瓜葛,移植方便。
[3] 浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
下面编写一些简单的四则运算C++类,将其编译成静态库给他人用,头文件如下所示:
1 // StaticMath.h头文件 2 #pragma once 3 4 class StaticMath 5 { 6 public: 7 StaticMath(void); 8 ~StaticMath(void); 9 10 static double add(double a, double b);//加法 11 static double sub(double a, double b);//减法 12 static double mul(double a, double b);//乘法 13 static double div(double a, double b);//除法 14 15 void print(); 16 };
Linux下使用ar工具、Windows下vs使用lib.exe,将目标文件压缩到一起,并且对其进行编号和索引,以便于查找和检索。一般创建静态库的步骤如图所示:
图:创建静态库过程
2.1 Linux下创建与使用静态库
2.1.1 Linux静态库命名规则
Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为.a。
2.1.2 创建静态库(.a)
通过上面的流程可以知道,Linux创建静态库过程如下:
[1] 首先,将代码文件编译成目标文件.o(StaticMath.o)
g++ -c StaticMath.cpp
[2] 然后,通过ar工具将目标文件打包成.a静态库文件注意带参数-c,否则直接编译为可执行文件
ar -crv libstaticmath.a StaticMath.o
生成静态库libstaticmath.a。
大一点的项目会编写makefile文件(CMake等等工程管理工具)来生成静态库,输入多个命令太麻烦了。
2.1.3 使用静态库
编写使用上面创建的静态库的测试代码:
1 // 测试代码: 2 #include "StaticMath.h" 3 #include <iostream> 4 using namespace std; 5 6 int main(int argc, char* argv[]) 7 { 8 double a = 10; 9 double b = 2; 10 11 cout << "a + b = " << StaticMath::add(a, b) << endl; 12 cout << "a - b = " << StaticMath::sub(a, b) << endl; 13 cout << "a * b = " << StaticMath::mul(a, b) <&