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

Moh*_*nde 533 c c++ shared-libraries static-libraries

静态库和共享库有什么区别?

我使用Eclipse,有几种项目类型,包括静态库和共享库?一个人比另一个人有优势吗?

Pet*_*esh 720

共享库是.so(或在Windows .dll或OS X .dylib中)文件.与库相关的所有代码都在此文件中,并且在运行时使用它来引用它.使用共享库的程序仅引用它在共享库中使用的代码.

静态库是.a(或Windows .lib)文件.与库相关的所有代码都在此文件中,并在编译时直接链接到程序中.使用静态库的程序从静态库中获取它使用的代码的副本,并使其成为程序的一部分.[Windows也有.lib文件,用于引用.dll文件,但它们的行为方式与第一个相同].

每种方法都有优点和缺点.

共享库减少了每个使用库的程序中重复的代码量,使二进制文件保持较小.它还允许您使用功能相同的对象替换共享对象,但可以增加性能优势,而无需重新编译使用它的程序.但是,共享库在执行函数时会产生额外的小额成本以及运行时加载成本,因为库中的所有符号都需要连接到它们使用的东西.此外,共享库可以在运行时加载到应用程序中,这是实现二进制插件系统的一般机制.

静态库增加了二进制文件的总体大小,但这意味着您不需要携带正在使用的库的副本.由于代码在编译时连接,因此没有任何额外的运行时加载成本.代码就在那里.

就个人而言,我更喜欢共享库,但在需要确保二进制文件没有很多可能难以满足的外部依赖项时使用静态库,例如C++标准库的特定版本或Boost C++库的特定版本.

  • 有些人没有提到的是,使用静态库,编译器知道应用程序需要哪些函数,然后可以通过仅包含这些函数来优化它.这可以大规模减少库大小,特别是如果你只使用一个非常大的库的一个非常小的子集! (14认同)
  • "用...功能等效替换共享对象,但可以[改善]性能":具体而言,API语义使用中的等效面向调用者功能(应用程序编程接口:函数签名和变量包括类型),但是实现方面功能可能不同于perf:例如,函数始终记录到文件 - >还记录到TCP服务器:$ MY_APP_LOG_SERVER中预期的端口. (2认同)
  • “因为代码是在编译时连接的,所以没有任何额外的运行时加载成本。代码就在那里。” - 是和否......如果执行需要,它都在准备好被分页的可执行映像中,但是 - 从你的程序最近没有运行到足以进入缓存的情况开始 - 使用共享库是可能的(有时可能)或确定)操作系统、驱动程序或其他正在运行的程序已经加载了您的应用程序想要使用的相同共享库,在这种情况下,它可能在缓存中并且您的程序启动和运行速度更快。 (2认同)
  • 这个答案可以更好地组织。制作利弊的项目符号列表或表格以显示存在差异的每个维度的差异会很有帮助。 (2认同)
  • 当您动态编译时,您正在声明在运行时解析的依赖项。满足这种依赖性需要 (a) 随程序携带库的副本,或者 (b) 确保在运行之前将库安装在目标系统上。这意味着程序的部署变得更加复杂。静态链接在编译时将所有这些依赖项放入程序中,因此通常可以减少对单个文件的部署。 (2认同)

Pau*_*ter 371

静态库就像一个书店,共享库就像一个库.使用前者,您可以获得自己的书籍/功能副本带回家; 与后者你和其他人去图书馆使用相同的书/功能.所以任何想要使用(共享)库的人都需要知道它在哪里,因为你必须"去获取"书籍/功能.使用静态库,书籍/功能是你自己的,你把它保存在你的家庭/程序中,一旦你拥有它,你就不在乎你何时或何时获得它.


Sta*_*ked 66

简化:

  • 静态链接:一个大的可执行文件
  • 动态链接:一个小的可执行文件加上一个或多个库文件(Windows上的.dll文件,Linux上的.so或macOS上的.dylib)

  • 这个答案对我来说是最好的,因为它很实用。它比不谈论计算机中实际发生的事情的比喻更有意义。在知道这就是发生的事情之后,我只是凭直觉知道所有其他含义。 (2认同)

小智 34

对于静态库,代码由链接器从库中提取,并用于在编译/构建应用程序时构建最终的可执行文件.最终的可执行文件在运行时没有依赖于库

对于共享库,编译器/链接器会在构建应用程序时检查链接的名称是否存在于库中,但不会将其代码移动到应用程序中.在运行时,共享库必须可用.

C编程语言本身没有静态库或共享库的概念 - 它们完全是一种实现特性.

就个人而言,我更喜欢使用静态库,因为它使软件分发更简单.然而,这是一个关于过去流失多少(象征性)血液的观点.

  • +1"C编程语言本身没有静态或共享库的概念 - 它们完全是一种实现功能." (4认同)

Tar*_*ski 30

静态库是作为应用程序的一部分编译的,而共享库则不是.当您分发依赖于共享库的应用程序时,例如,库.需要安装MS Windows上的dll.

静态库的优点是运行应用程序的用户不需要依赖 - 例如,他们不必升级他们的DLL.缺点是您的应用程序的大小更大,因为您将它与所需的所有库一起发货.

除了导致较小的应用程序,共享库还为用户提供了使用他们自己的,可能更好的库版本的能力,而不是依赖于应用程序的一部分.

  • DLL地狱,因为它已知 (3认同)

Jas*_*eet 17

共享库的最大优点是,无论有多少进程使用该库,内存中只加载了一个代码副本.对于静态库,每个进程都有自己的代码副本.这可能导致显着的内存浪费.

OTOH,静态库的一个优点是所有东西都捆绑在你的应用程序中.因此,您不必担心客户端将在其系统上提供正确的库(和版本).


san*_*ood 6

除了所有其他答案之外,尚未提及的一件事是解耦:

让我谈谈我一直在处理的现实生产代码:

一个非常大的软件,由> 300个项目(使用visual studio)组成,主要构建为静态库,最后所有链接在一个巨大的可执行文件中,最终会出现以下问题:

- 链接时间非常长.你最终可能会超过15分钟的链接,因为让我们说10个编译时间 - 有些工具是如此庞大的可执行文件,比如必须检测代码的内存检查工具.你可能会陷入被视为傻瓜的极限.

更有问题的是你的软件脱钩:在这个现实世界的例子中,每个项目的头文件都可以从任何其他项目中获得.因此,一个开发人员很容易添加依赖项; 它只是包括标题,因为最后的链接将全部找到符号.最终由可怕的骑车依赖和完全混乱.

使用共享库,这是一项额外的工作,因为开发人员必须编辑项目构建系统以添加依赖库.我发现共享库代码往往提供更清晰的代码API.


小智 5

+---------------+---------------------------+------------------------------+
| properties    | Static library            | Shared library               |
+===============+===========================+==============================+
| Linking time  | It happens as the         | Shared libraries             |
|               | last step of the          | are added during             |
|               | compilation process.      | linking process              |
|               | After the program         | when executable              |
|               | is placed                 | file and libraries           |
|               | in the memory             | are added to the memory.     |
+---------------+---------------------------+------------------------------+
| Means         | Performed by linkers      | Performed by operating System|
+---------------+---------------------------+------------------------------+
| Size          | Static libraries are      | Dynamic libraries are        |
|               | much bigger in size,      | much smaller, because        |
|               | because external          | there is only one copy       |
|               | programs are built        | of dynamic library           |
|               | in the executable file.   | that is kept in memory.      |
+---------------+---------------------------+------------------------------+
| External file | Executable file will      | In shared libraries,         |
| changes       | have to be recompiled     | no need to recompile         |
|               | if any changes were       | the executable.              |
|               | applied to external files.|                              |
+---------------+---------------------------+------------------------------+
| Time          | Takes longer to execute   | It is faster                 |
|               | because loading into the  | because shared               |
|               | memory happens every time | library code is              |
|               | while executing.          | already in the memory.       |
+---------------+---------------------------+------------------------------+
| Compatibility | Never has a compatibility | Programs are dependent       |
|               | issue,since all code is   | on having a compatible       |
|               | in one executable module. | library.Dependent program    |
|               |                           | will not work if library     |
|               |                           | gets removed from the system |
+---------------+---------------------------+------------------------------+
Run Code Online (Sandbox Code Playgroud)