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

其他回答

我给出一个一般的经验法则,如果你有一个很大的代码库,所有的代码库都建立在较低层次的库(例如Utils或Gui框架)之上,你想把它们划分成更易于管理的库,然后让它们成为静态库。动态库实际上不会为您带来任何东西,而且惊喜也更少——单个实例只有一个实例。

如果你有一个完全独立于其他代码库的库(例如第三方库),那么考虑将其作为一个dll。如果库是LGPL,由于许可条件,您可能无论如何都需要使用dll。

如果库是静态的,则在链接时将代码链接到可执行文件中。这使您的可执行文件更大(如果您走动态路线)。

如果库是动态的,那么在链接时,对所需方法的引用将内置于可执行文件中。这意味着您必须发布可执行文件和动态库。您还应该考虑对库中代码的共享访问是否安全、首选加载地址以及其他事项。

如果你能接受静态库,那就使用静态库。

您应该仔细考虑随时间的变化、版本控制、稳定性、兼容性等。

如果有两个应用程序使用共享代码,您是否希望强制这些应用程序一起更改,以防它们需要相互兼容?然后使用dll。所有的exe都将使用相同的代码。

或者你想把它们彼此隔离,这样你就可以改变一个,并确信你没有破坏另一个。然后使用静态库。

DLL地狱是当你可能应该使用一个静态库,但你使用了一个DLL代替,并不是所有的前任都与它兼容。

静态库被编译到客户机中。在编译时使用.lib,库的内容成为消费可执行文件的一部分。

动态库在运行时加载,而不是编译到客户端可执行文件中。动态库更加灵活,因为多个客户端可执行文件可以加载一个DLL并利用它的功能。这也将客户端代码的总体大小和可维护性保持在最小。

真正的权衡(在一个大型项目中)是在初始加载时间,库将在某个时间被链接,必须做出的决定是链接是否需要足够长的时间,以至于编译器需要咬紧牙关并提前完成,还是动态链接器可以在加载时完成。