繁体   English   中英

使用运行时DLL(/ MD)避免DLL与运行时相关

[英]Avoid runtime dependency with a dll using runtime DLL (/MD)

我们使用VS2012,并具有依赖于运行时DLL(/ MD)的dll。 该dll用于许多不同的项目,并且不能轻易更改。

我们还有一个小的启动器可执行文件,该可执行文件必须能够在全新安装的系统上运行,因此没有安装运行时。 它与运行时(/ MT)静态链接。

现在,此exe取决于上述dll。

照原样,该exe文件未构建[1]。 我观察到,通过忽略MSVCRT(/NODEFAULTLIB:"MSVCRT.lib“)来构建它可以解决[1],但会产生[2]。 在“强制符号引用”中添加报告为错误的少量符号(例如/ INCLUDE:“ _ strncpy”),使构建成功。

但是,使用Dependency Walker检查生成的exe会显示通过我们的dll对运行时DLL的依赖性[3]。 我确认其中存在字符串[3]。 尝试在Vista的全新安装上运行exe失败(错误说[3]中的DLL丢失)。 我担心这是不可能的,而且我还没有发现任何暗示它的信息。

静态链接的exe可以为动态链接的dll提供运行时功能吗? 如果是,怎么办?

谢谢

参考文献:

  1. 1> MSVCRT.lib(MSVCR110.dll):错误LNK2005:_sprintf已在libcmt.lib(sprintf.obj)中定义
  2. 错误LNK2001:无法解析的外部符号__imp__strncpy
  3. MSVCP110.dll,MSVCR110.dll

是的,静态链接的exe可以为DLL提供功能。 但是,使用标准库函数进行操作比其价值更大。

您需要使用/NODEFAULTLIB停止使用其自己的运行时副本来构建DLL。 这将使您产生大量链接错误,因为DLL使用的标准库的每个部分以及某些供应商扩展现在都无法解决。

其中的每一个都需要使用模块定义文件添加到EXE导出表中。 EXE链接期间将生成导入库。 然后将该导入库提供给DLL,以满足其外部需求,从而解决它们。

最后,您将只有一个运行时库副本,从而允许您的EXE和DLL共享库对象,例如FILE*和堆(因此您可以在其中分配一个,而在另一个分配中免费)。 但是DLL和EXE将非常紧密地耦合在一起。 对DLL的几乎任何更改都可能破坏构建,并要求EXE进行新的导出以对其进行修复。 您绝对不能将对DLL的更新与对EXE的更新分开提供。

一种更简单的方法(仍使DLL大小减小)将是使用延迟加载。 这样,尽管在没有先安装运行时可再发行文件的情况下仍然无法加载DLL,但是在进程启动期间不会发生故障,并且EXE将有机会检查运行时的存在并安装可再发行文件。 或诊断并处理DLL加载失败。

在极端情况下,EXE可以完全避免使用标准库,确保可再发行组件的存在,然后为所有需要标准库运行时的复杂逻辑调用延迟加载DLL。

在后一种情况下,由于EXE没有使用运行时的DLL版本,因此您无法在EXE和DLL之间共享标准库对象。 但是耦合要宽松得多。 我认为这是值得权衡的。

最终,我们将dll构建设置更改为/ MT。 我不知道有什么其他方法可以解决问题。

如果您的.exe需要在干净的操作系统上运行,则它不能依赖于动态链接的任何DLL,因为如果没有运行时DLL,这些DLL(以及.exe)就无法加载。 您是否考虑过本地应用程序部署 然后,.exe和dll都可以使用/ MD构建。

可以创建一个可以作为DLL或静态库构建的项目。 小型启动程序可执行文件应与DLL项目的静态库配置链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM