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

2024-01-12

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

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

(注:并不是说我不能打电话LoadLibrary,但这些 DLL 需要静态链接(带有__declspec(dllexport)),所以我打电话LoadLibrary没有任何意义,因为可执行加载程序已经调用了它。)

这两个DLL的作用是not彼此之间有任何依赖关系,也就是说,据我所知,它们的加载顺序是未定义的(并且should无关紧要)。 (两者的依赖关系基本上只依赖于标准的windows dll(kernel32、msvcrt等)

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

是否可以以某种方式告诉 Windows DLL 加载程序先加载一个 DLL,然后再加载另一个?

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

编辑:根据这个答案 https://stackoverflow.com/questions/6382560/does-the-nt-dll-loader-load-dlls-in-the-order-of-the-import-section-of-the-execut/6383562#6383562 / 这个博客条目 https://learn.microsoft.com/en-us/archive/blogs/mgrier/the-nt-dll-loader-basic-operation, NT 加载器does按顺序走导入部分。 (这将导致独立的DLL 按照它们在导入部分中出现的顺序加载。)

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

This output means that MSVCR80D.dll (and its dependecies[a]) will be loaded first and that bar.DLL will be loaded last. Unload will happen in reverse order.

What I haven't发现还如何影响此加载顺序 ...


(Notes)

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


As per some requests, I'm adding a rationale for this: (But please, I'm still interested in this generally. I know how to work around the MFC problem.)

Microsoft MFC DLL 的调试版本内置了内存泄漏检测功能。(据我所知,这与_CrtSetDbgFlag http://msdn.microsoft.com/en-us/library/5at7yxcs%28v=VS.80%29.aspx以及相关工具。)

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

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


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

我不知道为什么我没有尝试这个,但似乎结果模块的导入部分顺序确实取决于lib文件被提供给链接器。

Configuration Properties -> Linker -> Additional Dependencies ...

这里首先列出的 lib 文件也是导入部分中的第一个,meaning https://stackoverflow.com/a/6383562/321013加载器将按顺序导入它们(模依赖)。

所以,回答这部分:只需以正确的顺序向链接器提供 lib 文件即可。

Note:我已经在 VS2005 上尝试过,它似乎有效。我不知道是否在某处记录了这一点,也不知道它是否在新版本的 VC++ 中发生了变化。


Update:虽然当时它有效,但今天我遇到了加载顺序是的情况not受链接器命令行顺序的影响 of the lib文件。 (仍然)不知道为什么。 (仍然是VS2005)

然而,我设法通过将有问题的 DLL 添加到延迟加载的 DLL 列表中来使其工作(例如马克的回答 https://stackoverflow.com/a/6371859/321013).


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更改 Windows DLL 加载顺序? (加载顺序,不是搜索顺序) 的相关文章

随机推荐