一尘不染

“静态链接”和“动态链接”是什么意思?

c#

我经常听到术语“静态链接”和“动态链接”,通常是指用CC
++
C#编写的代码。他们是什么人,他们到底在说什么,他们有什么联系?


阅读 502

收藏
2020-05-19

共1个答案

一尘不染

从源代码(您编写的内容)到可执行代码(您运行的内容)有两个阶段(在大多数情况下,对解释代码进行打折)。

首先是编译,它将源代码转换为目标模块。

第二个链接是将对象模块组合在一起以形成可执行文件的链接。

区别在于:允许第三方库包含在您的可执行文件中,而您无需查看它们的源代码(例如用于数据库访问,网络通信和图形用户界面的库),或用于编译不同语言的代码(
C和汇编代码),然后将它们链接在一起。

当您将文件 静态 链接到可执行文件时,该文件的内容将在链接时包括在内。换句话说,文件的内容实际上已插入到将要运行的可执行文件中。

动态 链接时,可执行文件中将包含指向要链接的文件的指针(例如,文件的文件名),而链接时不包含该文件的内容。只有在以后 运行
可执行文件时,这些动态链接的文件才被购买,并且它们仅被购买到可执行文件的内存副本中,而不是磁盘上的副本。

基本上,这是一种延迟链接的方法。还有一个 延迟的方法(在某些系统上称为“后期绑定”),在您实际尝试在其中调用函数之前,不会引入动态链接的文件。

静态链接的文件在链接时被“锁定”到可执行文件,因此它们永远不会改变。可执行文件引用的动态链接文件仅通过替换磁盘上的文件即可更改。

这样就可以更新功能,而不必重新链接代码。每次运行时,加载程序都会重新链接。

这既有好处也有坏处-一方面,它允许更容易的更新和错误修复,另一方面,如果更新不兼容,则可能导致程序停止工作-这有时是造成某些人可怕的“
DLL地狱”的原因其中提到,如果用不兼容的库替换动态链接的库,应用程序可能会损坏(顺便说一下,这样做的开发人员应该被追捕并受到严厉的惩罚)。


作为 示例 ,让我们看一下用户编译main.c文件以进行静态和动态链接的情况。

Phase     Static                    Dynamic
--------  ----------------------    ------------------------
          +---------+               +---------+
          | main.c  |               | main.c  |
          +---------+               +---------+
Compile........|.........................|...................
          +---------+ +---------+   +---------+ +--------+
          | main.o  | | crtlib  |   | main.o  | | crtimp |
          +---------+ +---------+   +---------+ +--------+
Link...........|..........|..............|...........|.......
               |          |              +-----------+
               |          |              |
          +---------+     |         +---------+ +--------+
          |  main   |-----+         |  main   | | crtdll |
          +---------+               +---------+ +--------+
Load/Run.......|.........................|..........|........
          +---------+               +---------+     |
          | main in |               | main in |-----+
          | memory  |               | memory  |
          +---------+               +---------+

在静态情况下,您可以看到主程序和C运行时库在链接时(由开发人员)链接在一起。由于用户通常无法重新链接可执行文件,因此他们被库的行为所困扰。

在动态情况下,主程序与C运行时导入库(声明动态库中的内容但未实际 定义的 内容)链接在一起。即使实际的代码丢失,这也允许链接器链接。

然后,在运行时,操作系统加载程序将主程序与C运行时DLL(动态链接库或共享库或其他命名法)进行后期链接。

C运行时的所有者可以随时插入新的DLL,以提供更新或错误修复。如前所述,这具有优点和缺点。

2020-05-19