.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から到達可能なすべてのコードを追跡し、すべてがでコンパイルされていることを確認し#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が他のマネージ関数を間接的に呼び出した場合、コンパイラーは警告を生成しないため、発生しないようにする必要があります。そうしないと、アプリケーションがランダムにデッドロックする可能性があります。