【问题标题】:MSVC DLL loading: are __declspec(dllexport) functions loaded directly without DllMainMSVC DLL 加载:是 __declspec(dllexport) 函数在没有 DllMain 的情况下直接加载的
【发布时间】:2020-07-16 06:09:49
【问题描述】:

我尝试在 VS C++ 中编写一个 DLL 项目,其中包含一些导出函数,如下所示:

extern "C"  __declspec(dllexport) int function_sendNumber(unsigned num);

我注意到 VS 项目带有包含 DllMain 入口函数的文件 dllmain.cpp。 但是,我注释了 DllMain 函数并使用 Delphi exe 应用程序 调用导出的函数,如下函数指针:

function  function_sendNumber(n : Integer): Integer; cdecl;
external 'DLLproject.dll';

Delphi 应用程序成功调用了 DLL 导出函数。 我认为这种方法是 DLL 显式链接。 所以我想清楚地理解,是显式加载还是隐式加载。 如果是这样,如何在没有 DllMain 的情况下加载导出的函数。 我没有找到任何调用 LoadLibrary 来加载 DLL。

【问题讨论】:

  • DllMain 与隐式/显式链接/加载无关。问题是什么?
  • 感谢@CristiFati。问题是应用程序如何在没有加载任何 DLL 的情况下找到这个导出函数。我通过转储检查了 dll,只发现导出函数名称作为入口点。是不是直接在dll文件上寻找导出函数名作为入口点。

标签: delphi dll dllexport dllmain


【解决方案1】:

有一些或多或少相关的术语:

  • 显式/隐式链接 - 这有点不恰当,因为 .dll 要么被链接(通过 .exe 或另一个 .dll) 与否。更好的术语是 Explicit / Implicit Loading,因为 .dll 的加载方式:

    1. 显式 - 来自其客户端代码的按需(使用 LoadLibraryLoadLibraryEx 或其他(较低级别)机制)
    2. 隐式ly - 默认情况下(由Win在进程启动时自动(检查下一个项目符号))。这些 .dll.exe 链接(或另一个由 .exe链接(递归)的 .dll >)
    3. [MS.Docs]: Linker Support for Delay-Loaded DLLs - 中间满足上述 2 个选项,充分利用每个选项(意味着 .dll 仍将自动加载(因此仍为 Implicit Loading) ,但仅在需要时(调用其函数之一),而不是进程启动)
  • [MS.Docs]: DllMain entry point .dll 加载到进程中时执行的函数,不管加载方法如何(上)

  • function_sendNumber - 由于 __declspec(dllexport) 由您的 .dll 导出(名称为保持简单(即使代码编译为 C++)因为 extern "C")

  • 你可以从Delphi中调用函数是因为:

    检查这 3 项后,Delphi 完成了(在后台)通过 .exe 链接 .dll 的工作,并且因此,您有 Implicit Loading(值得一提的是@HeartWare 的建议,即从 Delphi 将函数标记为 delayed ,为了从延迟加载中受益

【讨论】:

  • 您可以通过将指令 delayed; 添加到您的 Delphi 声明中来使导入成为延迟加载的。这意味着 .DLL 文件只会在第一次调用时加载,而不是(如在隐式加载中)在主程序启动时加载。
  • @HeartWare:好点子!这是在当前方面明确后可能发生的优化。
猜你喜欢
  • 1970-01-01
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
相关资源
最近更新 更多