C++的静态库与动态库

在实际开发中,我们把通用的函数和类分文件编写,称之为库。在其他的程序中,可以使用库中的函数和类。
一般来说,通用的函数和类不提供源代码文件(涉及到安全性和商业机密等问题),而是编译成二进制文件。
库的二进制文件有两种:静态库和动态库。

一、静态库

(1) 制作静态库

1
2
3
4
5
g++  -c  -o  lib库名.a  [源代码文件清单] 

-c 表示制作静态库
[lib库名.a] 为静态库文件名,如libpublic.a,库名为public

(2) 使用静态库

不规范做法:

1
2
3
4
g++  [编译选项]  [源代码文件清单]  lib库名.a

例如:
g++ -o demo demo.cpp /home/dk/test/libpublic.a

规范做法:

1
2
3
4
g++  [编译选项]  [源代码文件清单]  -l库名  -L静态库所在的目录名

例如:
g++ -o demo demo.cpp -lpublic -L/home/dk/test/

(3) 静态库的概念

程序在编译时会把库文件的二进制文件链接到目标程序中,这种方式称为静态链接
如果多个程序中用到同一静态库中的函数,就会存在多份拷贝。

(4) 静态库的特点

1、静态库的链接是在编译时期完成的,执行的时候代码加载速度快
2、目标程序的可执行文件比较大,浪费空间。
3、程序的更新和发布不方便,如果某一个静态库更新了,所有使用他的程序都需要重新编译。

二、动态库

制作动态库

1
2
3
g++  -fPIC  -shared  -o  lib库名.so  [源代码文件清单]

-fPIC -shared 表示制作动态库

使用动态库

不规范做法:

1
2
3
4
g++  [编译选项]  [源代码文件清单]  lib库名.so

例如:
g++ -o demo demo.cpp /home/dk/test/libpublic.so

规范做法:

1
2
3
4
g++  [编译选项]  [源代码文件清单]  -l库名  -L动态库所在的目录名

例如:
g++ -o demo demo.cpp -lpublic -L/home/dk/test/

运行可执行程序时,需要提前设置 LD_LIBRARY_PATH 环境变量的值

1
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:/动态库的路径

动态库的概念

程序在编译时不会把库文件的二进制代码链接到目标程序中,而是在运行的时候载入。
如果多个程序中用到同一动态库中的函数,那么在内存中只有一份,避免了空间的浪费。

动态库的特点

1、程序运行的过程中,需要用到动态库的时候才把动态库的二进制代码载入内存。
2、可以实现进程间的代码共享,因此动态库也称为共享库。
3、程序升级比较简单,不需要重新编译程序,只需要更新动态库即可。

三、优先使用动态库

如果动态库和静态库同时存在,编译器会优先使用动态库。