A-1 静态库与动态库
库library是一组旨在供多个程序重复使用的代码。通常,C++ 库由两部分组成:
- 一个头文件,用于定义该库向使用它的程序提供的功能。
- 一个预编译二进制文件,其中包含已预编译为机器语言的该功能实现。
某些库可能会拆分为多个文件,并且/或者包含多个头文件。
库之所以被预编译,有几个原因。首先,由于库很少发生变化,因此无需频繁重新编译。如果每次编写使用库的程序时都重新编译库,那将是一种时间浪费。其次,由于预编译后的目标文件采用机器语言,这能防止他人访问或修改源代码,这对企业或出于知识产权考虑不愿公开源代码的人士而言至关重要。
库主要分为两类:静态库和动态库。
静态库static library(也称为归档文件archive)由一系列例程组成,这些例程在编译时会被直接链接到程序中。当您编译一个使用静态库的程序时,该程序所使用的静态库的所有功能都会成为可执行文件的一部分。在 Windows 系统中,静态库通常使用 .lib 扩展名,而在 Linux 系统中,静态库通常使用 .a(归档)扩展名。静态库的一个优势在于,您只需分发可执行文件,用户即可运行您的程序。由于库已成为程序的一部分,这确保了程序始终使用正确的库版本。此外,由于静态库已成为程序的一部分,您可以像使用自己编写的功能一样直接调用它们。但缺点在于,由于每个使用该库的可执行文件中都包含库的副本,这会导致大量空间浪费。静态库也难以升级——要更新库,必须替换整个可执行文件。
动态库dynamic library(也称为共享库shared library)由在运行时加载到应用程序中的例程组成。当您编译使用动态库的程序时,该库不会成为可执行文件的一部分——它仍作为独立单元存在。在 Windows 系统中,动态库通常具有 .dll(动态链接库)扩展名,而在 Linux 系统中,动态库通常具有 .so(共享对象)扩展名。动态库的一个优势在于,多个程序可以共享同一份副本,从而节省空间。也许更大的优势在于,动态库可以升级到新版本,而无需替换所有使用它的可执行文件。
由于动态库未链接到程序中,使用动态库的程序必须显式加载并调用动态库。这种机制可能令人困惑,并使与动态库的交互变得笨拙。为了简化动态库的使用,可以使用导入库。
导入库import library是一种能够自动化动态库加载和使用过程的库。在 Windows 系统中,这通常通过一个与动态库(.dll)同名的小型静态库(.lib)来实现。该静态库在编译时被链接到程序中,随后动态库的功能便可像静态库一样被有效调用。在 Linux 系统中,共享对象 (.so) 文件既可作为动态库,也可作为导入库使用。大多数链接器在创建动态库时,都能为其生成相应的导入库。
安装和使用库
既然你已经了解了各种类型的库,接下来我们就来谈谈如何在程序中实际使用库。在 C++ 中安装库通常包括 4 个步骤:
- 获取该库。最佳选择是下载适用于您操作系统的预编译包(如果存在),这样您就不必自己编译该库。如果您的操作系统没有提供预编译包,您将不得不下载仅包含源代码的包并自行编译(这超出了本课的范围)。在 Windows 系统中,库通常以 .zip 文件的形式发布。在 Linux 系统中,库通常以软件包(例如 .RPM)的形式发布。您的软件包管理器可能已列出一些较流行的库(例如 SDL),以便于安装,因此请先在此处查看。
- 安装库。在 Linux 上,这通常只需调用包管理器并让其完成所有操作。在 Windows 上,这通常需要将库解压到您选择的目录中。我们建议将所有库集中存放在一个位置以便于访问。例如,使用名为 C:\Libs 的目录,并将每个库放在其各自的子目录中。
- 确保编译器知道在哪里查找该库的头文件。在 Windows 系统中,通常位于安装库文件的目录下的 include 子目录中(例如,若将库安装到 C:\libs\SDL-1.2.11,则头文件很可能位于 C:\libs\SDL-1.2.11\include)。在 Linux 系统中,头文件通常安装在 /usr/include 目录下,该目录通常已包含在头文件搜索路径中。但是,如果文件安装在其他位置,则需要告知编译器其位置。
- 告知链接器在何处查找库文件。与步骤 3 类似,这通常涉及将一个目录添加到链接器搜索库的位置列表中。在 Windows 系统中,这通常是您安装库文件的目录下的 /lib 子目录。在 Linux 系统中,库通常安装在 /usr/lib 目录下,该目录通常已包含在您的库搜索路径中。
安装好库并确保 IDE 知道去哪里查找该库后,对于每个想要使用该库的项目,通常需要执行以下 3 个步骤:
- 如果使用静态库或导入库,请告知链接器需要链接哪些库文件。
- 在程序中包含库的头文件。这会向编译器告知库提供的所有功能,从而确保程序能够正确编译。
- 如果使用动态库,请确保程序知道在哪里查找它们。在 Linux 系统中,库通常安装在 /usr/lib 目录下,该目录位于 LD_LIBRARY_PATH 环境变量中路径之后的默认搜索路径中。在 Windows 系统中,默认搜索路径包括程序运行所在的目录、通过调用 SetDllDirectory() 设置的目录、Windows、System 和 System32 目录,以及 PATH 环境变量中的目录。使用 .dll 文件最简单的方法是将其复制到可执行文件所在的位置。由于通常会将 .dll 文件与可执行文件一同分发,因此将它们放在一起也是合理的。
步骤 3-5 涉及配置您的 IDE——幸运的是,几乎所有 IDE 在执行这些操作时都遵循相同的方式。遗憾的是,由于每个 IDE 的界面各不相同,此过程最困难的部分仅仅在于找到执行每个步骤的正确位置。因此,在本节接下来的几节课中,我们将介绍如何在 Visual Studio 和 Code::Blocks 中完成所有这些步骤。如果您使用的是其他 IDE,请同时阅读两部分内容——等您读完后,应该就能掌握足够的信息,只需稍加搜索,就能在您自己的 IDE 中完成同样的操作。

浙公网安备 33010602011771号