我们可以从ExitInstance调用FreeLibrary [英] Can we call FreeLibrary from ExitInstance

查看:144
本文介绍了我们可以从ExitInstance调用FreeLibrary的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从MSDN文档可以看出,我们不应该在DllMain入口点函数中调用LoadLibrary / FreeLibrary。

From the MSDN document, we can see that, we should not call LoadLibrary/FreeLibrary in the DllMain entry point function.


入门点功能只能执行简单的初始化或
终止任务。它不能调用LoadLibrary或LoadLibraryEx
函数(或调用这些函数的函数),因为这可能是
在DLL加载顺序中创建依赖循环。这可能导致在系统执行其初始化代码之前使用
DLL。
类似地,入门点函数不能在进程
终止期间调用FreeLibrary
函数(或调用FreeLibrary的函数),因为这可能导致在$ b之后使用DLL $ b系统已执行终止代码。

The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary) during process termination, because this can result in a DLL being used after the system has executed its termination code.

我的问题是:可以从ExitInstance()调用FreeLibrary吗? strong>例如:

My question is: Can we call FreeLibrary from ExitInstance()? for example:

Test.exe - 主可执行文件

Test.exe - main executable

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

TestApp.dll - Regular DLLs dynamically linked to MFC

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,资源

TestApp_Resource.dll - Regular DLLs, resource

...

我认为我们不应该,但是从CWinApp :: ExitInstance()我们可以看到,它也试图卸载资源dll。这是否意味着我们可以在ExitIntance()中调用FreeLibrary?

I think we should not, but from the implmentation of CWinApp::ExitInstance(), we can see that, it was also trying to unload the resource dll. Does that mean we can call FreeLibrary in the ExitIntance()?

int CWinApp::ExitInstance()
{
  //... 

 if (m_hLangResourceDLL != NULL)
  {
    ::FreeLibrary(m_hLangResourceDLL);
    m_hLangResourceDLL = NULL;
  }
  //...
}

我也在Win95中从ExitInstance调用FreeLibrary时发现一个文件,确认有一个错误。

I also found a document which confirm there is a bug while calling FreeLibrary from ExitInstance in Win95.

BUG:Assert从ExitInstance调用AfxFreeLibrary
http://support.microsoft.com/kb/187684

BUG: Assert When Calling AfxFreeLibrary from ExitInstance http://support.microsoft.com/kb/187684


状态:Microsoft已经确认这是Windows 95中的一个错误。我们是
研究这个错误,并将在
中发布新信息Microsoft知识库可用。

STATUS: Microsoft has confirmed this to be a bug in Windows 95. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.


推荐答案

如果事实上ExitInstance正在从DllMain (通过堆栈跟踪确认),然后适用于DllMain的所有规则,包括禁止递归或卸载其他DLL。 (请注意,将您的CWinApp放在DLL中是非常不寻常的,MFC可能会遇到其他问题,例如知识库文章中提到的问题,而不是说没有或没有更多的问题潜伏着,而是添加了一个额外的注释谨慎。)

If in fact ExitInstance is being called from DllMain (as confirmed by the stack trace) then all the rules for DllMain apply, including the prohibition on loading or unloading other DLLs recursively. (Note that putting your CWinApp in a DLL is highly unusual and MFC may have other issues with it, such as the one noted in the KB article. Not saying that there are or are not any more issues lurking, but adding a note of additional caution.)

这篇关于我们可以从ExitInstance调用FreeLibrary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆