我一直想知道。我知道编译器会将您编写的代码转换为二进制文件,但链接器是做什么的?他们对我来说一直是个谜。
我大致了解什么是“链接”。这是对库和框架的引用被添加到二进制文件中的时候。我不明白除此之外的任何事情。对我来说,它“有效”。我也了解动态链接的基础知识,但没有太深。
有人可以解释这些条款吗?
要了解链接器,首先要了解当您将源文件(例如 C 或 C++ 文件)转换为可执行文件(可执行文件是可以在您的机器上执行的文件或其他人的机器运行相同的机器架构)。
在后台,当程序被编译时,编译器将源文件转换为目标字节码。此字节码(有时称为目标码)是只有您的计算机体系结构才能理解的助记指令。传统上,这些文件具有 .OBJ 扩展名。
创建目标文件后,链接器开始发挥作用。通常,一个真正的程序做任何有用的事情都需要引用其他文件。例如,在 C 语言中,将您的姓名打印到屏幕上的简单程序将包括:
printf("Hello Kristina!\n");
当编译器将你的程序编译成一个 obj 文件时,它只是简单地引用了该printf函数。链接器解析此引用。大多数编程语言都有一个标准的例程库来涵盖该语言所期望的基本内容。链接器将您的 OBJ 文件与此标准库链接。链接器还可以将您的 OBJ 文件与其他 OBJ 文件链接。您可以创建具有可由另一个 OBJ 文件调用的功能的其他 OBJ 文件。链接器的工作方式几乎类似于文字处理器的复制和粘贴。它“复制”出程序引用的所有必要函数并创建一个可执行文件。有时,复制出来的其他库依赖于其他 OBJ 或库文件。有时,链接器必须非常递归才能完成其工作。
printf
请注意,并非所有操作系统都创建单个可执行文件。例如,Windows 使用 DLL 将所有这些功能放在一个文件中。这会减小可执行文件的大小,但会使可执行文件依赖于这些特定的 DLL。DOS 曾经使用称为覆盖(.OVL 文件)的东西。这有很多目的,但一个是将常用的功能放在一个文件中(如果您想知道,它的另一个目的是能够将大型程序放入内存中。DOS 在内存方面存在限制,并且覆盖可以从内存中“卸载”,其他覆盖可以“加载”在该内存之上,因此名称为“覆盖”)。Linux 有共享库,这与 DLL 基本相同(我认识的 Linux 硬核人士会告诉我有很多很大的不同)。
希望这可以帮助您理解!