【问题标题】:Delay-load DLL in windows: can I dynamically choose what DLL name to look for? (c++)在 Windows 中延迟加载 DLL:我可以动态选择要查找的 DLL 名称吗? (c++)
【发布时间】:2020-07-07 19:49:48
【问题描述】:

我有一个从 foo.dll 调用函数的库。

在我的 MSVS 设置中,我延迟加载 foo.dll 并在尝试调用其函数之前手动检查它是否存在(这样,如果机器上不存在它,我的库就不会崩溃)。

如果 DLL 存在性检查成功并且我调用了它的函数,则 Windows 延迟加载助手会自动加载 DLL,并且一切正常。

但是,在 50% 的用户计算机上,foo.dll 被重命名为 bar.dll。即使我调用 LoadLibrary("path\bar.dll") 并且它成功了,我的库仍然会崩溃,因为当我调用其中一个函数时,延迟加载帮助程序仍然会尝试加载 foo.dll。

我使用十六进制编辑器查看库的内容,并在一个位置明确命名了“foo.dll”。如果我使用十六进制编辑器将该条目重命名为“bar.dll”,当 bar.dll 是用户机器上的 DLL 的名称时,我的库运行完美(并且在 foo.dll 是名称的情况下崩溃)。所以似乎问题在于延迟加载帮助程序试图在我的库中加载显式命名的 DLL。

我如何告诉延迟加载帮助程序,有问题的 DLL 的名称与我编译的库中的显式文件名不匹配?

【问题讨论】:

    标签: c++ windows dll load delay


    【解决方案1】:

    要告诉延迟加载帮助程序使用与链接的不同的 DLL,您可以使用 delay load failure hook。根据 MSDN:

    Linker Support for Delay-Loaded DLLs: Error Handling and Notification

    如果您的代码需要在失败时恢复或提供备用库和/或例程,则可以向辅助函数提供一个挂钩,以提供或补救这种情况。 钩子例程需要返回一个合适的值,以便处理可以继续(一个 HINSTANCE 或 FARPROC)或 0 表示应该抛出一个异常。它也可以抛出自己的异常或 longjmp。有通知钩子和失败钩子。

    当延迟加载的 DLL 加载失败时,将使用包含有关加载操作和错误的详细信息的 dliFailLoadLib 通知调用挂钩。钩子可以通过返回一个有效的HMODULE 来从错误中恢复以供助手使用,或者返回 0 以使加载操作失败。

    如果通知是dliFailLoadLib,钩子函数可以返回:

    • 0,如果不能处理失败。

    • HMODULE,如果故障挂钩解决了问题并加载了库本身。

    所以,如果错误报告失败的 DLL 是 foo.dll,您的钩子可以加载并返回 HMODULEbar.dll,然后帮助程序将从bar.dll 代替。

    【讨论】:

      猜你喜欢
      • 2010-11-26
      • 1970-01-01
      • 2017-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      相关资源
      最近更新 更多