【发布时间】:2015-12-05 20:16:13
【问题描述】:
我认为隐式链接会在应用程序启动后立即加载 DLL,因为它也称为“加载时动态链接”。但是我从这里的链接中发现了一些奇怪的解释(https://msdn.microsoft.com/en-us/library/253b8k2c(VS.80).aspx)。
隐式链接
与程序代码的其余部分一样,DLL 代码映射到地址 进程启动并加载到进程时的进程空间 仅在需要时记忆。因此,PRELOAD 和 LOADONCALL 代码 .def 文件用于控制以前版本中的加载的属性 的 Windows 不再有意义。
显式链接
隐式链接到许多 DLL 的应用程序可能会很慢 启动,因为 Windows 会在应用程序加载时加载所有 DLL。 为了提高启动性能,应用程序可以隐式链接到 加载后立即需要的那些 DLL 并等待显式 在需要时链接到其他 DLL。
还有对隐式链接的另一种解释(https://msdn.microsoft.com/en-us/library/151kt790.aspx)。
隐式链接
Visual C++ 链接器现在支持延迟加载 DLL。这 使您无需使用 Windows SDK 函数 LoadLibrary 和 GetProcAddress 实现 DLL 延迟加载。
在 Visual C++ 6.0 之前,在运行时加载 DLL 的唯一方法是通过 使用 LoadLibrary 和 GetProcAddress;操作系统将加载 加载可执行文件或使用它的 DLL 时的 DLL。
从 Visual C++ 6.0 开始,当与 DLL 进行静态链接时, 链接器提供延迟加载 DLL 直到程序调用的选项 该 DLL 中的函数。
应用程序可以使用 /DELAYLOAD(延迟加载 导入)带有辅助函数的链接器选项(默认实现) 由 Visual C++ 提供)。辅助函数将在运行时加载 DLL 时间为您调用 LoadLibrary 和 GetProcAddress。
我真的很困惑,不知道如何理解这些。
1.隐式链接是在启动时加载 DLL 还是仅在调用 DLL 中的函数时加载?
2。这意味着最终两者都是相似的,因为 LoadLibrary() 是在后台调用的?
【问题讨论】:
-
在隐式链接中,DLL 在应用程序启动时加载,但在第一次调用 DLL 之前,它可能不会完全提交到内存中。 DLL 函数调用直接转到 DLL。显式链接由用户自己的代码管理。延迟加载是两者的混合。链接器在应用程序的 PE 标头中创建一个特殊表,其中包含有关延迟加载的 DLL 函数的信息,并且运行时库具有每个延迟加载的函数最初指向的存根代码...
-
... 当第一次调用延迟加载函数时,存根代码查看延迟加载 PE 表,显式加载指定的 DLL 函数指针,将函数的存根指针替换为加载的 DLL 指针,因此后续调用将直接转到 DLL,然后存根通过调用加载的函数完成。应用永远不知道静态链接函数调用和延迟加载函数调用之间的区别(除非在尝试加载 DLL 时发生运行时错误)。
-
@Remy Lebeau 谢谢!
-
@RemyLebeau - 你为什么不回答?这是一个很好的解释,我认为它值得点赞。我很抱歉试探你...
-
@Jenix - 另见LoadLibrary Reference Counting 和NTDLL.dll 的
LdrLoadDll的讨论。
标签: c++ dll linker implicit explicit