在c++中创建类库时,可以在动态(.dll, .so)和静态(.dll, .so)之间进行选择。Lib, .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的代码和变量应该只在最终合并的可执行文件中出现一次。有人能支持这个问题吗?
其他回答
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.
c++程序的构建分两个阶段
编译——生成目标代码(.obj) 链接——生成可执行代码(.exe或.dll)
静态库(.lib)只是一个.obj文件的包,因此不是一个完整的程序。它还没有经历构建程序的第二个(链接)阶段。另一方面,dll类似于exe,因此是完整的程序。
如果你构建了一个静态库,它还没有被链接,因此你的静态库的消费者将不得不使用与你使用的相同的编译器(如果你使用g++,他们将不得不使用g++)。
如果相反,您构建了一个dll(并且正确地构建了它),那么您已经构建了一个所有消费者都可以使用的完整程序,无论他们使用哪种编译器。但是,如果需要跨编译器兼容性,则从dll导出有几个限制。
如果你在嵌入式项目或专门的平台上工作,静态库是唯一的方法,而且很多时候它们编译到你的应用程序中不是那么麻烦。同时,拥有包含一切的项目和makefile会让生活更快乐。
关于这个主题的精彩讨论,请阅读Sun的这篇文章。
它包含了所有的好处,包括能够插入插入库。关于插入的更多细节可以在这篇文章中找到。
如果您的库将在几个可执行文件之间共享,那么将其动态化以减少可执行文件的大小通常是有意义的。否则,一定要让它是静态的。
使用dll有几个缺点。装载和卸载它有额外的开销。还有一个额外的依赖关系。如果您更改dll使其与执行表不兼容,则它们将停止工作。另一方面,如果您更改了静态库,则使用旧版本编译的可执行文件将不会受到影响。