MSDNドキュメントから、DllMainエントリポイント関数でLoadLibrary/FreeLibraryを呼び出さないようにする必要があることがわかります。
エントリポイント関数は、単純な初期化または終了タスクのみを実行する必要があります。LoadLibraryまたはLoadLibraryEx関数(またはこれらの関数を呼び出す関数)を呼び出さないでください。これにより、DLLのロード順序に依存関係ループが作成される可能性があります。これにより、システムが初期化コードを実行する前にDLLが使用される可能性があります。同様に、エントリポイント関数は、プロセスの終了時にFreeLibrary関数(またはFreeLibraryを呼び出す関数)を呼び出さないでください。これにより、システムが終了コードを実行した後にDLLが使用される可能性があります。
私の質問は、ExitInstance()からFreeLibraryを呼び出すことはできますか?例えば:
Test.exe-メインの実行可能ファイル
HINSTANCE hDllMFC = LoadLibrary(L"TestApp.dll");
if (hDllMFC != NULL)
{
FreeLibrary(hDllMFC);
}
while unload the hDllMFC, the call stack looks like:
TestApp.dll!CTestAppApp::ExitInstance() Line 42 C++
TestApp.dll!InternalDllMain() Line 155 C++
TestApp.dll!DllMain() Line 272 C++
TestApp.dll!__DllMainCRTStartup() Line 512 C
TestApp.dll!_DllMainCRTStartup() Line 477 C
ntdll.dll!LdrpUnloadDll() Unknown
ntdll.dll!LdrUnloadDll() Unknown
KernelBase.dll!FreeLibrary() Unknown
Test.exe!wmain() Line 17 C++
TestApp.dll -MFCに動的にリンクされた通常のDLL
CTestApp theApp;
HINSTANCE hDllResource = NULL;
BOOL CTestApp::InitInstance()
{
hDllResource = ::LoadLibrary(L"TestApp_Resource.dll");
return CWinApp::InitInstance();
}
int CTestApp::ExitInstance()
{
::FreeLibrary(hDllResource);
return CWinApp::ExitInstance();
}
TestApp_Resource.dll-通常のDLL、リソース
..。
すべきではないと思いますが、CWinApp :: ExitInstance()の実装から、リソースdllをアンロードしようとしていたことがわかります。これは、ExitIntance()でFreeLibraryを呼び出すことができるという意味ですか?
int CWinApp::ExitInstance()
{
//...
if (m_hLangResourceDLL != NULL)
{
::FreeLibrary(m_hLangResourceDLL);
m_hLangResourceDLL = NULL;
}
//...
}
また、Win95のExitInstanceからFreeLibraryを呼び出しているときにバグがあることを確認するドキュメントを見つけました。
バグ:ExitInstancehttp ://support.microsoft.com/kb/187684からAfxFreeLibraryを呼び出すときにアサートする
ステータス:マイクロソフトは、これがWindows 95のバグであることを確認しています。このバグを調査しており、利用可能になり次第、マイクロソフトナレッジベースに新しい情報を掲載します。