【问题标题】:Getting out of DLL Hell with Microsoft.VC90.CRT?使用 Microsoft.VC90.CRT 摆脱 DLL 地狱?
【发布时间】:2019-01-21 11:12:24
【问题描述】:

我已经构建了一个 inproc com 服务器 dll,我可以通过构建实用程序 py2exe 将其打包为一个或多个文件。当我允许所有依赖项保持外部时,我没有问题,但捆绑为 1 个文件会产生问题。

当使用 dll 时(注册它或从中实例化一个 com 对象),无论我做什么,它都会立即从路径 c:\windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6871_none_50944e7cbcb706e5\MSVCR90.DLL 加载 MSVCR90.DLL,我无法更改它。我找不到任何信息(使用 Dependency Walker)来指示导致加载的原因。它只是神奇地发生......

然后,稍后它通过显式调用LoadLibraryA("MSVCR90.dll")(某些py2exe 黑匣子的一部分?)再次加载该dll,但这次它不查看winsxs manifests / 目录。相反,它会查看系统路径和/或将尊重 dll 重定向。这就是问题发生的时候。如果我将系统路径设置为以c:\windows\winsxs\x86_microsoft.vc90.crt...\ 开头,它将加载完全相同的 dll 并且很高兴 - 但如果使用任何其他文件 - 包括完全相同的 dll 的副本 - 但在不同的路径 - 那么整个事情爆炸了。它无法处理使用两个不同的文件。

我该如何解决这个问题?理想情况下,我喜欢让 dll 的初始魔法加载基于私有程序集,但无论我对清单或 .dll.local 等做什么,在第二次加载 dll 之前,它都不会尊重这一点。

请注意,对于非捆绑 dll(外部依赖项),它始终使用 winsxs MSVCR90.DLL。

我可以通过强制系统路径加载winsxs副本来“修复”我无法使用dll的问题,但这对于可部署的com服务器来说毫无用处!

【问题讨论】:

    标签: dll com assemblies py2exe winsxs


    【解决方案1】:

    原因是你的 DLL 有一个清单,它告诉模块加载器也在 SxS 存储中搜索。

    你有几个选择

    1. 使用静态链接构建您的 DLL。不使用任何 MFC-DLL(参见项目设置)
    2. 不要对 DLL 使用并行清单,而仍然使用 MFC DLL。但请注意,您必须将这些 DLL 与本地路径中的 DLL 一起提供(请参阅 DLL 搜索序列文档)
    3. 使用更高版本的 VS。更高版本的 VS 不再使用 SxS 存储,并且不再有这些 DLL 的清单。

    对于 2. 请参阅code project 中的这篇文章。 VS-2008 [这里] 有一个更新。 2

    构建你的 DLL

    【讨论】:

    • 谢谢,但我认为这一切的前提是基于我在 Visual Studio 中编写 VC++ 的假设。我不是。我用 Python 编写了代码,并使用 py2exe 魔法来创建 dll。除了尝试拆分并重新编译底层工具之外,我还可以选择静态的动态链接等。
    • 也就是说,清单中具体是什么告诉加载程序使用 SxS?我已经调整了清单 100 次,试图让他的工作(尽管我不确定它是否确实受到尊重......)。我很幸运使用 .dll.local 进行重定向,但正如在原始问题中所写的那样,只有在某些神秘进程最初加载 dll 之后,在随后调用 LoadLibrary 时才会尊重。
    • 回答我关于 SxS 的问题,这就是 publicKeyToken 的工作。从理论上讲,从清单中删除它会指导使用私有程序集。我已经试过了,但我又试了一次。这对我没有影响。我可以加载私有程序集——但只能在“第二次”加载 dll 时。第一个仍然是 SxS。我认为它包含在 pythoncom 和/或 py2exe dll 加载程序代码和嵌入式 dll 中。我猜解决方案需要深入研究该来源......(我已经开始了,但没有成功)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多