假设我有一个可执行文件: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 不会报告错误泄漏。