C++动态库和静态库
静态库、动态库均指可复用、可独立功能程序代码的集合。静态库是在链接阶段把库代码包含入可执行文件的方式,动态库是在执行阶段把库代码引入可执行文件的方式。
静态库只需保证在开发者的计算机有正确的库文件,生成的可执行文件体积较大。当初正是为了避免此问题,才开发了动态库技术。各有各的长处,各有各的短肋。针对不同的情况,选择不同的方式吧。
先来回忆一下,从一个程序文件到编译为可执行文件需要这么4步:预编译=》编译 =》 汇编 =》 链接。但是 gcc 一个工具集,把好多功能都集成进去了,对于一些简单的程序只要通过一个命令即可编译为可执行文件。如下:
gcc test.cpp -o test
如何创建、使用这两种库是本文探讨的重点,以下示例是运行在 GNU/Linux。让我们一步步深入理解:
1. 创建一个库源文件 hello.cpp,如下:
char* say() { char *str = "Hello World!"; return str; }
2. 创建一个库头文件 hello.h,如下:
char* say();
3. 编译为对象文件 hello.o,如下:
g++ -c hello.cpp -o hello.o
此命令一步到位,内部包含了预编译、汇编等操作。详细可参考:Ubuntu-Cpp编译
4.1 创建动态库 libhello.so,如下:
g++ -shared hello.o -o libhello.so
4.2 创建静态库 libhello.a,如下:
ar -cr libhello.a hello.o
5.1 创建测试源文件 test.cpp,如下:
#include <iostream> #include "hello.h" using namespace std; int main() { cout << say() <<endl; return 0; }
5.2 编译测试源文件为 test(使用静态库),如下:
g++ -static test.cpp -L ./ -I ./ -l hello -o test5.3 验证一下结果:
[root@localhost libhello]# ./test Hello World!
5.4 编译测试源文件为 test (使用动态库),如下:
g++ test.cpp -L ./ -I ./ -l hello -o test -Wl,-rpath=./
-Wl,-rpath=./ 指在当前目录查找 libhello.so
5.5 验证一下结果:
[root@localhost libhello]# ./test Hello World!
备注:
1. 动态库、静态库 名称有一定的讲究,格式为:libxxx.so / libxxx.a
2. ldd 可以查看二进制文件中对动态库的引用情况
3. nm 可以查看二进制文件中的函数列表信息