链接
- 符号解析:
原则是:编译器只允许每个模块中每个本地符号只有一个定义。而且对全局的符号的解析很棘手,因为多个目标文件可能会定义相同的符号。C++和Java使用mangling手段来支持重载。
- 根据Unix连接器使用下面的规则来处理多重定义的符号:
-
规则1:不允许有多个强符号。
-
规则2:如果有一个强符号和多个弱符号,那么选择强符号
-
规则3:如果有多个弱符号,那么从这些弱符号中任意选择一个
- 静态库
事先写好的一些可重定位的目标文件打包成一个单独的文件,它可以用作连接器的输入。当连接器构造一个输出的可执行文件时,它只拷贝静态库里被应用程序引用的目标模块
在Unix系统中,静态库以一种成为存档(archive)的特殊文件格式存放在磁盘中。存档文件是一组连接起来的可重定位目标文件的集合。有一个头部用来描述每个成员目标文件的大小和位置。存档文件的后缀是.a标识。是否可以这么理解.a文件的结构呢?
下面用展示一个静态库连接的过程:
- 从应用程序中加载和链接共享库
应用程序还可能从应用程序中加载和链接任意共享库,而无需编译时链接那些库到应用中
Windows中的更新大部分是这个技术。另外还有构建高性能web服务器。
Linux为动态链接器提供了一系列简单的接口:
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);//加载共享库
void *dlsym(void *handle, char *symbol); //指向一个共享库的句柄和一个符号名字。
int dlclose(void *handle); //下载共享库
const char *dlerror(void); //容错