C++ 静态库与动态库

库(library)是为多个程序复用而打包的代码集合。典型的 C++ 库由两部分组成:

  • 头文件:声明库向使用者暴露(提供)的功能;
  • 预编译二进制文件:将该功能预先编译为机器码的实现。

某些库可能拆分为多个文件,或包含多个头文件。

库被预先编译的原因如下:

  1. 库通常不常改动,不必每次编写使用它的程序都重新编译,否则浪费时间;
  2. 预编译的目标文件为机器码,可防止他人访问或修改源代码,这对出于知识产权考虑不愿公开源码的商业机构或个人尤为重要。

库分为两类:静态库与动态库。

静态库(又称归档库,archive)

静态库中的例程在编译时被直接编译并链接到最终可执行文件中。当编译使用静态库的程序时,程序所用到的全部静态库功能都会成为可执行文件的一部分。

  • Windows 下静态库扩展名通常为 .lib;
  • Linux 下通常为 .a(archive)。

优点:

  • 仅需分发可执行文件即可让用户运行程序;
  • 由于库已嵌入程序,确保始终使用正确版本;
  • 与自行编写的功能一样,可直接调用。

缺点:

  • 每个可执行文件都含一份库副本,导致空间浪费;
  • 升级困难——更新库时必须替换整个可执行文件。

动态库(又称共享库,shared library)

动态库中的例程在运行时才被加载到应用程序中。编译使用动态库的程序时,库并不并入可执行文件,而是保持独立。

  • Windows 下扩展名通常为 .dll(dynamic link library);
  • Linux 下通常为 .so(shared object)。

优点:

  • 多个程序可共享同一份库,节省磁盘与内存;
  • 可在不替换所有依赖程序的情况下,单独升级动态库。

由于动态库未在编译期链接,使用它们的程序必须显式加载并与动态库交互,机制复杂,接口不便。为简化使用,可借助导入库(import library)。

导入库是一种自动完成动态库加载与调用的库。

  • Windows 中,通常由与动态库同名的静态库(.lib)充当;该静态库在编译期链接到程序,之后即可像使用静态库一样调用动态库功能。
  • Linux 中,.so 文件本身兼具动态库与导入库角色;多数链接器在创建动态库时可同时生成导入库。

库的安装与使用

了解库的种类后,以下介绍如何在程序中使用库。C++ 库的安装通常分四步:

  1. 获取库
    优先下载操作系统对应的预编译包,避免自行编译。若无预编译包,则需下载源码自行编译(本节不展开)。

    • Windows:库通常以 .zip 形式发布;
    • Linux:通常以 .RPM 等包形式发布。包管理器可能已收录常见库(如 SDL),请先检查。
  2. 安装库

    • Linux:调用包管理器自动完成;
    • Windows:将库解压到自选目录,建议集中存放,如 C:\Libs,每个库单独子目录。
  3. 让编译器找到头文件

    • Windows:头文件通常位于库的 include 子目录(例如库位于 C:\libs\SDL-1.2.11,则头文件在 C:\libs\SDL-1.2.11\include);
    • Linux:头文件通常安装至 /usr/include,已包含在默认搜索路径;若安装在其他位置,需显式告知编译器。
  4. 告知链接器库文件位置
    与第 3 步类似,需将库目录加入链接器搜索路径。

    • Windows:通常为库安装目录下的 lib 子目录;
    • Linux:库通常安装至 /usr/lib,已包含在默认路径。

库安装完成且 IDE 知晓其位置后,每个项目还需执行以下三步:

  1. 若使用静态库或导入库,告知链接器需要链接的库文件;
  2. 在程序中加入 #include 引用库的头文件,使编译器了解库提供的全部功能;
  3. 若使用动态库,确保程序运行时能找到它们。
    • Linux:库通常位于 /usr/lib,默认搜索路径还包括 LD_LIBRARY_PATH 环境变量所列目录;
    • Windows:默认搜索顺序为:程序所在目录、SetDllDirectory() 设置的目录、Windows、System、System32 目录,以及 PATH 环境变量中的目录。最简单做法是将 .dll 复制到可执行文件同级目录,发布时也通常一起分发。

步骤 3–5 涉及 IDE 配置。几乎所有 IDE 的原理相同,但界面各异,因此难点仅在于找到对应设置项。后续章节将在 Visual Studio 与 Code::Blocks 中示范上述步骤。若使用其他 IDE,可参照这两部分说明,稍加搜索即可完成配置。

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"