我有一个带有 .NET 包装器的本机 C++ 库,全部内置于 Visual Studio 2003 和 2005 中。我们最近将 .NET 包装器库移植到 VS2005,但它不起作用。.NET 包装库是混合模式的,具有本地 C++ 和托管扩展类,以及一些本地程序集。在所有情况下都假设一个发布二进制文件。
VS2003 .NET dll 完美运行,没有任何抱怨,但到目前为止我无法使用 VS2005。我在本机库上构建了其他本机应用程序,因此问题似乎受限于链接器设置和围绕 .NET 库的动态链接规则。
.net 库正在使用 C++ 的托管扩展 (/clr:oldSyntax),因此某些选项在属性表中受到限制。
我原来的问题是运行时错误 R6034: An application has made an attempt to load the C runtime library incorrectly
。通过在程序集中包含嵌入式清单已解决此问题。异常跟踪如下:
Unhandled Exception: System.IO.FileLoadException: A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT: 0x8007045A)
at Corp.Blah.BlahConsole.Program.Main(String[] args)
在程序集中嵌入清单后,我收到一个新错误。问题标题中的并排错误来自 Dependency Walker。全文:
Error: The Side-by-Side configuration information for "s:\release\MDM3NET80.DLL" contains errors. This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem (14001).
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
据我所知,与 Kernel32.dll 部分相关的延迟加载警告在不同版本的 Windows 中已发生变化,但与我的应用程序无关,尤其是 MPR.DLL、IESHIMS.DLL 和 WER.DLL。这些警告似乎并不重要。
尝试使用小型控制台应用程序加载 .NET dll 会产生System.IO.FileLoadException
:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'BLAH, Version=5.0.0.22, Culture=neutral, PublicKeyToken=ffbc9a05441709bc' or one of its dependencies. This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0x800736B1)
File name: 'BLAH, Version=5.0.0.22, Culture=neutral, PublicKeyToken=ffbc9a05441709bc' ---> System.Runtime.InteropServices.COMException (0x800736B1): This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0x800736B1)
at Corp.Blah.BlahConsole.Program.Main(String[] args)
此错误发生在开发机器以及其他机器上,因此我不希望 Visual Studio 尝试使用错误版本的 MSCRT dll。
我从构建的 DLL 中提取了以下程序集:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="Corp.Blah.BlahNet">
</assemblyIdentity>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">
</assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
指示的 CRT dll 可以在 WINSxS 目录下找到x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700
,以及许多其他版本。据我所知,这意味着库的正确版本应该按照此链接的建议在运行时链接。
我尝试了各种摆弄链接器和清单设置的方法,包括以下内容:
- 使用和不使用嵌入式清单进行构建。添加清单可修复 R6034 错误,但会出现 FileLoadException/side-by-side 问题。
- 将 MSCRT dll 放在输出文件夹中并尝试链接到它们,而不是静态链接 .lib 文件。
- 将代码生成运行时库从 /MD 更改为 /MT(/clr:oldSyntax 项目不支持,我仍然需要支持 VS2003,因此无法升级)。
- 属性 -> 链接器 -> 生成清单:是(默认),否 -(相同的结果)
- 尝试将 .NET 包装器移植到 VS2010 并链接到 VS2005 本机二进制文件 - 适用相同的问题和错误消息。
我经历了许多类似的问题和论坛帖子,到目前为止,没有一个提供的解决方案有效。任何人都可以帮忙吗?我对这个有点迷失了。
来自事件查看器的附加信息
在系统事件查看器中,错误按来源报告:SideBySide,全文:
为 S:\release\BlahNet.dll 生成激活上下文失败。参考错误信息:操作成功完成。
看起来像是 Daily WTF 的候选人。
更新:尝试从头开始没有运气
我通过从头开始构建 VS2005 项目文件并导入源进行了另一次尝试。我想当密钥签名系统出现故障时,我可能会做一些事情,如此处所述。FileLoadException
在尝试了建议的密钥签名方法后,我在尝试使用 DLL 时仍然得到相同的结果。