技术共享

链接器的工作原理,静态链接与动态链接的区别,如何创建和使用动态链接库

2024-07-08

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

链接器在程序开发中的作用至关重要,它负责将多个目标文件和库文件整合成一个可以执行的文件。在深入了解链接器的工作原理、静态链接与动态链接的区别,以及如何创建和使用动态链接库之前,我们先来概述一下链接器的基本功能。

链接器的工作原理

链接器(Linker) 是负责将一个或多个目标文件与库文件组合成一个可执行文件的工具。其主要功能包括:

  1. 符号解析:识别并处理程序中所有的符号(函数和变量的名称),确保每个符号都有唯一的定义。对于引用但未定义的符号(外部符号),链接器会在提供的库或其他目标文件中查找定义。

  2. 重定位:将每个模块中的代码和数据地址调整到最终的内存地址。重定位包括代码中的地址修正和数据段的位置调整,以保证所有引用指向正确的内存位置。

  3. 合并段:将来自不同目标文件的相同类型的段(如代码段、数据段等)合并成一个连续的段。

  4. 处理库:将程序需要的库代码与目标文件链接在一起。链接器可以处理两种类型的库:静态库和动态库。

  5. 生成可执行文件:最终输出一个可以在操作系统上运行的可执行文件。

静态链接与动态链接的区别

静态链接(Static Linking)动态链接(Dynamic Linking) 是链接器的两种工作模式,它们各自有不同的特点和使用场景。

静态链接
  • 概念:在静态链接中,库代码在编译时被复制并嵌入到每个使用它的可执行文件中。这样,生成的可执行文件包含所有需要的代码,不依赖外部的库文件。

  • 优点

    • 独立性强:生成的可执行文件包含所有依赖,不需要在运行时额外的库文件。
    • 兼容性好:运行时不依赖于系统中安装的库版本,不会遇到“库版本冲突”问题。
  • 缺点

    • 文件体积大:每个可执行文件都包含完整的库代码,导致文件体积增大。
    • 更新麻烦:如果库有更新,需要重新编译所有使用该库的程序。
  • 静态库的扩展名

    • Windows: .lib
    • Unix/Linux: .a
动态链接
  • 概念:在动态链接中,库代码在运行时加载,不嵌入到可执行文件中。可执行文件只包含对库的引用,库代码在运行时由操作系统加载。

  • 优点

    • 文件体积小:可执行文件不包含库代码,只包含对库的引用。
    • 易于更新:更新库不需要重新编译程序,只需替换库文件。
    • 内存效率高:多个程序可以共享同一个库文件的内存实例,减少内存使用。
  • 缺点

    • 依赖性强:可执行文件在运行时需要能够找到并加载正确版本的库文件。
    • 兼容性问题:库文件版本不匹配可能导致程序运行失败。
  • 动态库的扩展名

    • Windows: .dll(Dynamic-Link Library)
    • Unix/Linux: .so(Shared Object)

创建和使用动态链接库

创建动态链接库

在不同的操作系统上,创建动态链接库的方法略有不同。以下是一些常见的步骤和命令:

在 Linux 上创建动态链接库
  1. 编写库代码

    创建一个C 源文件,包含我们要放在动态库中的函数。

    // example.cpp
    #include