在c++中创建类库时,可以在动态(.dll, .so)和静态(.dll, .so)之间进行选择。Lib, .a)库。它们之间的区别是什么?什么时候使用哪个比较合适?
当前回答
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.
其他回答
如果你在嵌入式项目或专门的平台上工作,静态库是唯一的方法,而且很多时候它们编译到你的应用程序中不是那么麻烦。同时,拥有包含一切的项目和makefile会让生活更快乐。
除了静态库与动态库的技术影响(静态文件将所有内容捆绑在一个大的二进制文件中,而动态库允许在几个不同的可执行文件之间共享代码)之外,还有法律影响。
例如,如果您正在使用LGPL许可的代码,并且静态地链接到一个LGPL库(从而创建了一个大的二进制文件),那么您的代码将自动成为开源(自由)LGPL代码。如果您链接到一个共享对象,那么您只需要LGPL对LGPL库本身所做的改进/错误修复。
例如,如果你决定如何编译你的移动应用程序,这就成为一个更重要的问题(在Android中你可以选择静态和动态,在iOS中你不能-它总是静态的)。
Ulrich Drepper关于“如何编写共享库”的论文也是一个很好的资源,详细介绍了如何最好地利用共享库,或者他所说的“动态共享对象”(DSOs)。本文主要讨论ELF二进制格式的共享库,但有些讨论也适用于Windows dll。
在我们的项目中,我们使用了很多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优点:可用于多个产品之间重用/共享代码;按需装入进程内存,不需要时可卸载;可以独立于程序的其余部分进行升级。
Dll缺点:Dll加载和代码重基的性能影响;版本控制问题(“dll地狱”)
Lib优点:没有性能影响,因为代码总是在进程中加载,而不是重基;没有版本问题。
Lib缺点:可执行文件/进程“膨胀”-所有的代码都在你的可执行文件中,并在进程启动时加载;没有重用/共享-每个产品都有自己的代码副本。