【问题标题】:difference between dynamic loading and dynamic linking?动态加载和动态链接的区别?
【发布时间】:2012-04-20 14:26:14
【问题描述】:

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

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

【问题讨论】:

    标签: dynamic linker operating-system loading


    【解决方案1】:

    此答案假设您了解基本的 Linux 命令。

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

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

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

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

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

    摘自维基百科:

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

    如果您仍然感到困惑,请先阅读这篇很棒的文章:Anatomy of Linux dynamic libraries 并构建 dynamic loading example 以了解它,然后再回到这个答案。

    这是我的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 的动态可执行文件,当您运行dl 时,它由ld.so 动态链接,Linux 动态链接器。列表中的其他 3 个库也是如此。

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

    【讨论】:

      【解决方案2】:

      动态加载是指在加载或运行时将库(或任何其他二进制文件)加载到内存中。

      可以将动态加载想象成类似于插件,即一个exe可以在动态加载发生之前实际执行(例如动态加载可以使用C或C++中的LoadLibrary调用来创建)

      动态链接是指在加载或运行时而不是在创建 exe 时完成的链接。

      如果在创建 exe 时动态链接链接器所做的工作最少。要使动态链接器工作,它实际上也必须加载库。因此它也称为链接加载器。

      因此,您引用的句子可能是有道理的,但它们仍然很模糊,因为我们无法推断出它所指的上下文。您能告诉我们您在哪里找到这些句子以及作者在什么上下文中谈论的吗?

      【讨论】:

      • 这些句子在著名的 Silberschatz、Galvin、Gagne 操作系统一书中的内存管理章节中
      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

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

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

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

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

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

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

            语句不完整。“主程序被加载到主存中并被执行。”没有指定何时加载程序。

            如果我们认为它在调用时加载为1st 语句 指定那么它的动态加载

            【讨论】:

            • 如何在执行时间之前调用例程? (我假设执行时间是指运行时间,还是有区别?)
            • 是的,调用发生在执行时间之前是没有意义的,除非你的意思是调用发生在源代码中。
            【解决方案7】:

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

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

            优势

            1. 永远不会加载未使用的例程。这在程序代码中最有用 很大,需要处理不经常发生的情况,例如 错误例程。在这种情况下,虽然程序代码很大,但使用的代码 会很小。
            2. 动态加载不需要操作系统的特殊支持。 用户有责任设计他们的程序以利用 方法。不过,O.S 可以提供库来帮助程序员

            【讨论】:

              【解决方案8】:

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

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

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-02-08
                • 2012-04-16
                • 2011-01-04
                • 2011-05-08
                • 2013-06-19
                • 1970-01-01
                • 2010-10-07
                相关资源
                最近更新 更多