.NET 4.0 以降の最新フレームワークの更新
これは、.Net 2.0 の時点で尋ねられた古い質問です。混合モードの DLL のサポートには深刻な初期化の問題があり、ランダムなデッドロックが発生する傾向がありました。.Net 4.0 以降、混合モード DLL の初期化が変更されました。現在、初期化には 2 つの段階があります。
- DLL のエントリ ポイントで呼び出されるネイティブ初期化。これには、ネイティブ C++ ランタイム セットアップと DllMain メソッドの実行が含まれます。
- システムローダーによって自動的に実行される管理された初期化。
ステップ 2 はローダー ロックの外で実行されるため、デッドロックは発生しません。詳細は、混合アセンブリの初期化で説明されています。
混合モード アセンブリをネイティブ実行可能ファイルから確実に読み込めるようにするために確認する必要があるのは、DllMain メソッドがネイティブ コードとして宣言されていることだけです。#pragma unmanaged
ここで役立ちます:
#pragma unmanaged
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
... // your implementation here
}
また、DllMain が直接または間接的に呼び出す可能性のあるコードもアンマネージであることも重要です。DllMain で使用される機能の種類を制限して、DllMain から到達可能なすべてのコードをトレースし、すべてが .NET でコンパイルされていることを確認することは理にかなっています#pragma unmanaged
。
コンパイラは、DllMain がアンマネージとして宣言されていないことを検出した場合、警告 C4747 を提供することで少し役立ちます。
1> Generating Code...
1>E:\src\mixedmodedll\dllmain.cpp : warning C4747: Calling managed 'DllMain': Managed code may not be run under loader lock, including the DLL entrypoint and calls reached from the DLL entrypoint
ただし、DllMain が他のマネージ関数を間接的に呼び出す場合、コンパイラは警告を生成しないため、警告が発生しないようにする必要があります。そうしないと、アプリケーションがランダムにデッドロックする可能性があります。