C 语言静态库和共享库的区别

2025年1月7日 | 阅读 4 分钟

在本文中,我们将讨论 **静态库** 和 **共享库** 之间的区别。但在讨论区别之前,我们必须了解库。

在软件开发中起着至关重要的作用。它提供了可重用的代码组件,有助于编程过程。它们分为两种类型:静态库共享库。它们为程序提供功能,就像经验丰富的旅行者分享地图和资源一样。

静态库

静态库,或称为归档库,是在编译时与程序链接的对象文件集合。编译代码时,必要的库函数将包含在可执行文件中。这意味着编译后的程序包含所有代码,可以在执行期间独立运行,而无需依赖外部库。

要创建静态库,程序员会将单个源文件编译成对象文件,然后使用归档工具将它们打包到一个归档文件中。之后,链接器在编译期间将此归档文件与主程序链接。

共享库

共享库 也称为 **动态** 或共享对象库,它们在程序执行期间加载。共享库中的代码不会在编译时包含在可执行文件中。但是,程序在运行时动态依赖这些库,允许多个程序共享该库,从而减少了总体内存使用量。

在 Windows 系统上,共享库存储为动态链接库;在类 Unix 系统上,则存储为共享对象。这些文件包含在程序启动时或在运行时显式加载到内存中的已编译代码。

示例

让我们以一个用 C 语言创建和使用静态库的程序为例。

为静态库创建源文件

文件 1:math_operaations.h

文件 2:math_operations.c

源代码创建

"math_operations.h" 是一个头文件,它声明了将在静态库中定义的加法和减法函数的原型。"math_operations.c" 是实现 "math_operations.h" 中声明的函数的源文件。

将源文件编译成静态库

因此,打开终端并导航到包含源文件的目录。

使用 gcc -c 命令将 "math_operations.c" 文件编译为对象文件。此步骤生成特定于体系结构的机器代码,但不创建最终的可执行文件。

之后,使用 **" ar rcs"** 命令将对象文件归档为静态库 **"libmathstatic.a"**。此库包含已编译的函数。

示例

让我们以一个使用静态库的 C 程序为例。

使用静态库编译主程序

"main.c" 文件由 **"gcc"** 编译器编译成对象文件。

使用 -L 库路径,通过 "gcc" 链接器将对象文件与静态库链接。

最终执行

用户在终端中运行编译后的可执行文件。程序执行,利用静态库中的数学运算函数。

静态库和共享库之间的区别

Difference between Static and Shared libraries in C

C 语言中的 **静态库 和 **共享库** 之间存在一些区别。静态库和共享库之间的一些主要区别如下。

特点静态库共享库
编译时间在编译时链接在编译时(符号引用)或运行时(实际地址)链接
文件扩展名.a (归档文件).so (共享对象) 或 .dll (动态链接库)
大小可执行文件大小较大可执行文件大小较小
内存使用由于代码重复,内存消耗较高由于代码共享,内存消耗较低
更新需要重新编译才能更改库无需重新编译即可动态更新
依赖性运行时独立于外部库动态链接会引入运行时依赖
加载时间加载速度更快,因为所有内容都包含在可执行文件中由于动态链接,加载时间稍慢
灵活性灵活性较低,更改需要重新编译灵活性更高,无需重新编译即可进行更改
符号解析在编译时解析在编译时(符号引用)或运行时(实际地址)解析
隔离代码和数据在可执行文件内隔离代码由多个进程共享
执行速度由于本地优化,性能可能更快动态链接可能会带来轻微的开销。
分发较大的可执行文件大小可能会影响分发。较小的可执行文件大小有利于分发。
链接类型静态链接动态链接
平台兼容性更具可移植性,因为它包含了必要的代码需要兼容的共享库版本
调试调试更容易,因为所有代码都可用由于代码共享,调试可能更具挑战性

结论

静态库和共享库之间的选择取决于项目需求、性能考虑、分发限制以及所需的灵活性。两种类型的库都为多样化的软件开发格局做出了重要贡献,了解它们的细微差别可以使开发人员根据其特定需求做出明智的决策。