65.9K
CodeProject 正在变化。 阅读更多。
Home

延迟加载 DLL

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.07/5 (21投票s)

2005年1月27日

CPOL

4分钟阅读

viewsIcon

156055

downloadIcon

1852

延迟加载的优点/缺点以及如何延迟加载 DLL。

引言

本文中显示的代码片段用于延迟加载 DLL,即,DLL 是隐式链接的,但实际上直到您的代码尝试引用 DLL 中包含的符号时才加载。如果您的应用程序使用多个 DLL,则其初始化时间可能会很慢,因为加载程序会将所有必需的 DLL 映射到进程的地址空间中,并且很可能甚至不会调用这些 DLL 中的单个函数,因此加载很少使用的 DLL 的更好方法是延迟加载,即,在需要时加载它,而不是最初加载它。 这缩短了启动时间。 听起来不错。 现在,我们将实际尝试延迟加载 DLL,并分析其优点和缺点,因此一切就绪...

使用代码

首先,您像通常一样创建 DLL。 您还像通常一样创建可执行文件,但您必须更改几个链接器开关并重新链接可执行文件。 这是您需要添加的两个链接器开关

/Lib:DelayImp.lib
/DelayLoad:MyDll.dll
#pragma comment(lib, "DelayImp.lib")
#pragma comment(linker, "/DelayLoad:Dll.Dll")
#pragma comment(linker, "/Delay:unload")

很简单,不是吗? 只需在 EXE 的代码中添加以上三行,您的 DLL 就会被延迟加载。 现在,让我们看看它是如何实现的。

Lib,“DelayImp.lib” 开关告诉链接器将一个特殊函数 __delayLoadHelper 嵌入到您的可执行文件中。

第二个开关告诉链接器以下内容

从可执行模块的导入部分中删除 Dll.dll,以便操作系统加载程序在进程初始化时不隐式加载 DLL。 您可以从 VC 6.0 附带的依赖项查看器实用程序中观察到它。 以下是具有和不具有延迟加载的依赖项查看器的图像。 如图所示,在延迟加载的情况下,它在 EXE 的依赖项中没有条目。

如在没有延迟加载的第一种情况下所见,Dll.Dll 显示在 EXE 的依赖项中,但在使用延迟加载 DLL 的 EXE 的第二个图像中没有显示。

继续讨论链接器开关

... 它在可执行文件中嵌入一个新的延迟导入部分(称为 .didata),指示哪些函数正在从 Dll.dll 导入。

通过让调用跳转到 __delayLoadHelper 函数来解析对延迟加载函数的调用。

当应用程序运行时,对延迟加载函数的调用实际上会调用 __delayLoadHelper 函数。 此函数引用特殊的延迟导入部分,并且知道调用 LoadLibrary,然后调用 GetProcAddress。 获得延迟加载函数的地址后,__delayLoadHelper 会修复对该函数的调用,以便将来的调用直接转到延迟加载的函数。 请注意,同一 DLL 中的其他函数仍然必须在您第一次调用它们时进行修复。 另请注意,您可以多次指定 /DelayLoad 链接器开关——为要延迟加载的每个 DLL 指定一次。

缺点

当操作系统加载程序加载您的可执行文件时,它会尝试加载所有必需的 DLL。 如果无法加载 DLL,加载程序会显示一条错误消息。 但是对于延迟加载的 DLL,在初始化时不检查 DLL 的存在。 如果在调用延迟加载的函数时找不到 DLL,则 __delayLoadHelper 函数会引发软件异常。 您可以使用结构化异常处理 (SEH) 捕获此异常并保持您的应用程序运行。 如果您不捕获异常,您的进程将被终止。

_delayLoadHelper 找到您的 DLL,但您尝试调用的函数不在 DLL 中时,可能会发生另一个问题。 例如,如果加载程序找到旧版本的 DLL,则可能会发生这种情况。 在这种情况下,_delayLoadHelper 也会引发软件异常,并且适用相同的规则。

如果找到 DLL 和函数,加载程序将在引用该 DLL 中的函数或符号时尝试加载 DLL。 由于它现在加载而不是在应用程序启动时加载,因此需要一些时间,但是如果在构建 DLL 时,您没有将其地址重新定位到适当的地址,那么情况会变得更糟,因此在函数调用时,加载程序将首先尝试加载 DLL,并且它必须重新定位 DLL,这会产生大量开销(有关重新定位的详细信息,请阅读文章 需要重新定位 DLL)。 因此,如果可能,也要正确地重新定位它以快速加载 DLL。

致谢和参考文献

我要感谢作者 Jeffery Richter 先生及其关于 Windows 操作系统的书籍,这是了解 Windows 操作系统内部结构的最佳书籍之一。 本文的部分内容摘自本书,并添加了示例以简化内容。

© . All rights reserved.