MSVC DLL 加载: __declspec(dllexport) 函数是直接加载的,没有 DllMain
MSVC DLL loading: are __declspec(dllexport) functions loaded directly without DllMain
我尝试用 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 显式链接。
所以想了解清楚,到底是Explicit Loading还是implicit。
如果是这样,如何在没有 DllMain 的情况下加载导出的函数。
我没有找到任何调用 LoadLibrary 来加载 DLL。
有一些或多或少相关的术语:
显式/隐式链接 - 这有点不合适,因为 .dll 要么被链接(通过.exe 或另一个 .dll) 或不是。更好的术语是 显式/隐式加载 ,因为 .dll 的加载方式:
- Explicitly - 按需(使用 LoadLibrary、LoadLibraryEx 或其他(较低级别)机制)来自其客户端代码
- 隐式ly - 默认情况下(自动,由 Win 在进程启动时 (检查下一个项目符号))。这些 .dll 由 .exe 链接(或另一个 .dll 链接(递归) .exe)
- [MS.Docs]: Linker Support for Delay-Loaded DLLs - 在中间满足上述 2 个选项,利用每个选项的优势(意味着 .dll 仍然会自动加载(所以它仍然隐式加载),但仅在需要时(调用其函数之一)而不是进程启动时)
[MS.Docs]: DllMain entry point 当 .dll 加载到进程中时正在执行的函数,regardless加载方法(上)
function_sendNumber - 由您的 .dll 导出,因为 __declspec(dllexport)(并且名称保持简单(即使代码编译为 C++)因为外部“C”)
您可以从 Delphi 调用函数的事实是因为:
- 由.dll
导出
- 外部关键字([Embarcadero.DocWiki]: Procedures and Functions (Delphi))
- 函数实际调用来自Delphi代码
选中这 3 个项目后,Delphi 完成了(在幕后)链接 .dll 的工作.exe,因此你有 隐式加载 (值得一提的是@HeartWare 的建议,也将函数标记为 delayed 来自 Delphi,以便受益于 Delayed Loading)
我尝试用 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 显式链接。 所以想了解清楚,到底是Explicit Loading还是implicit。 如果是这样,如何在没有 DllMain 的情况下加载导出的函数。 我没有找到任何调用 LoadLibrary 来加载 DLL。
有一些或多或少相关的术语:
显式/隐式链接 - 这有点不合适,因为 .dll 要么被链接(通过.exe 或另一个 .dll) 或不是。更好的术语是 显式/隐式加载 ,因为 .dll 的加载方式:
- Explicitly - 按需(使用 LoadLibrary、LoadLibraryEx 或其他(较低级别)机制)来自其客户端代码
- 隐式ly - 默认情况下(自动,由 Win 在进程启动时 (检查下一个项目符号))。这些 .dll 由 .exe 链接(或另一个 .dll 链接(递归) .exe)
- [MS.Docs]: Linker Support for Delay-Loaded DLLs - 在中间满足上述 2 个选项,利用每个选项的优势(意味着 .dll 仍然会自动加载(所以它仍然隐式加载),但仅在需要时(调用其函数之一)而不是进程启动时)
[MS.Docs]: DllMain entry point 当 .dll 加载到进程中时正在执行的函数,regardless加载方法(上)
function_sendNumber - 由您的 .dll 导出,因为 __declspec(dllexport)(并且名称保持简单(即使代码编译为 C++)因为外部“C”)
您可以从 Delphi 调用函数的事实是因为:
- 由.dll 导出
- 外部关键字([Embarcadero.DocWiki]: Procedures and Functions (Delphi))
- 函数实际调用来自Delphi代码
选中这 3 个项目后,Delphi 完成了(在幕后)链接 .dll 的工作.exe,因此你有 隐式加载 (值得一提的是@HeartWare 的建议,也将函数标记为 delayed 来自 Delphi,以便受益于 Delayed Loading)