静态链接和动态链接

静态链接是在编译期间解决不同模块间的通信问题,包括函数调用和符号解析,将编译后的目标文件组合成可执行文件。而动态链接则在运行时确定函数入口地址,常用于多态场景。静态链接处理符号解析和重定位,动态链接则涉及虚函数调用。两者分别在编译和运行阶段起作用。
摘要由CSDN通过智能技术生成

静态链接要解决的事情

现代的大型软件动辄几百万行的代码,如果我们把所有的代码放在同一个main.c文件中,我想在后期寻找bug和维护的时候,一定是一个头疼的事情。最常用的结局方法便是使用不同的模块来完成一个功能,然后把这些模块拼接起来,组成一个完整的应用程序。所以,静态链接就是用来解决不同模块之间的通信问题:
1.不同模块之间的函数调用;
2.不同模块之间的函数调用;一个完整程序的模块组成
一个复杂的软件就是把全部分成一个小系统来进行处理,把每个模块的源代码进行独立的编译,然后通过静态链接组装起来,链接就是整个组装模块的过程,链接的主要内容就是把各个模块之间相互引用的部分处理好,使得整个模块能够正确的链接。
链接的过程主要包括三部分:
1.地址和空间分配;
2.符号决议;
3.重定位;
值得注意的是,链接针对的是目标文件(.o),所以源代码必须经过编译之后形成目标文件和库(Library)一起链接最终形成一个用户可以执行的可执行文件(.exe)。

链接的过程

其实很简单,对于main.c中的函数想调用test.c中的test()函数,则必须每次调用test()的时候都得知道此函数的地址。但是因为每个模块的编译是分开进行的,所以肯定无法及时知道不同模块的函数地址;所以暂时把调用此函数的指令的目标地址搁置,等待最后链接的时候通过链接器修改这些指令的目标地址。这个修改目标地址的操作也是上文提到的重定位。这也就完成了不同模块之间的引用和通信问题;

地址和空间分配

***链接之后的可执行文件中的代码段和数据段都是由输入的目标文件合并来的。***所以将所有的输入的目标文件的.bss合并在一起,.data合并在一起,.text合并在一起;这个过程也分为了两步:

  1. 空间和地址分配
    扫描不同目标文件各个段的长度等信息,链接器获取到所有输入目标文件的段长度,分别合并不同的段,计算合并之后的位置和长度,建立映射关系;
  2. 符号解析和重定位
    读取输入文件中段的信息、重定位信息,并且警醒符号解析和重定位,以及调整代码中的地址;值得注意的是,链接之前的目标文件的所有段的虚拟地址都是0。

动态链接

动态链接主要指的是,必须在程序的运行阶段才能确定函数的入口地址,也就是具体使用哪个函数。动态链接通常出现在多态的使用场景中。通常是用基类指针指向派生类对象时,调用虚函数时,就可以发生动态链接,在函数运行阶段通过虚函数指针指向虚表来找到函数的入口地址从而确定到底使用哪一个函数。这就是动态链接。
简单总结:
静态链接发生在编译时期;
动态链接发生在运行阶段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值