为什么我的 DLL 不需要 DllMain 函数?

Joe*_*Joe 2 c++ windows dll visual-studio

我刚刚将 C++ Windows DLL 项目添加到 Visual Studio (2022) 解决方案中。巫师DllMain在那里放了一个。这让我大吃一惊;我不记得我的其他 DLL 有DllMain函数;

搜索我的代码,发现我的 9 个 DLL 都没有 DllMain 函数。但它们都构建并运行良好。我检查了所有这些项目的项目设置:

  • 它们都没有/NOENTRY设置链接器选项。
  • 他们都已经/SUBSYSTEM:WINDOWS定了。
  • 他们都没有 /NODEFAULTLIB设置链接器选项
  • 它们当然都是DLLS。

于是我把刚刚添加的新项目中的DllMain注释掉了。它仍然构建得很好。

我的知识显然已经过时了。我认为DllMain过去是必需的。我记得几年前,当我未能添加DllMain.

所以我的问题是:

  1. 为什么我的 DLL 不需要 DllMain?是否有一些构建设置我没有检查?
  2. 没有的话有什么坏处吗?

(请注意,这些 DLL 都导出 C++ 类。它们都不是资源 DLL。所有这些都运行良好 6 年。其中一些使用线程本地存储。其中一些在函数内部有静态变量。我一直认为使用诸如此类的事情需要 DllMain)

Ben*_*igt 6

运行时库(“CRT”= C/C++ 运行时库)提供真正的DLL 入口点_DllMainCRTStartup,它可以在调用DllMain. MSDN 上有文档对此进行了描述:

链接器/ENTRY选项的文档也相关:

还有一个库为您提供的弱符号DllMain,因此从真实入口点到 的调用DllMain不会在链接时因未解析的外部而失败。从上面的第一个文档:

默认情况下,如果您不提供DllMain函数,Visual Studio 会为您提供一个函数并将其链接起来,以便_DllMainCRTStartup始终有东西可以调用。

您提到的线程本地存储之类的东西确实需要使用库提供的入口点;如果您使用/ENTRYlink.exe 的选项将库入口点替换为您自己的库入口点或/NOENTRY禁用它,它们将会中断。DllMain它们都不需要库入口点调用的任何操作。

  • @Joe:我认为您可能记得的是源自向导用来创建的 .DEF 文件的行为(在 `__declspec(dllexport)` 系统存在之前,导出必须在那里列出)。如果您从 C/C++ 源代码中删除了任何向导生成的函数(例如“DllCanUnloadNow”或“DllRegisterServer”),并且没有从 .DEF 文件中删除它们,则会出现链接错误。 (2认同)