33

例程在被调用之前不会加载。所有例程都以可重新定位的加载格式保存在磁盘上。主程序被加载到内存中并被执行。这称为动态链接。

为什么这称为动态链接?它不应该是动态加载,因为在动态加载中调用例程之前不会加载例程,而在动态链接中,链接推迟到执行时间。

4

8 回答 8

29

这个答案假设您知道基本的 Linux 命令。

在 Linux 中,有两种类型的库:静态库或共享库。

在此处输入图像描述

为了调用静态库中的函数,您需要将库静态链接到可执行文件中,从而生成静态二进制文件。

在共享库中调用函数时,您有两种选择。

第一个选项是动态链接,这是常用的 - 在编译可执行文件时,您必须指定程序使用的共享库,否则它甚至不会编译。当您的程序启动时,系统会负责打开这些库,这些库可以使用ldd命令列出。

另一个选项是动态加载——当你的程序运行时,打开那个库是程序的工作。此类程序通常与 libdl 链接,它提供了打开共享库的能力。

摘自维基百科:

动态加载是一种机制,计算机程序可以在运行时将库(或其他二进制文件)加载到内存中,检索库中包含的函数和变量的地址,执行这些函数或访问这些变量,并卸载记忆中的图书馆。它是计算机程序可以使用其他软件的三种机制之一;另外两个是静态链接和动态链接。与静态链接和动态链接不同,动态加载允许计算机程序在没有这些库的情况下启动,以发现可用的库,并可能获得额外的功能。

如果您仍然感到困惑,请先阅读这篇很棒的文章:剖析 Linux 动态库并构建动态加载示例以了解它,然后再回到这个答案。

这是我的输出ldd ./dl

linux-vdso.so.1 =>  (0x00007fffe6b94000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f400f1e0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f400ee10000)
/lib64/ld-linux-x86-64.so.2 (0x00007f400f400000)

如您所见,dl它是一个动态可执行文件libdl,它ld.so在您运行时由 Linux 动态链接器动态链接dl。列表中的其他 3 个库也是如此。

libm未显示在此列表中,因为它用作动态加载的库。直到ld被要求加载它才会加载。

于 2017-08-30T11:58:46.163 回答
20

Dynamic loading means loading the library (or any other binary for that matter) into the memory during load or run-time.

Dynamic loading can be imagined to be similar to plugins , that is an exe can actually execute before the dynamic loading happens(The dynamic loading for example can be created using LoadLibrary call in C or C++)

Dynamic linking refers to the linking that is done during load or run-time and not when the exe is created.

In case of dynamic linking the linker while creating the exe does minimal work.For the dynamic linker to work it actually has to load the libraries too.Hence it's also called linking loader.

Hence the sentences you refer may make sense but they are still quite ambiguous as we cannot infer the context in which it is referring in.Can you inform us where did you find these lines and at what context is the author talking about?

于 2012-04-07T07:30:38.973 回答
10

动态加载是指在启动后将可执行文件或库映射(或较少复制)到进程的内存中。动态链接是指在编译后解析符号——将它们的名称与地址或偏移量相关联。

这是 quora 上 Jeff Darcy 的完整答案的链接

http://www.quora.com/Systems-Programming/What-is-the-exact-difference-between-Dynamic-loading-and-dynamic-linking/answer/Jeff-Darcy

于 2014-02-03T03:15:59.063 回答
7

我也在阅读“恐龙书”,对加载和链接的概念感到困惑。以下是我的理解:

  1. 动态加载和链接都发生在运行时,并将所需的任何内容加载到内存中。

  2. 主要区别在于动态加载检查例程是否由加载程序加载,而动态链接检查例程是否在内存中

  3. 因此,对于动态链接,在内存中只有一份库代码,对于动态加载可能不是这样。这就是为什么动态链接需要操作系统支持来检查其他进程的内存。这个特性对于许多程序共享的语言子程序库来说非常重要。

于 2016-10-12T15:27:49.677 回答
2

动态链接器是一个运行时程序,它在开始执行程序之前加载和绑定程序的所有动态依赖项。动态链接器将找到程序需要哪些动态库,这些库需要哪些库(等等),然后它将加载所有这些库并确保对函数的所有引用都正确指向正确的位置。例如,即使是最基本的“hello world”程序通常也需要 C 库来显示输出,因此动态链接器将在加载 hello world 程序之前加载 C 库,并确保对 printf() 的任何调用都执行到正确的代码。

于 2013-07-13T12:32:46.487 回答
1

Dynamic Loading:在调用时将例程加载到主存储器中。

Dynamic Linking:在执行期间将例程加载到主存中,如果调用发生在执行时间之前,则推迟到执行时间。

动态加载不需要操作系统的特殊支持,程序员有责任检查要加载的例程是否存在于主存中。

动态链接需要操作系统的特殊支持,通过动态链接加载的例程可以在各个进程之间共享。

例程在被调用之前不会加载。所有例程都以可重新定位的加载格式保存在磁盘上。主程序被加载到内存中并被执行。这称为动态链接。

声明不完整。“主程序被加载到主存中并被执行。” 未指定何时加载程序。

如果我们认为它是按第1语句指定的调用时加载的,那么它的动态加载

于 2015-05-16T06:39:46.233 回答
1

我们使用动态加载来实现更好的空间利用率

  • 使用动态加载,程序在被调用之前不会被加载所有例程都以可重定位加载格式保存在磁盘上。主程序被加载到内存中并被执行。
  • 当一个例程需要调用另一个例程时,调用例程首先检查是否已加载。如果没有,则调用可重定位链接加载器将所需的例程加载到内存中并更新程序的地址表以反映这种变化。然后控制是传递给新加载的例程

优点

  1. 永远不会加载未使用的例程。这在程序代码很大时最有用,其中需要处理不经常发生的情况,例如错误例程。在这种情况下,尽管程序代码很大,但使用的代码会很小。
  2. 动态加载不需要 OS 的特殊支持。用户有责任设计自己的程序以利用方法。但是,OS 可以提供库来帮助程序员
于 2017-11-03T16:26:53.893 回答
0

有两种类型的链接静态和动态,当输出文件在运行时执行时没有任何依赖项(文件=库),这种类型的链接称为静态,其中动态有两种类型 1.动态加载链接 2.动态运行时链接.这些描述如下

动态链接是指在运行时链接,其中库文件被带到主内存并链接..(无论函数调用如何,这些都是链接的)。

动态运行时链接是指在需要时链接,这意味着无论何时发生函数调用,都在运行时链接..并非所有函数都被链接,这在代码编写中有所不同。

于 2014-02-25T11:07:28.273 回答