2

我假设读者熟悉混合托管/非托管代码系统以及它们为什么是必要的。这个问题不会涉及这个问题,而是使用 Visual Studio 2008 编译器和链接器控件构建这样一个系统的机制。

的背景

首先,摆脱谷壳。我的调查总结如下:

  • 初始 C++ 项目基于 MFC
  • 共享 dll 中的 MFC
  • 没有 clr
  • C++ 异常/EHa
  • 多线程调试/MD

这一切都在 Visual Studio 2008 下的所有开发人员工作站上正确构建和运行。

我们现在将第三方 C# .NET3.5 SP1 库包含到项目中。该库是使用用于互操作的本机 C++ 桥构建的。原始 C++ 项目引用此新库的导入文件作为其链接器输入的一部分。所有非常标准的东西,并在论坛上得到很好的参考。

第三方库构建如下:

  • 公共语言运行时支持 /clr
  • C++ 异常/EHa
  • 多线程调试/MD

问题

在我们的八个开发人员工作站上,调试(和发布)构建所有构建和启动都正确。我们只有一个开发人员工作站在启动时出现以下错误:

Windows 在 blah.exe 中触发了断点。
这可能是由于堆中的损坏,这表明 blah.exe 或其已加载的任何 DLL 中存在错误。

这一切都发生在应用程序启动之前,并且被证明难以追踪。我已经使用/尝试/消除了以下内容:

  • 配置不正确的工作站。也就是说,没有两个工作站是完全相同的。是的,它们都具有相同的工具和操作系统 (Windows-7),但除此之外,它们的配置会略有不同。
  • 依赖步行者
  • 过程分析工具 (ProcMon)
  • 静态库的构建彼此不一致,导致堆不匹配。编译器开关 /MD 与两个代码库对齐。话虽如此,CLR 的堆总是与本机代码的堆不同。

解决方案

如果我现在只需打开C++ 构建的/clr ,所有问题都会消失。为什么?我怀疑两个代码空间现在将使用相同的堆。不同的运行时环境肯定是混合模式的全部内容吗?这不是优选的解决方案。

最新信息

Visual Studio 调试窗口报告以下内容:

* “blah.exe”中发生访问冲突:

747220A3 处的指令尝试从无效地址 00000B90 读取

  • 输入 .exr 00032690 作为异常记录
  • 输入 .cxr 000326AC 作为上下文
  • 然后 kb 获取故障堆栈

blah.exe 中 0x747220a3 (MSCTF.dll) 的第一次机会异常:0xC0000005:访问冲突读取位置 0x00000b90。

附录

C++ 项目编译器选项(调试构建):

/Od /D "WIN32" /D "_WINDOWS" /D "_D​​EBUG" /D "_VC80_UPGRADE=0x0710" /D "_AFXDLL" /D "_MBCS" /FD /EHa /MDd /Yu"stdafx.h" /Fp" Debug\blah.pch" /Fo"Debug\" /Fd"Debug\vc90.pdb" /W3 /WX /nologo /c /Zi /clr /TP /wd4793 /wd4996 /errorReport:prompt

C++ 项目链接器选项(调试构建):

/OUT:"..\Debug\blah.exe" /INCREMENTAL /NOLOGO /MANIFEST /MANIFESTFILE:"Debug\blah.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /ASSEMBLYDEBUG /PDB:"blah.pdb" /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE /DYNAMICBASE:NO /FIXED:No /MACHINE:X86 /ERRORREPORT:PROMPT iphlpapi.lib UxTheme.lib ../Libraries/Bridge.lib

C# .NET 库编译器选项(调试构建):

/Od /D "WIN32" /D "_D​​EBUG" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /FD /EHa /MDd /Yu"stdafx.h" /Fp"Debug\Bridge.pch" / Fo"Debug\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /Zi /clr /TP /errorReport:prompt /FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System. dll" /FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll" /FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.XML.dll" /FU“库.dll”

C# .NET 库链接器选项(调试版本):

/OUT:"Bridge.dll" /INCREMENTAL /NOLOGO /DLL /MANIFEST /MANIFESTFILE:"Debug\Bridge.dll.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /ASSEMBLYDEBUG / PDB:"Bridge.pdb" /DYNAMICBASE /FIXED:No /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT

4

1 回答 1

1

只需将 DELAY LOAD 应用于有问题的 DLL,即可解决该问题。我只能假设这将其从启动负载中删除,因此避免了启动冲突。

当首次使用该功能时,该 DLL 会在以后的任何时间加载。它在所有工作站上都​​能正常运行。

于 2012-07-19T11:25:20.650 回答