如何在mfc dll中加入dllmain

  

  通过向导创建一个带有mfc的dll,你会发现没有dllmain。那么如何使用dllmain的呢。请看下面解说。引用的是ms:http://support.microsoft.com/kb/q148791/

通过设计,MFC 常规 dll 具有由 MFC 自动提供一个默认 DllMain 函数。规则 dll 不应提供自己 DllMain。 任何初始化,这是必需的 DLL 加载时应进行 InitInstance 成员函数的正则 DLL 中一个 CWinApp 派生类中。代码 deinitialization 和终止代码应转 ExitInstance 成员函数中。

但是,InitInstance 时才调用通过 MFC 的 DllMain 进程将 (DLL_PROCESS_ATTACH) 附加到该 DLL 并仅在进程从 DLL 分离 (DLL_PROCESS_DETACH) 时,将调用 ExitInstance。如果需要处理线程的附件和 MFC 常规 DLL 中的从 (DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH) detachment 常规 DLL 将需要提供其自身 DllMain。本文介绍了如何执行该操作。

 

 

 

在创建常规 DLL 时 MFC 源强制链接在代码中的源代码文件 /Msdev/Mfc/Src/Dllmodul.cpp。Dllmodul.cpp 包含大部分代码添加到常规支持该 DLL 中的 MFC DLL。Dllmodul.cpp 中最重要功能之一是 DllMain 函数。

若要 MFC 的 DllMain 中添加代码将 /Msdev/Mfc/Src/Dllmodul.cpp 源文件复制到您的项目目录,并包括在您的项目中的副本。这份 Dllmodul.cpp 将编译并链接到的 Mfc/Src 目录中 Dllmodul.cpp 而不是 DLL,因此它在 DllMain 的更改将显示在最终的 DLL 中。

主要需要说明的是这不是推荐的解决方案,并只应在绝对必要时使用。Dllmodul.cpp 中代码的任何更改将肯定会产生不可预知的结果。添加代码仅、 执行不删除或修改现有代码。

有关在共享库中使用 MFC 的规则 dll,模块状态应该设置任何已添加的代码的开头,并还原后,才能从 DllMain 返回。有关处理 DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH 通知并正确切换模块状态,如有必要 DllMain 的一个示例,请参阅本文中示例代码。

依赖于 DllMain DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH 由于以下条件的被调用时,必须采取特别小心:

  • 当在进程中创建线程时,系统调用 DllMain 值为 DLL_THREAD_ATTACH 到进程映射到该 dll 的每个。但是,如果进程中有几个新 DLL 映射到它时,在其中运行的线程 DllMain 不调用一个 DLL_THREAD_ATTACH 与任何现有的线程的值。
  • 将不会 DllMain 调用具有一个值 DLL_THREAD_ATTACH 的进程的主线程。
  • 在 (通过 ExitThread 调用) 线程终止,DllMain 调用 DLL_THREAD_DETACH 值对于每个 dll DllMain 将不会调用与 DLL_THREAD_DETACH 的任何线程除非通过调用 ExitThread 某个线程终止。
  • 如果某个线程终止由于到 TerminateThread 调用,DLL_THREAD_DETACH 一个值,不被调用 DllMain。
  • 它有可能调用 LoadLibrary 加载 DLL_PROCESS_ATTACH,与导致 DllMain 调用 DLL 并在线程终止导致 dllMain 调用与 DLL_THREAD_DETACH 没有以往任何时候都调用 DLL_THREAD_ATTACH 情况下进程中的线程。因此,它是最佳线程调用 LoadLibrary 还调用 FreeLibrary。

注: MFC CWnd 对象、 CDC 对象、 CMenu 对象、 GDI 对象和 CImageList 对象被限制为一个每线程,每个模块的基础。也就创建一个模块或线程中的 MFC 对象无法和/传递给或在不同的模块或线程中使用。此项添加到处理 DLL_THREAD_ATTACH 或 $ 在 DllMain DLL_THREAD_DETACH DllMain 调用不同的线程与这些原因是因为任何代码的特殊相关性。 CWnd,例如,创建的对象在 DllMain 期间 DLL_PROCESS_ATTACH 或 InitInstance 中将不会有效 DLL_THREAD_ATTACH 期间。

 

示例代码

//////////////////////////////////////////////////////////////////// 
// 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;
}
				

你可能感兴趣的:(thread,Module,null,dll,mfc,winapi)