2

私は最近、純粋にアンマネージ コード (Visual Studio 6 でコンパイルされた C++ および VB6 コンポーネント) で開発されたアプリケーションの 1 つに .NET NLog ログ コンポーネントを統合しました。COM インターフェイスを介して NLog と通信する C++ アプリケーションが多数あります。

現時点ではすべて正常に動作していますが、プログラムの終了中に次のメッセージがポップアップすることに気付きました (VS6 で C++ コンポーネントをデバッグしている場合は出力ウィンドウに、VS 2005 経由で NLog をデバッグしている場合は IDE のプロンプトとして)。

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

DllMain は次のとおりです。

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

私の推測では_Module.Term();、いくつかの .NET 参照のリリースが含まれており (毎回インスタンス化してリリースする必要がないように、C++ クラスの 1 つで NLog オブジェクトへの参照を保持しています)、この警告がポップアップ表示されます。

私の質問: これは無視しても安全ですか? そうでない場合、適切な回避策は何ですか? (私が考えることができる最善の方法は、そのNLogオブジェクトへの参照をインスタンス化し、ログファイルに書き込みたいたびにそれを解放することです...最も洗練されたソリューションではありません)

4

2 に答える 2

6

このメッセージを無視するのは絶対に安全ではありません。このメッセージが表示された場合、ほぼ確実に実際のローダー ロック ポリシー違反が発生しています。これは非常に重大なエラーであり、プログラムで予期しない動作 (デッドロックを含む) を引き起こす可能性があります。

これを回避する最善の方法は、DLL main 内で直接的または間接的に他の .Net オブジェクト/関数にアクセスしないことです。あなたの場合、別のキャッシュ ポリシーを使用するのがおそらく最善です。おそらく、.Net 参照を保持する参照カウント オブジェクトを作成します。そうすれば、アンロードのために DllMain が呼び出される前にオブジェクトが解放されます (すべてのオブジェクトが破棄されるまで、dll をアンロードできません)。

于 2009-01-29T04:57:35.027 に答える
2

無視しないでください。アンマネージ C++ DLL を使用する C# アプリの起動時に LoaderLock の問題が発生しました。この場合、一部の DLL コード (Linux から移植) には、ロード中の初期化時にファイルにアクセスする静的変数が含まれていました。統計がクリーンアップされると、LoaderLock の問題が修正されました。同様に、クリーンアップ中にファイルにアクセスする C/C++ 静的がある場合、これが LoaderLock に寄与している可能性があります。

于 2009-01-29T06:24:43.853 に答える