4

別の DLL を動的に複数回呼び出す必要がある DLL を作成しています。呼び出し先をロードしたままにして、DLL がアンロードされたときにアンロードしたいと思います。しかし、Microsoft によれば、それは悪い考えです。

エントリ ポイント関数は、単純な初期化タスクのみを実行する必要があり、他の DLL の読み込みまたは終了関数を呼び出してはなりません。たとえば、エントリ ポイント関数では、LoadLibrary 関数または LoadLibraryEx 関数を直接的または間接的に呼び出すべきではありません。さらに、プロセスの終了時に FreeLibrary 関数を呼び出さないでください。

これが問題のコードです。DLL のエントリ ポイントから LoadLibrary と FreeLibrary を呼び出すべきではない理由を誰か説明できますか?

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
switch (ul_reason_for_call) {
    case DLL_PROCESS_DETACH :
            if (hLogLib != NULL) FreeLibrary(hLogLib);
            break;
    }
    return TRUE;
}
4

3 に答える 3

4

は答えを見つけたと思います。

エントリポイント関数は、単純な初期化または終了タスクのみを実行する必要があります。LoadLibrary または LoadLibraryEx 関数 (またはこれらの関数を呼び出す関数) を呼び出してはなりません。これは、DLL の読み込み順序で依存ループが作成される可能性があるためです。これにより、システムが初期化コードを実行する前に DLL が使用される可能性があります。同様に、エントリポイント関数は、プロセスの終了時に FreeLibrary 関数 (または FreeLibrary を呼び出す関数) を呼び出してはなりません。これは、システムが終了コードを実行した後に DLL が使用される可能性があるためです。

于 2009-12-14T21:24:54.923 に答える
2

DLLMain 内で重要なことを行わないでください。真剣に。FreeLibrary の呼び出しは、フリーが refcount をゼロに減らし、ライブラリが実際に解放された場合にデッドロックすることがあるため、さらに悪いことです。

于 2009-12-14T21:27:05.497 に答える
2

DllMain 関数は OS ローダー ロック内で実行され、そのローダー ロックを再取得しようとすると (たとえば、LoadLibrary を呼び出すことによって)、デッドロックが発生するため、エントリ ポイントから LoadLibrary を呼び出すことはできません。

于 2009-12-14T19:57:17.360 に答える