静态或动态链接CRT、MFC、ATL等

22
在90年代,当我刚开始使用MFC时,我经常动态链接我的应用程序并发布相关的MFC DLL。这给我带来了一些问题(DLL地狱!),所以我转而采用静态链接-不仅是对于MFC,还包括CRT和ATL。除了EXE文件更大之外,静态链接从未给我带来任何问题-因此,其他人是否遇到过任何缺点呢?重新考虑动态链接是否有充分的理由?就FWIW而言,我的应用程序现在主要是STL / Boost。
7个回答

22

我听到的大多数关于这个问题的答案都涉及共享你的dll文件给其他程序,或者让那些dll文件在无需修补你的软件的情况下进行更新。

坦白地说,我认为这些是缺点而不是优点。当第三方dll被更新时,它可能会发生足够的变化导致你的软件出现故障。而现在,硬盘空间不像过去那样珍贵,你的可执行文件多500k?谁在意呢?

  • 确定你的软件使用的dll版本是100%正确的是一件好事。
  • 确保客户不会有依赖性问题是一件好事。

在我看来,优点远远超过缺点。


19

存在一些缺点:

  • 较大的exe文件大小(尤其是如果您发布多个exe文件)
  • 使用依赖于或假定动态链接的其他DLL存在问题(例如:第三方DLL,您无法将其作为静态库获取)
  • 具有独立静态链接的DLL之间的不同c运行时(没有跨模块分配/释放)
  • 没有共享组件的自动维护(无法让第三方模块供应商更新其代码以修复问题,而无需重新编译和更新您的应用程序)

我们在Windows应用程序中使用静态链接,主要是因为它允许xcopy部署,而依靠SxS DLL以一种有效的方式进行安装或依赖是不可能的,因为该过程和机制没有得到很好的记录或易于远程操作。如果在安装目录中使用本地DLL,则它会有点起作用,但受支持性不强。我们不使用动态链接的主要原因是难以轻松地进行远程安装,而不必通过远程系统上的MSI进行,但是(正如您所指出的),使用静态链接还有许多其他好处。每种方法都有优缺点。希望这有助于列举它们。


一个可能更好的方法(私有程序集)在https://dev59.com/m3RA5IYBdhLWcg3w6SNH中有描述。 - Weidenrinde

4
只要您的使用范围限于某些库并且不使用任何dll,则应该没问题。不幸的是,有一些库无法静态链接。我最好的例子是OpenMP。如果您利用Visual Studio的OpenMP支持,则必须确保安装了运行时(在这种情况下为vcomp.dll)。
如果您使用dll,则无法轻松地来回传递某些项。std::strings就是一个例子。如果您的exe和dll是动态链接的,则分配发生在CRT中。否则,您的程序可能会尝试在一侧分配字符串,在另一侧释放它。糟糕的事情会发生...
话虽如此,我仍然将我的exe和dll静态链接。这确实减少了安装中的很多变数,我认为这是值得的,尽管有一些局限性。

1
关于内存分配的事情是不正确的。当您使用DLL CRT时,应用程序中只有一个CRT,因此您可以从一个DLL中分配并在另一个DLL中释放,因为它们都指向相同的堆,因为它们使用的是相同的CRT。 - Adam Mitz
没错,但如果exe和dll都是静态链接的话,就会有两个堆。对吧?至少这是我的经验。我得告诉你,能够来回传递std::string或vector会让我的生活轻松很多。 - Jere.Jones
2
解决 std::string 问题的方法不是犹豫不决。要么静态链接,要么动态链接。如果您至少有一个 C++ DLL,请链接到 CRT DLL。 - MSalters

2

DLL的一个优点是,如果多个进程加载同一个DLL,它们之间可以共享代码。这可以节省内存,并缩短应用程序加载已被另一个程序使用的DLL的时间。


2
这可以通过页面去重来节省系统内存,但是个别进程的虚拟地址空间实际上会被减少——不仅可执行文件中的部分库被拉入,整个库都映射到进程地址空间中。随着多个 DLL 被映射并启用 ASLR,进程虚拟地址空间变得分散,这至少对于 32 位应用程序来说,会大大减少可分配的连续内存块的大小。 - Igor Levicki

1

有一些软件许可证,比如LGPL,要求你使用DLL或者分发应用程序作为用户可以链接在一起的目标文件。如果你正在使用这样的库,你可能想要将其作为DLL使用。


如果你_必须_使用这样的库,你可以支付赎金以静态链接(而不是携带DLL)。 - Navin

1

没有,关于那方面没有新的进展。保持现状就好。


1

当然。

分配是在“静态”堆上完成的。由于分配和释放应该在同一堆上完成,这意味着如果您发布一个库,您应该注意客户端代码不能调用“您”的p = new LibClass()并使用delete p;删除该对象。

我的结论:要么保护客户端代码免受分配和释放的影响,要么动态链接CRT。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接