Итак, я пытался настроить тесты для своего решения, используя среду тестирования 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).
Еще одна вещь, которую я заметил, это то, что код C # не запускается в домене приложения по умолчанию. Итак, моя теория заключается в том, что происходит следующее:
- Wrapper A пытается загрузить домен приложения в песочнице.
- Что-то происходит, чтобы заставить систему думать, что Wrapper A не загрузился успешно
- Система пытается загрузить Wrapper A в домене приложения по умолчанию. В этом домене приложения библиотеки DLL C # не загружаются, поэтому он пытается и не может их загрузить.
Итак, что дает? Что может происходить на шаге 2? Каковы некоторые возможные причины, по которым оболочка B успешно загружается, а оболочка A - нет?
В случае, если вам интересно, чем отличаются оболочка A и оболочка B: их проекты имеют одинаковые параметры и поддерживают одинаковые интерфейсы; в противном случае они совершенно разные. Но я хотел бы знать, какие различия могут привести к этой ситуации.
Я должен добавить, что, если я добавлю DLL в GAC или скопирую их в каталог VSTestHost, оболочка A найдет DLL и успешно загрузится. Тем не менее, я все еще хотел бы понять, что происходит не так.