98

C# でコードを記述して、C++ dll を構築しています。

エラーが表示されます

LoaderLock が検出されました メッセージ: OS ローダー ロック内でマネージ実行を試みています。アプリケーションがハングする可能性があるため、DllMain またはイメージ初期化関数内でマネージ コードを実行しようとしないでください。

このエラーが正確に何を意味するのかを検索しようとしましたが、無意味な記事を描いています。ほとんどの場合、それは単なる警告であり、Visual Studio でそれをオフにする必要があります。他の解決策は ITunes、または DirectX でのプログラミング時に発生するこの問題が原因のようです。私の問題はどちらにも接続されていません。

これが実際に何を意味するのか、誰か説明できますか?

4

9 に答える 9

72

メニューの [Debug] -> [Exceptions] に移動し、[Managed Debugging Assistants] を開き、[LoaderLock] を見つけてチェックを外す必要があります

http://goo.gl/TGAHV

于 2010-11-04T08:04:27.303 に答える
52

ローダー ロックの一般的な考え方: システムは DllMain のコードをロック内で実行します (同期ロックのように)。したがって、ここで説明されているように、DllMain 内で重要なコードを実行すると、「デッドロックが発生する」ことになります。

問題は、なぜ DllMain 内でコードを実行しようとしているのですか? このコードを DllMain のコンテキスト内で実行することは重要ですか?それとも、DllMain 内でコードの実行が完了するのを待たずに、新しいスレッドを生成してその中でコードを実行できますか?

具体的には、管理されたコードの問題は、管理されたコードを実行するとCLRなどをロードする可能性があり、そこで何が起こり、デッドロックが発生するかがわからないことだと思います...「この警告を無効にする」というアドバイスには耳を傾けませんほとんどの場合、シナリオによってはアプリケーションが予期せずハングすることがあるからです。

于 2008-09-11T14:18:36.723 に答える
19

.NET 4.0 以降の最新フレームワークの更新

これは、.Net 2.0 の時点で尋ねられた古い質問です。混合モードの DLL のサポートには深刻な初期化の問題があり、ランダムなデッドロックが発生する傾向がありました。.Net 4.0 以降、混合モード DLL の初期化が変更されました。現在、初期化には 2 つの段階があります。

  1. DLL のエントリ ポイントで呼び出されるネイティブ初期化。これには、ネイティブ C++ ランタイム セットアップと DllMain メソッドの実行が含まれます。
  2. システムローダーによって自動的に実行される管理された初期化。

ステップ 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 が他のマネージ関数を間接的に呼び出す場合、コンパイラは警告を生成しないため、警告が発生しないようにする必要があります。そうしないと、アプリケーションがランダムにデッドロックする可能性があります。

于 2016-03-20T23:29:12.470 に答える
6

ctr d+e を押してから、Managed Debugging Assistants ノードを展開します。次に、LoaderLock のチェックを外しました。

これがあなたを助けることを願っています。

于 2012-07-18T06:37:09.540 に答える
4

最近、ネイティブ コードで記述された COM オブジェクトのインスタンスを作成しているときに、次のエラーが発生しました。

m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy"));

これにより、説明されているエラーが発生しました。「LoaderLock が検出されました」-例外がスローされました。

追加のスレッドでオブジェクト インスタンスを作成することで、このエラーを克服しました。

ThreadStart threadRef = new ThreadStart(delegate { m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy")); });
Thread myThread = new Thread(threadRef);

myThread.Start();
myThread.Join(); // for synchronization
于 2015-07-09T15:41:58.463 に答える
3

アンマネージ DLL を呼び出し、アンマネージ コードを定義する必要がある C++ CLR DLL (MSVS2015) を構築しています。#pragma managed と #pragma unmanaged を使用して、コードの特定の領域のモードを制御します。

私の場合、 #pragma unmanaged を DllMain() の前に置くだけで、問題は解決しました。DllMain() のマネージ バージョンが必要だと考えているようです。

于 2016-07-15T13:10:59.143 に答える
2

この問題は、Visual Studio のデバッガーが、1 つまたは複数の DLL ファイルで Microsoft Foundation Classes バージョン 8.0 を使用するマネージ アプリケーションを実行する方法が原因で発生します。

http://msdn.microsoft.com/en-us/library/aa290048(vs.71).aspxをよく読んでください。

于 2012-07-13T00:18:46.637 に答える
2

Visual Studio 2017 インスタンスの設定パスは Debug -> Windows -> Exception Settings です。例外設定の「ウィンドウ」が (別のウィンドウではなく) 一番下のタブ グループに表示されたので、気付くのに時間がかかりました。「ローダー」で検索してください。

于 2018-10-22T18:11:19.660 に答える