windows 中的延迟加载 DLL:我可以动态选择要查找的 DLL 名称吗? (c++)

Delay-load DLL in windows: can I dynamically choose what DLL name to look for? (c++)

我有一个从 foo.dll.

调用函数的库

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

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

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

我使用十六进制编辑器查看我的库的内容,并且在一个位置 "foo.dll" 被明确命名。如果我使用十六进制编辑器将该条目重命名为 "bar.dll",则当 bar.dll 是用户计算机上的 DLL 名称时,我的库将完美运行(并且当 foo.dll 是名称时会崩溃)。所以看来问题出在延迟加载助手试图在我的库中加载明确命名的 DLL。

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

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

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

If your code needs to recover or provide an alternate library and/or routine on failure, a hook can be provided to the helper function that can supply or remedy the situation. The hook routine needs to return a suitable value, so that processing can continue (an HINSTANCE or FARPROC) or 0 to indicate that an exception should be thrown. It could also throw its own exception or longjmp out of the hook. There are notification hooks and failure hooks.

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

If the notification is dliFailLoadLib, the hook function can return:

  • 0, if it cannot handle the failure.

  • An HMODULE, if the failure hook fixed the problem and loaded the library itself.

因此,如果错误报告失败的 DLL 是 foo.dll,您的挂钩可以加载 return HMODULE bar.dll,然后助手将加载foo.dll 的所有延迟加载函数都来自 bar.dll