如何: 如何提供自己 DllMain MFC 的规则 DLL 中
2017-05-03 15:07
405 查看
概要
按照设计,MFC 的规则 Dll 具有 MFC 将自动提供一个默认 DllMain 函数。规则 Dll 不应提供自己 DllMain。应在规则 DLL 中的一个 CWinApp 派生类的 InitInstance 成员函数 DLL 加载时需要的任何初始化。取消初始化和终止代码应放在 ExitInstance 成员函数中。
但是,由 MFC 的 DllMain 进程附加到 DLL (DLL_PROCESS_ATTACH) 和仅当进程与 DLL 分离 (DLL_PROCESS_DETACH) 时,调用 ExitInstance 时才调用 InitInstance。如果有必要处理线程接触和分离 (DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH) 从 MFC 的规则 DLL 中,需要提供其自己 DllMain 规则 DLL。本文介绍了如何执行此操作。
详细信息
创建规则 DLL 时,MFC 源强制链接源文件 \Msdev\Mfc\Src\Dllmodul.cpp 的代码中。Dllmodul.cpp 包含大部分的代码添加到支持该 DLL 中的 MFC 的规则 DLL。在 Dllmodul.cpp 中的最重要功能之一是 DllMain 函数。
将代码添加到 MFC 的 DllMain,将 \Msdev\Mfc\Src\Dllmodul.cpp 文件复制到项目目录中,并包括在项目中复制。这份 Dllmodul.cpp 用于编译和链接到您的 DLL 而不是在 Mfc\Src 目录中,Dllmodul.cpp,所以在 DllMain 更改会显示在最终的 DLL。
主要需要说明的是这并不是推荐的解决方案,并应在绝对必要时才使用。对 Dllmodul.cpp 中的代码的任何更改将肯定会有不可预知的结果。添加代码只、 不要删除或修改现有的代码。
有关在共享库中使用 MFC 的规则 Dll,模块状态应该设置任何添加的代码的开头,并从 DllMain 返回之前恢复。DllMain,处理 DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH 通知并正确切换模块状态所需的示例,请参阅本文中的示例代码。
依赖于 DllMain 由于以下情况而被称为 DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH 时,必须考虑特别加以注意:
在进程中创建线程时,系统会调用 DllMain 值为 DLL_THREAD_ATTACH 每个 Dll 映射到流程中。但是,如果进程有了新的 DLL 映射到它在运行中的多个线程,DllMain 不调用 DLL_THREAD_ATTACH 值与任何现有的线程。
进程的主线程的值 DLL_THREAD_ATTACH,不会调用 DllMain。
线程终止时 (通过调用 ExitThread),在 DllMain 每个 Dll。 DllMain 不称为 DLL_THREAD_DETACH 的任何线程除非线程终止通过调用 ExitThread 与 DLL_THREAD_DETACH 的值调用。
如果线程终止由于对 TerminateThread 的调用,DLL_THREAD_DETACH 的值不调用 DllMain。
有可能一个线程在调用则加载 DLL 与 DLL_PROCESS_ATTACH,导致调用 DllMain,然后在线程终止导致 dllMain 调用 DLL_THREAD_DETACH 而不会调用 DLL_THREAD_ATTACH 的进程中。因此,最佳的线程调用则还调用句是。
注意: MFC CWnd 对象、 CDC 对象、 CMenu 对象、 GDI 对象和 CImageList 对象被限制为每个线程,每个模块的基础。换句话说,在一个模块或线程创建的 MFC 对象不能是传递到或在不同的模块或线程中使用。这有特殊的相关性,因为 DllMain 调用这些原因与不同线程处理 DLL_THREAD_ATTACH 或 DLL_THREAD_DETACH 在 DllMain 中的添加任何代码。在 DLL_THREAD_ATTACH 期间,CWnd 对象,例如,创建在 DllMain 期间 DLL_PROCESS_ATTACH 或 InitInstance 中将无效。
示例代码
转:http://www.cnblogs.com/helloboyang/p/5237648.html
按照设计,MFC 的规则 Dll 具有 MFC 将自动提供一个默认 DllMain 函数。规则 Dll 不应提供自己 DllMain。应在规则 DLL 中的一个 CWinApp 派生类的 InitInstance 成员函数 DLL 加载时需要的任何初始化。取消初始化和终止代码应放在 ExitInstance 成员函数中。
但是,由 MFC 的 DllMain 进程附加到 DLL (DLL_PROCESS_ATTACH) 和仅当进程与 DLL 分离 (DLL_PROCESS_DETACH) 时,调用 ExitInstance 时才调用 InitInstance。如果有必要处理线程接触和分离 (DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH) 从 MFC 的规则 DLL 中,需要提供其自己 DllMain 规则 DLL。本文介绍了如何执行此操作。
详细信息
创建规则 DLL 时,MFC 源强制链接源文件 \Msdev\Mfc\Src\Dllmodul.cpp 的代码中。Dllmodul.cpp 包含大部分的代码添加到支持该 DLL 中的 MFC 的规则 DLL。在 Dllmodul.cpp 中的最重要功能之一是 DllMain 函数。
将代码添加到 MFC 的 DllMain,将 \Msdev\Mfc\Src\Dllmodul.cpp 文件复制到项目目录中,并包括在项目中复制。这份 Dllmodul.cpp 用于编译和链接到您的 DLL 而不是在 Mfc\Src 目录中,Dllmodul.cpp,所以在 DllMain 更改会显示在最终的 DLL。
主要需要说明的是这并不是推荐的解决方案,并应在绝对必要时才使用。对 Dllmodul.cpp 中的代码的任何更改将肯定会有不可预知的结果。添加代码只、 不要删除或修改现有的代码。
有关在共享库中使用 MFC 的规则 Dll,模块状态应该设置任何添加的代码的开头,并从 DllMain 返回之前恢复。DllMain,处理 DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH 通知并正确切换模块状态所需的示例,请参阅本文中的示例代码。
依赖于 DllMain 由于以下情况而被称为 DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH 时,必须考虑特别加以注意:
在进程中创建线程时,系统会调用 DllMain 值为 DLL_THREAD_ATTACH 每个 Dll 映射到流程中。但是,如果进程有了新的 DLL 映射到它在运行中的多个线程,DllMain 不调用 DLL_THREAD_ATTACH 值与任何现有的线程。
进程的主线程的值 DLL_THREAD_ATTACH,不会调用 DllMain。
线程终止时 (通过调用 ExitThread),在 DllMain 每个 Dll。 DllMain 不称为 DLL_THREAD_DETACH 的任何线程除非线程终止通过调用 ExitThread 与 DLL_THREAD_DETACH 的值调用。
如果线程终止由于对 TerminateThread 的调用,DLL_THREAD_DETACH 的值不调用 DllMain。
有可能一个线程在调用则加载 DLL 与 DLL_PROCESS_ATTACH,导致调用 DllMain,然后在线程终止导致 dllMain 调用 DLL_THREAD_DETACH 而不会调用 DLL_THREAD_ATTACH 的进程中。因此,最佳的线程调用则还调用句是。
注意: MFC CWnd 对象、 CDC 对象、 CMenu 对象、 GDI 对象和 CImageList 对象被限制为每个线程,每个模块的基础。换句话说,在一个模块或线程创建的 MFC 对象不能是传递到或在不同的模块或线程中使用。这有特殊的相关性,因为 DllMain 调用这些原因与不同线程处理 DLL_THREAD_ATTACH 或 DLL_THREAD_DETACH 在 DllMain 中的添加任何代码。在 DLL_THREAD_ATTACH 期间,CWnd 对象,例如,创建在 DllMain 期间 DLL_PROCESS_ATTACH 或 InitInstance 中将无效。
示例代码
转:http://www.cnblogs.com/helloboyang/p/5237648.html
//////////////////////////////////////////////////////////////////// // export DllMain for the DLL // Add code in the specified sections only. // Remove code at your own risk. extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { if (dwReason == DLL_PROCESS_ATTACH) { // ... Code abbreviated from DLLMODUL.CPP } else if (dwReason == DLL_PROCESS_DETACH) { // ... Code abbreviated from DLLMODUL.CPP } // NEW CODE ADDED HERE // ------------------- else if (dwReason == DLL_THREAD_ATTACH) { #ifdef _AFXDLL // set module state ASSERT(AfxGetThreadState()->m_pPrevModuleState == NULL); AfxGetThreadState()->m_pPrevModuleState = AfxSetModuleState(AfxGetStaticModuleState()); #endif // ADD DLL_THREAD_ATTACH CODE HERE // Remember that this won't necessarily be called for // every thread in the process into which this DLL is mapped // Threads created by the process BEFORE the DLL // was loaded will not call into DLL_THREAD_ATTACH. #ifdef _AFXDLL // restore previously-saved module state VERIFY(AfxSetModuleState(AfxGetThreadState()->m_pPrevModuleState) == AfxGetStaticModuleState()); DEBUG_ONLY(AfxGetThreadState()->m_pPrevModuleState = NULL); #endif } else if (dwReason ==DLL_THREAD_DETACH) { #ifdef _AFXDLL // set module state ASSERT(AfxGetThreadState()->m_pPrevModuleState == NULL); AfxGetThreadState()->m_pPrevModuleState = AfxSetModuleState(AfxGetStaticModuleState()); #endif // ADD DLL_THREAD_DETACH CODE HERE #ifdef _AFXDLL // restore previously-saved module state VERIFY(AfxSetModuleState(AfxGetThreadState()->m_pPrevModuleState) == AfxGetStaticModuleState()); DEBUG_ONLY(AfxGetThreadState()->m_pPrevModuleState = NULL); #endif } return TRUE; }
相关文章推荐
- 如何提供自己 DllMain MFC 的规则 DLL 中
- 如何: 如何提供自己 DllMain MFC 的规则 DLL 中
- 如何在MFC DLL工程添加DllMain入口
- 如何给Win32 DLL添加MFC支持?(Dllmain重定义的问题)
- MFC Regular DLL 中自己 DllMain
- 如何在mfc dll中加入dllmain
- 如何提供对 MFC 对话框为您自己窗口类名
- VC++动态链接库编程之MFC规则DLL
- VC++动态链接库编程之MFC规则DLL
- 在dreamweaver里如何引用自己写的组件dll里的方法
- 如何在MFC里写自己的自定义消息
- 如何在最短的时间内找到自己需要的信息:现有技术实现信息提供的方式总结[原创]
- VC++动态链接库编程之MFC规则DLL
- VC++动态链接库(DLL)编程(三)――MFC规则DLL
- 如何给自己的程序增加插件功能-用DLL做插件
- 如何为 MFC 应用程序创建本地化资源 DLL
- MFC规则DLL
- VC++动态链接库编程之MFC规则DLL
- 如何在MFC里写自己的自定义消息
- 如何在C#中加载自己编写的动态链接库(DLL)