自 Visual C++ 6.0 以来 DLL 延迟加载 Helper 函数所做的更改
如果您的计算机上有多个 Visual C++ 版本,或者您定义了自己的 Helper 函数,对 DLL 延迟加载 Helper 函数所做的更改对您可能会有所影响。 例如:
__delayLoadHelper 现在为 __delayLoadHelper2
__pfnDliNotifyHook 现在为 __pfnDliNotifyHook2
__pfnDliFailureHook 现在为 __pfnDliFailureHook2
__FUnloadDelayLoadedDLL 现在为 __FUnloadDelayLoadedDLL2
提示
如果正在使用默认 Helper 函数,则不会受这些更改的影响。 调用链接器的方法没有更改。
多个 Visual C++ 版本
如果您的计算机上有多个 Visual C++ 版本,请确保链接器与 delayimp.lib 匹配。 如果不匹配,您会收到一条链接器错误,向您报告 ___delayLoadHelper2@8 或 ___delayLoadHelper@8 是无法解析的外部符号。 前者意味着新链接器遇到旧 delayimp.lib,后者意味着旧链接器遇到新 delayimp.lib。
如果得到了一条未解析的链接器错误,请对您认为应包含该 Helper 函数的 delayimp.lib 运行 dumpbin /linkermember:1 以查看实际上定义的 Helper 函数。 Helper 函数也可在对象文件中定义;运行 dumpbin /symbols 并查找 delayLoadHelper(2)。
如果知道有 Visual C++ 6.0 链接器,那么:
对延迟加载帮助程序的 .lib 文件或 .obj 文件运行 dumpbin,确定它是否定义 __delayLoadHelper2。 如果没有,链接将失败。
在延迟加载 Helper 的 .lib 文件或 .obj 文件中定义 __delayLoadHelper。
用户定义的 Helper 函数
如果您定义了自己的 Helper 函数,并且正使用 Visual C++ 的当前版本,请执行下列操作:
将 Helper 函数重命名为 __delayLoadHelper2。
因为延迟描述符(delayimp.h 中的 ImgDelayDescr)中的指针已经从绝对地址 (VA) 更改为相对地址 (RVA),以便按预期那样在 32 位和 64 位程序中都有效,所以需要将这些转换回指针。 已经介绍过在 delayhlp.cpp 中找到的一个新函数:PFromRva。 可以在描述符的每个字段上使用该函数以将它们转换回 32 位或 64 位指针。 默认延迟加载 Helper 函数仍是用作示例的好模板。
加载延迟加载的 DLL 的所有导入
链接器可以加载指定为要延迟加载的 DLL 的所有导入。 有关更多信息,请参见加载被延迟加载的 DLL 的所有导入。