多个静态链接 dll 的 DLL 重定向

Posted

技术标签:

【中文标题】多个静态链接 dll 的 DLL 重定向【英文标题】:DLL redirection for multiple static-linked dll's 【发布时间】:2020-03-30 16:47:46 【问题描述】:

我正在尝试在 VS2010 C++ 项目(x32 配置)上加载同一 DLL 的多个实例。

所以我有主 dll - Parent.dll 与其他一些 kids.dll(kid1.dll、kid2.dll 等...、kid8.dll)静态链接 - 当我加载 Parent.dll 时, kids.dll 会自动加载(它们位于同一路径,因此可以成功加载)。

在我的代码中,我使用 LoadLibraryEx(Path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) 来加载 Parent.dll 实例。 当我尝试创建 Parent.dll 的多个实例时出现我的问题: 我将所有 DLL 的副本复制到另一个路径中,重命名了父名称(例如 Parnet_1.dll),关于其他 DLL - 它们无法重命名,因为它们是静态链接的。 (我无法访问 Parnet.dll 源代码并将其更改为动态加载)。

有 1 个实例 - Parent.dll 和他的所有孩子都成功加载。当我尝试加载另一个实例 Parent_1.dll 时,Parent_1.dll 已成功加载,但其他子 DLL 未加载:它们具有已从第一个实例加载的完全相同的名称 - 这就是导致我的程序崩溃。

我想要做的是动态加载 Parent.dll 的多个实例,每个 Parent 都会加载他自己的 kids.dll。换句话说 - 递归重定向

我一直在互联网上搜索,但找不到适合我的情况的解决方案。 我在那里看到了这篇文章: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-redirection 并尝试了 MyCode.exe.local 并没有用。

我也尝试使用清单进行 DLL 重定向,但不明白如何正确执行。

感谢您的帮助!

【问题讨论】:

您能否详细说明您要解决的问题,例如,如果您只加载多个“Parent.dll”实例会导致什么问题? parent.dll 依赖于他的 kids.dll,当我加载第一个 parnt.dll 时一切正常,但当我加载另一个带有重定向的 parend.dll 实例时出现问题编译器成功加载 parent.dll 的新实例的方式(即使它具有完全相同的名称,但来自不同的路径),但不是加载依赖的 DLL(所有子 DLL),而是编译器首先查看内存并查看该 DLL 已经加载,ant 将它们作为参考返回,而不是加载它们。我需要一些递归重定向所有依赖 DLL 的方法 【参考方案1】:

只要文件相同,这将不起作用。

一个 DLL 在进程间共享,如果一个 DLL 已经被加载,对 LoadLibrary 的新调用将只返回对该已加载模块的引用。它会破坏 DLL 采取不同做法的意义。

如果您绝对必须有不同的负载,您可以重命名文件(尽管这很快就会变得笨拙(即使这样我也不确定它会起作用(库的名称编码为二进制文件的一部分,我不确定如果新文件是 LoadLibrary'd 并且内部名称与已加载库的名称匹配,则窗口将继续加载。

如果您可以在加载 parent2.dll 之前卸载 parent1.dll(连同所有子项),那么上述任何一项都不应该发挥作用。

【讨论】:

“只要文件相同,这将不起作用” - 这不是真的。我成功加载了多个具有名称的 DLL,它们位于不同的路径上:LoadLibraryEx(Path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)。也可以使用我上面提到的链接来完成。我希望递归地做到这一点。看看我对菲尔·布鲁贝克的回答 “文件相同”我的意思是路径加文件,不同的路径加文件不是同一个文件。

以上是关于多个静态链接 dll 的 DLL 重定向的主要内容,如果未能解决你的问题,请参考以下文章

lib和dll文件的初了解

静态链接库的动态 DLL

C++中lib 和 dll 的区别,生成以及使用详解

如何静态链接我的 MFC 扩展 DLL?

无需 DLL 静态链接 zlib

dll从静态链接库导出函数符号