【问题标题】:Why does DLL_THREAD_DETACH happen twice?为什么 DLL_THREAD_DETACH 会发生两次?
【发布时间】:2015-08-18 16:40:10
【问题描述】:

我正在学习 COM。我在 DLL 中编写了一个简单的 COM 组件,并在注册表中注册了它。然后我创建了一个简单的客户端并尝试使用我的 COM 组件。但我不明白DllMain 的行为(我也读过this)。

extern "C" BOOL WINAPI DllMain(
  _In_ HINSTANCE hinstDLL,
  _In_ DWORD     fdwReason,
  _In_ LPVOID    lpvReserved){
  pDll = hinstDLL;
  if (DLL_PROCESS_ATTACH == fdwReason){
    trace("DllMain(): DLL_PROCESS_ATTACH");
  }
  else if (DLL_THREAD_ATTACH == fdwReason){
    trace("DllMain(): DLL_THREAD_ATTACH");
  }
  else if (DLL_PROCESS_DETACH == fdwReason){
    trace("DllMain(): DLL_PROCESS_DETACH");
  }
  else if (DLL_THREAD_DETACH == fdwReason){
    trace("DllMain(): DLL_THREAD_DETACH");
  }
  else{
    trace("DllMain(): unknown variant...");
  }
  return TRUE;
}

我希望每个DLL_PROCESS_ATTACH 一个DLL_PROCESS_DETACH 被调用,每个DLL_THREAD_ATTACH 一个DLL_THREAD_DETACH 被调用(如果没有发生异常)。

但我看到一个DLL_PROCESS_ATTACH 有两个DLL_THREAD_DETACH

为什么会这样?

【问题讨论】:

  • 奇怪的是,如果您已经按照您所说的阅读了DllMain 的文档,那么您应该已经回答了这些问题。

标签: c++ winapi dll com dllmain


【解决方案1】:

关于DLL_THREAD_ATTACH

请注意,只有在进程加载 DLL 后创建的线程才能使用此值调用 DLL 的入口点函数。使用 LoadLibrary 加载 DLL 时,现有线程不会调用新加载的 DLL 的入口点函数。

DLL_THREAD_ATTACHDLL_THREAD_DETACH 的数量之间没有关系。这都是关于加载和创建时间的。在加载 DLL 时创建线程时,将调用 DLL_THREAD_ATTACH。当加载 DLL 时线程退出时,将调用 DLL_THREAD_DETACH。线程永远不会被 DLL 抢占,因此 THREAD 调用只能在线程创建和结束时发生。

在您的情况下,日志仅表明您在加载 DLL 后没有创建线程,但在卸载 DLL 之前退出了两个线程。

【讨论】:

  • ... 是的,这使得 DLL_THREAD_ATTACH 几乎毫无用处,尤其是结合 DllMain 的其他限制。但也有边缘情况。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 2010-12-02
  • 2011-01-27
  • 2021-07-08
  • 1970-01-01
  • 2014-10-05
相关资源
最近更新 更多