【发布时间】:2011-04-04 18:46:12
【问题描述】:
所以我一直在尝试使用 Visual Studio 测试环境在我的解决方案上设置测试。设置如下所示:
Third party native library --> Managed C++ wrapper DLL --> C# project being tested
^ ^
Foundation C# Projects -----------------|------------------------|
有两个理论上可互换的第三方库和相应的包装器。我需要能够同时支持两者。
所以,当我运行我的测试项目时,会发生以下情况:
- 被测项目加载成功
- 基础 C# 项目加载成功
- C++ 包装 A 加载失败;如果我使用包装器 B,一切都很好。
包装器 A 的异常调用栈是:
mscorlib.dll!System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(int errorCode) + 0x23 bytes
msvcm90d.dll!<CrtImplementationDetails>::DoCallBackInDefaultDomain(int* function = 0x1018E1D0, bool cookie = false) Line 451 C++
[Native to Managed Transition]
[Managed to Native Transition]
Wrapper.dll!<CrtImplementationDetails>::DefaultDomain::Initialize() Line 284 C++
Wrapper.dll!<CrtImplementationDetails>::LanguageSupport::InitializeDefaultAppDomain() Line 519 C++
Wrapper.dll!<CrtImplementationDetails>::LanguageSupport::_Initialize() Line 730 C++
Wrapper.dll!<CrtImplementationDetails>::LanguageSupport::Initialize() Line 876 C++
Wrapper.dll!?.cctor@@$$FYMXXZ() Line 922 + 0x9 bytes C++
[Native to Managed Transition]
[Managed to Native Transition]
TestProject.dll!TestProject.TestProjectBase.TestProjectBase() Line 44 + 0x8 bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
TestProject.dll!TestProject.Test.Test() Line 17 + 0x8 bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter.dll!Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.CreateTestClassInstance() + 0x174 bytes
我确实在网上搜索了这个,发现很多人都在询问同一个调用堆栈,但响应方式却很少。
我查看了 ProcMon 的情况。我比较了加载包装器 A 和包装器 B 时发生的情况。在包装器 B 完成加载之前,情况似乎或多或少相同。同时,包装器 A 莫名其妙地重新开始加载,这次尝试加载测试项目已经加载的 C# 基础 DLL。但它没有找到这些 DLL,因为 DLL 搜索路径不包含测试文件夹(它在 GAC 和 VSTestHost 目录中查找 DLL)。
我注意到的另一件事是 C# 代码没有在默认的 appdomain 中运行。所以我的理论是以下情况正在发生:
- 包装器 A 尝试在沙盒应用程序域中加载。
- 发生了什么事让系统认为 Wrapper A 没有成功加载
- 系统尝试在默认应用程序域中加载 Wrapper A。在此 appdomain 中,未加载 C# DLL,因此它尝试加载但失败。
那么,什么给了?第 2 步可能会发生什么?包装器 B 会成功加载而包装器 A 不会加载的可能原因有哪些?
如果您想知道包装器 A 和包装器 B 有何不同:它们的项目具有相同的设置,并且支持相同的接口;否则它们是完全不同的。但我想知道可能导致这种情况的差异。
我应该补充一点,如果我将 DLL 添加到 GAC 或将它们复制到 VSTestHost 目录,包装器 A 会找到 DLL 并成功加载。但是,我仍然想了解发生了什么问题。
【问题讨论】:
-
你的 Wrapper A 在做什么?它是否以原生 C++ 代码的形式开始生命,然后开始运行托管代码?
标签: c# .net visual-studio-2008 dll vstesthost