从MSDN文档中,我们可以看到,我们不应该在DllMain入口点函数中调用LoadLibrary/FreeLibrary。
入口点函数应仅执行简单的初始化或终止任务。它不能调用LoadLibrary或LoadLibraryEx函数(或调用这些函数的函数(,因为这可能按照DLL加载顺序创建依赖循环。这可能导致DLL在系统执行其初始化代码之前使用。同样,入口点函数也不能调用FreeLibrary函数(或调用FreeLibrary的函数(终止,因为这可能导致DLL在系统已执行其终止代码。
我的问题是:我们可以从ExitInstance((调用FreeLibrary吗例如:
测试.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时存在错误。
BUG:从ExitInstance调用AfxFreeLibrary时断言http://support.microsoft.com/kb/187684
状态:Microsoft已确认这是Windows 95中的一个错误。我们是正在研究此错误,并将在可用的Microsoft知识库。
如果事实上是从DllMain调用ExitInstance(由堆栈跟踪确认(,则适用DllMain的所有规则,包括禁止递归加载或卸载其他DLL。(请注意,将您的CWinApp放入DLL中是非常不寻常的,MFC可能会有其他问题,例如KB文章中提到的问题。不是说存在或没有更多问题,而是添加了一个额外的注意事项。(