我假设读者熟悉混合托管/非托管代码系统以及它们为什么是必要的。这个问题不会涉及这个问题,而是使用 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 "_DEBUG" /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 "_DEBUG" /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