1

我尝试在 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。

4

1 回答 1

3

有许多或多或少相关的术语:

  • 显式/隐式链接- 这有点不恰当,因为.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 入口点是在将.dll加载到进程中时正在执行的函数,无论加载方法如何(上图)

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

  • 您可以从Delphi调用该函数的事实是:

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

于 2020-07-16T12:18:05.793 回答