1 概念
1.1 静态库
一般扩展名为( .a
或 .lib
),这类函数库通常名为libxxx.a
或xxx.lib
。
这类库在编译的时候会直接整合到目标程序中,所以利用静态函数库编译成的文件会比较大,这类函数库最大的优点就是编译成功的可执行文件可以独立运行,而不在需要向外部要求读取函数库的内容。
1.2 动态库
动态函数库的扩展名一般为( .so
或 .dll
),这类函数库通常名为libxxx.so
或xxx.dll
动态库是程序设计常用的技术。采用动态库可以有效的减少程序大小、节省空间、提高效率。增加程序的可扩展性。便于模块化管理。在Windows和Linux操作系统中都有动态库的概念。Windows将其称为动态链接库(Dvnamic Link Library. DLL),其文件扩展名.dll,Linux称其为共享库技术(Shared Library),相应的共享库文件扩展名为.so。
动态函数库在编译的时候,在程序里只有一个“指向”的位置而已,也就是说当可执行文件需要使用到函数库的机制时,程序才会去读函数库来使用。
1.3 动态库链接
动态库在程序运行的时候被动态链接。但是在具体使用动态库的时候却有两种不同的方式:隐式链接和显式链接。
1.3.1 隐式链接
隐式链接在编译/链接阶段完成,由编译系统根据动态库的头文件和库文件进行编译和链接。从而确定待调用的函数原形和地址。
1.3.2 显式链接
利用API函数实现加载和卸载共享库,获取带调用函数地址,获取错误信息等功能。
2 dlfcn.h
#include<dlfcn.h>
/* 打开一个动态链接库
* pathname:动态库的名称
* mode:动态库的打开方式
* RTLD_NOW:将共享库中的所有函数加载到内存
* RTLD_LAZY:会推后共享库中的函数的加载操作,直到调用dlsym()时方加载某函数
* return:返回一个句柄给进程,打开错误返回NULL
*/
void *dlopen(const char *pathname, int mode);
/* handle:打开动态链接库后返回的句柄
* symbol:需要获取的函数的名称
* return:指向函数的地址
*/
void *dlsym(void *handle, const char* symbol);
/*dlerror返回NULL或者一个指向描述最近错误的ASCII字符串指针*/
char *dlerror(void);
/*关闭句柄并且取消共享目标文件的映射*/
int dlclose(void *handle);
有的代码可能用到了两个特殊的函数 __init和__fini。这两个函数用在装载和卸载某个动态库的时候。
void __init(void);/*dlopen打开动态库,调用__init()*/
void __fini(void);/*dlclose关闭动态库,调用__fini()*/