そのため、VisualStudioのテスト環境を使用してソリューションのテストをセットアップしようとしています。セットアップは次のようになります。
Third party native library --> Managed C++ wrapper DLL --> C# project being tested
^ ^
Foundation C# Projects -----------------|------------------------|
対応するラッパーを持つ2つの理論的に交換可能なサードパーティライブラリがあります。両方をサポートできる必要があります。
したがって、テストプロジェクトを実行すると、次のようになります。
- テスト対象のプロジェクトが正常に読み込まれます
- 基盤の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を検索します)。
私が気付いたもう1つのことは、C#コードがデフォルトのappdomainで実行されていないことです。だから私の理論は、次のことが起こっているということです:
- ラッパーAは、サンドボックス化されたアプリドメインにロードしようとします。
- ラッパーAが正常にロードされなかったとシステムに思わせる何かが発生しました
- システムは、デフォルトのappdomainにラッパーAをロードしようとします。このアプリドメインでは、C#DLLが読み込まれないため、読み込みを試みて失敗します。
それで、何が得られますか?ステップ2で何が起こっている可能性がありますか?ラッパーBが正常にロードされ、ラッパーAがロードされない理由として考えられるものは何ですか?
ラッパーAとラッパーBがどのように異なるのか疑問に思われる場合:それらのプロジェクトは同じ設定を持ち、同じインターフェースをサポートします。そうでなければ、それらは完全に異なります。しかし、どのような違いがこの状況につながる可能性があるのか知りたいです。
DLLをGACに追加するか、VSTestHostディレクトリにコピーすると、ラッパーAがDLLを検出し、正常にロードされることを追加する必要があります。しかし、私はまだ何が悪いのかを理解したいと思います。