【问题标题】:What is the difference between linking and binding?链接和绑定有什么区别?
【发布时间】:2014-10-04 14:02:24
【问题描述】:

我正在阅读这两件事并感到困惑,两者之间有什么区别?

【问题讨论】:

标签: c++ c linker


【解决方案1】:

绑定是一个在多个上下文中使用的词。它总是与将一件事与另一件事联系起来有关,但是当绑定行为发生时可能会有所不同。

有一个绑定时间的概念,即某个组件绑定到某个其他组件的时间点。绑定时间的基本列表是:(1)编译时绑定,(2)链接时绑定,(3)加载时绑定,(4)运行时绑定。

编译时绑定发生在编译源代码时。对于 C/C++ 有两个主要阶段,预处理器执行源文本替换,例如定义替换或宏替换,以及源文本编译,将源文本转换为机器代码以及链接器的必要指令。

链接时绑定是指外部符号链接到一组特定的目标文件和库。您可能有几个不同的静态库,它们具有相同的函数名称集,但函数的实际实现是不同的。所以你可以通过选择不同的静态库来选择使用哪个库实现。

加载时绑定是加载程序将可执行文件连同任何动态或共享库一起加载到内存中。加载器将函数调用绑定到特定的动态或共享库,并且选择的库可能会有所不同。

运行时绑定是指程序实际运行并根据当前执行线程做出选择。

所以链接实际上只是绑定的一种类型。查看此 stackoverflow static linking vs dynamic linking,它提供了有关链接和库的更多信息。

您可能还对 C++ 中的 std::bind 感兴趣,所以这里有一篇 stackoverflow 文章 std::function and std::bind what are they when they should be used

在某项绑定到其他项之前等待的时间越长,可以为软件的使用方式提供所需程度的灵活性。然而,通常在延迟绑定和运行时效率以及源代码的复杂性之间进行权衡。

以绑定时间为例,考虑一个应用程序,它打开一个文件并从文件中读取,然后关闭它。当文件名绑定到打开的文件时,您可以选择几个不同的时间。

您可以硬编码文件名,在编译时绑定,这意味着它只能用于那个文件。要更改文件名,您必须更改源并重新编译。

您可能有用户输入的文件名,例如使用用户提示符或命令行参数,将文件名绑定到运行时打开的文件。要更改不再需要重新编译的文件名,只需使用不同的文件名再次运行程序即可。

【讨论】:

    【解决方案2】:

    假设你有一个函数声明为:

    void f(int, char);
    

    还有:

    void f(int);
    

    然后您调用具有正确签名的函数 f(4)。这是绑定。 链接器将链接到函数体的可用定义,以便 f 与签名 void f(int); 匹配;

    【讨论】:

      【解决方案3】:

      实际上两者在 c 编程的上下文中具有相同的含义。有些人使用绑定,有些人使用链接。

      如果你想知道什么是链接,那么这里有一个简短的解释。

      假设您创建了一个名为 sum() 的用户定义函数,其声明如下 整数总和(整数,整数); 然后每当从程序调用函数时,您的程序应该知道在内存中跳转到哪里来执行该函数。简单来说,你的程序应该知道被调用函数的地址,才能到达它的主体,这就是所谓的绑定。

      现在 sum 是用户定义的函数,因此它将出现在您的源代码本身中。如果它是从 main() 调用的,那么它将在编译时链接到 main,因为那时编译器会知道你的函数在可执行文件中的位置。这称为静态绑定。

      现在想想 printf() 是库函数,它的主体不存在于您的程序中。所以当程序被编译时,printf 的主体不会出现在你编译的可执行文件中。当您执行程序时,它将被加载到内存中,并且它的地址将在运行时被 main 知道,而不是在 sum() 的情况下在编译时知道。这种类型的链接称为动态链接。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-26
        • 1970-01-01
        • 2010-09-16
        • 2014-12-22
        • 2011-01-03
        • 2012-05-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多