早在 90 年代,当我第一次开始使用 MFC 时,我曾经动态链接我的应用程序并提供相关的 MFC DLL。这给我带来了一些问题(DLL 地狱!),我改用静态链接 - 不仅适用于 MFC,还适用于 CRT 和 ATL。除了较大的 EXE 文件之外,静态链接从来没有给我带来任何问题 - 那么其他人遇到过什么缺点吗?是否有充分的理由再次重新审视动态链接?我的应用程序现在主要是 STL/Boost FWIW。

有帮助吗?

解决方案

有一些缺点:

  • 更大的 exe 大小(特别是如果您发送多个 exe)
  • 使用依赖或假定动态链接的其他 DLL 时出现问题(例如:无法以静态库形式获取的第 3 方 DLL)
  • 具有独立静态链接的 DLL 之间的不同 c 运行时(无跨模块分配/解除分配)
  • 无法自动提供共享组件(无需重新编译和更新应用程序,第三方模块供应商就无法更新其代码来解决问题)

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

其他提示

我听到的大多数答案都涉及与其他程序共享您的 dll,或者更新这些 dll 而无需修补您的软件。

坦率地说,我认为这些都是缺点,而不是优点。当第三方 dll 更新时,它的变化足以破坏您的软件。如今,硬盘空间不再像以前那样宝贵,您的可执行文件中需要额外的 500k 空间吗?谁在乎?

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

我认为优点远远大于缺点

只要您将使用限制在某些库中并且不使用任何dll,那么您应该是好的。

不幸的是,有些库无法静态链接。我最好的例子是OpenMP。如果您利用Visual Studio的OpenMP支持,则必须确保安装了运行时(在本例中为vcomp.dll)。

如果你确实使用了dll,那么你就不能在没有严肃体操的情况下来回传递一些物品。想到std :: strings。如果您的exe和dll是动态链接的,那么分配将在CRT中进行。否则,您的程序可能会尝试在一侧分配字符串并在另一侧释放它。随之而来的是糟糕的事情......

那就是说,我仍然静态链接我的exe和dll。它确实减少了安装中的许多变化,我认为这非常值得一些限制。

使用dll的一个很好的特性是,如果多个进程加载相同的dll,则可以在它们之间共享其代码。这可以节省内存并缩短加载已经被其他程序使用的dll的应用程序的加载时间。

不,在这方面没什么新鲜事。保持这种状态。

绝对是。

分配在'静态'堆上完成。由于分配应该在同一个堆上进行解除分配,这意味着如果你运送一个库,你应该注意客户端代码不能调用'你的' p = new LibClass()并删除它使用 delete p;

对象本身

我的结论:屏蔽分配和从客户端代码中释放,或动态链接CRT。

有些软件许可证(例如LGPL)要求您使用DLL或将应用程序分发为用户可以链接在一起的目标文件。如果您使用的是此类库,则可能需要将其用作DLL。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top