gpt4 book ai didi

c++ - 使用运行时 DLL (/MD) 避免与 dll 的运行时依赖

转载 作者:行者123 更新时间:2023-11-30 05:47:22 24 4
gpt4 key购买 nike

我们使用 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 提供函数。然而,使用标准库函数这样做麻烦多于其值(value)。

您需要使用 /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 之间共享标准库对象。但是耦合要松散得多。我认为这是一个值得做出的权衡。

关于c++ - 使用运行时 DLL (/MD) 避免与 dll 的运行时依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28599689/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com