我正在创建一个 C++/CLI dll,它将加载到旧版 C++ 应用程序中。遗留应用程序通过传统的 LoadLibrary 调用来完成此操作。应用程序和 C++/CLI dll 均以 64 位模式编译。
当发生 LoadLibrary 调用时,它会失败并显示错误 193。这通常意味着某些非 64 位组件正在尝试加载。当我查看 Visual Studio 2010 中的 dll 加载输出时,我发现加载 mscoree.dll 时发生故障(确切地说,我看到加载了我的 dll,然后加载了 mscoree,然后卸载了 mscoree,然后卸载了我的 dll) ,然后返回错误)。具体来说,C:\Windows\System32\mscoree.dll 正在被加载,当我检查这个 mscoree.dll 时,我发现它的目标是 I386。
如何确保我的应用程序链接到正确的 mscoree.dll?我知道这可以通过清单来完成,但我找不到任何有关设置清单的好信息。理想的解决方案将允许在 32 位或 64 位模式下进行编译并以正确的 mscoree.dll 为目标。
附带说明一下,我在并排文件夹中发现了一个 mscoree.dll,我验证该文件夹是 64 位模式,并将其复制到我的应用程序目录中,希望它能首先找到该文件。这不起作用,C:\Windows\System32 版本仍然加载。
Thanks,
Max
C++/CLI dll 上 CorFlags.exe 的输出
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.
Version : v4.0.30319
CLR Header: 2.5
PE : PE32+
CorFlags : 16
ILONLY : 0
32BIT : 0
Signed : 0
C:\System32\mscoree.dll 上 pedump.exe 的输出
PS C:\Windows\System32> pedump.exe .\mscoree.dll
Dump of file .\MSCOREE.DLL
File Header
Machine: 014C (I386)
Number of Sections: 0004
TimeDateStamp: 4B90752B -> Thu Mar 04 22:06:19 2010
PointerToSymbolTable: 00000000
NumberOfSymbols: 00000000
SizeOfOptionalHeader: 00E0
Characteristics: 2102
EXECUTABLE_IMAGE
32BIT_MACHINE
DLL
...
(pedump 从这里继续描述导入和导出,但这在这里并不重要)
扩展加载信息
这是失败加载的完整输出。
注意:C++/CLI dll 称为 DsfClr.dll
输出是通过运行 gflags.exe -i [exename] +sls 并在调试器中检查结果获得的
http://pastebin.com/FyumUiMN http://pastebin.com/FyumUiMN
UPDATE:
使用 Reuben 在下面的评论中发布的提示,我能够确定 mscoree.dll 确实针对 AMD64,但 pedump 提供了无效信息,因为它在 WOW64 中运行。话虽这么说,我仍然无法加载这个库,如果有人有任何建议,他们将不胜感激。
我还尝试过一件事:我创建了一个新的 C# 应用程序并引用了 C++/CLI dll,然后在 main() 函数中,我在 C++/CLI dll 中实例化了一个类。这会在调用 main() 函数之前导致访问冲突异常。当我删除实例化时,主函数运行正常。我的猜测是,实例化导致了 C++/CLI 程序集的延迟加载,这导致了我在本机程序集中看到的相同加载错误。