gpt4 book ai didi

c++ - 更改 Windows DLL 加载顺序? (加载顺序,不是搜索顺序)

转载 作者:IT老高 更新时间:2023-10-28 22:59:32 32 4
gpt4 key购买 nike

假设我有一个可执行文件:app.exe

我在这个可执行文件中使用了 2 个不同的 3rd 方 DLL:foo.dll bar.dll 并且应用程序必须隐式链接到这些 DLL,也就是说我不能使用 ::LoadLibrary 来加载它们。

(注意:不是我不能调用LoadLibrary,而是这些DLL需要静态链接(C++ DLLs with __declspec(dllexport)),所以我调用 LoadLibrary没有任何意义,因为可执行加载器已经调用了它。)

这两个 DLL 确实 彼此之间没有任何依赖关系,也就是说,据我所知,它们的加载顺序是未定义的(并且 应该 是不相关的)。 (两者的依赖基本上都只在标准的windows dll(kernel32、msvcrt等)上

我现在有一个问题,我希望控制这些 DLL 的加载顺序,即我希望 foo.dll 在 bar 之前 总是 加载(DLL_PROCESS_ATTACH) .dll。

是否有可能告诉 Windows DLL 加载程序先加载一个 DLL?

编辑:要检查可执行文件的 DLL 加载顺序,可以使用 DUMPBIN.exe 实用程序:(只需启动 Visual Studio 命令提示符)

编辑:根据 this answer/this blog entry ,NT 加载程序确实按顺序遍历导入部分。 (这将导致 独立 DLL 按它们在导入部分中出现的顺序加载。)

C:\path\to\program> dumpbin /IMPORTS app.exe | grep -i \.dll
MSVCR80D.dll
KERNEL32.dll
OLEAUT32.dll
MSVCP80D.dll
foo.dll
bar.DLL

此输出意味着 MSVCR80D.dll(及其依赖项[a])将首先加载,而 bar.DLL 将最后加载。卸载将以相反的顺序进行。

还没有发现如何影响这个加载顺序 ...


(注释)

[a] :这当然意味着例如kernel32.dll 会先加载,因为 msvcr80d.dll 会依赖 kernel32.dll。


根据一些要求,我为此添加了一个理由:(但是,我仍然对此一般感兴趣。我知道如何解决 MFC 问题。)

它的调试版本中的 Microsoft MFC DLL 内置了内存泄漏检测。(据我所知,它与 _CrtSetDbgFlag 和相关工具使用的机制相同。)

MFC 调试 DLL 将在卸载时转储所有未释放的内存。现在,如果您的进程中有第二个 DLL,它独立于 MFC,并且这个第二个 DLL 在 DLL_PROCESS_DETACH 上释放内存,如果 MFC DLL 在另一个 dll 之前卸载,则 MFC 报告机制将报告错误的内存泄漏。

如果可以确保调试 MFC DLL 在所有独立 DLL 中最先加载/最后卸载,那么所有其他 DLL 本身就已经清理完毕,并且 MFC 不会报告错误泄漏。

最佳答案

这是一个想法:在 app.exe 的链接器选项中将它们标记为“延迟加载的 dll”怎么样?

延迟加载将允许您“静态”链接(即没有 LoadLibrary() 等),但不会加载 DLL 并在实际需要之前进行链接。

如果这是一个选项,那么(假设您可以等待很长时间,即不要在 main() 之前访问 foo/bar dll 函数),您可以在 main() 中访问一个函数(只需获取一个函数 ptr或其他东西)首先在 foo.dll 中加载它并绑定(bind)所有“静态”链接的函数?

(也许 LoadLibrary() 会在需要时触发相同的链接过程。不确定。不过在您的代码中看起来会更干净。)

关于c++ - 更改 Windows DLL 加载顺序? (加载顺序,不是搜索顺序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6371779/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com