3

我有一个带有 .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 时仍然得到相同的结果。

4

1 回答 1

0

这些错误的原因被证明是相当不直观的。

.Net DLL 封装的本机库由各种模块组成,每个模块都有自己的 DLL,每个模块都封装了第三方库或提供类似插件的功能。其中一些本机 DLL 是在没有清单的情况下链接的。

虽然 .Net 包装器和插件之间没有直接链接,但缺少清单似乎会导致运行时错误 (R6034)。链接到这些库的本机应用程序没有类似的运行时错误,因此在加载本机 DLL 时,.Net 程序集的程序加载程序的行为必须不同。

告诉链接器包含所有本机库的清单似乎可以解决问题并且不会损坏本机应用程序。

于 2012-05-24T14:35:16.373 回答