linux 静态链接和动态链接

  • 链接

一个可执行目标文件的生成需要经过预编译(g++ -E)、编译(g++ -S)、汇编(g++ -c)、链接四个步骤。链接是将多个可重定位目标文件合并到一个目标文件的过程。链接由链接器完成,链接器重要完成两个任务:

1、符号(符号表由汇编器构造)解析。也就是将符号引用和符号定义关联起来。其中符号定义和符号引用可能不在同一个目标文件中。而且链接器对多重定义的全局符号的解析有一定的规则:不允许有多个同名强符号(函数和初始化了的全局变量)、如果有一个强符号和多个弱符号同名选择强符号、如果有多个弱符号随机选择一个。

2、重定位。包括将不同可重定位目标文件的相应的节合并为一个节,以及重定位符号引用,使得对符号的引用都指向正确的运行时地址。

  • 静态链接

1、生成静态库

# g++ -c a.cc b.cc

# g++ ar rcs libab.a a.o b.o

# g++ -static -o prog main.o ./libab.a

通过以上形式,可以将多个目标模块打包成一个单独的文件,称为静态库。与静态库链接时,只复制被程序引用的目标模块,但是有一点需要注意:在链接形成最终的可执行文件时,命令行中文件出现的顺序必须正确。即符号定义必须出现在符号引用之后。所以库一般放在命令行的最后。

静态链接具有以下缺点:

多个进程引用相同的目标模块,则在内存上会有多个副本,从而浪费内存

如果静态库有更新,则需要重新链接。

  • 动态链接

动态链接分为加载时链接和运行时链接。

加载时链接,在链接阶段链接器会复制一些重定位和符号表信息,而在加载时重定位动态库的文本和数据到一个内存段,有多个进程使用同一个动态库时,将使用内存映射的方法共享代码和数据,并且内存中只有一份副本。以以下形式创建一个动态链接:

# g++ -shared -fpic -o libab.so a.c b.c

运行时链接则是通过显示调用系统函数的方式。

运行时链接

原文地址:https://www.cnblogs.com/coderht/p/7197899.html