在c++中创建类库时,可以在动态(.dll, .so)和静态(.dll, .so)之间进行选择。Lib, .a)库。它们之间的区别是什么?什么时候使用哪个比较合适?


当前回答

如果您的库将在几个可执行文件之间共享,那么将其动态化以减少可执行文件的大小通常是有意义的。否则,一定要让它是静态的。

使用dll有几个缺点。装载和卸载它有额外的开销。还有一个额外的依赖关系。如果您更改dll使其与执行表不兼容,则它们将停止工作。另一方面,如果您更改了静态库,则使用旧版本编译的可执行文件将不会受到影响。

其他回答

Static libraries are archives that contain the object code for the library, when linked into an application that code is compiled into the executable. Shared libraries are different in that they aren't compiled into the executable. Instead the dynamic linker searches some directories looking for the library(s) it needs, then loads that into memory. More then one executable can use the same shared library at the same time, thus reducing memory usage and executable size. However, there are then more files to distribute with the executable. You need to make sure that the library is installed onto the uses system somewhere where the linker can find it, static linking eliminates this problem but results in a larger executable file.

关于这个主题的精彩讨论,请阅读Sun的这篇文章。

它包含了所有的好处,包括能够插入插入库。关于插入的更多细节可以在这篇文章中找到。

除了其他人提到的所有要点,我在特定的用例中使用静态库:

不允许我的终端用户访问一些通用库 我在我的代码中开发的。

换句话说,假设我的产品中有两个库,A和B。A使用B服务并依赖于它。但是B是一个通用库,包括许多可以单独使用的有用服务。为了避免我的终端用户直接从B中受益(他们应该为B的许可证付费!),我通常将B编译为一个静态库,并将其直接放在a中。因此,B服务对a来说是完全私有的,最终用户不能使用。

在我们的项目中,我们使用了很多DLL(> 100)。这些DLL相互依赖,因此我们选择了动态链接的设置。然而,它有以下缺点:

启动慢(> 10秒) DLL必须进行版本控制,因为windows根据名称的唯一性加载模块。否则,自己编写的组件将得到错误版本的DLL(即已经加载的DLL而不是自己的分布式集) 优化器只能在DLL边界内进行优化。例如,优化器试图将经常使用的数据和代码放在彼此旁边,但这将不能跨越DLL边界

也许更好的设置是将所有内容都设置为静态库(因此您只有一个可执行文件)。只有在没有发生代码复制的情况下,这才有效。一个测试似乎支持这个假设,但我找不到MSDN的官方引用。例如,创建1个exe:

Exe使用shared_lib1, shared_lib2 Shared_lib1使用shared_lib2 shared_lib2

shared_lib2的代码和变量应该只在最终合并的可执行文件中出现一次。有人能支持这个问题吗?

静态库必须链接到最终的可执行文件中;它成为可执行文件的一部分,并跟随它到任何地方。每次执行可执行文件时都会加载动态库,并以DLL文件的形式与可执行文件分开。

当您希望能够更改库提供的功能而不必重新链接可执行文件(只需替换DLL文件,而不必替换可执行文件)时,您将使用DLL。

当您没有理由使用动态库时,您可以使用静态库。