更改Windows DLL加载顺序? (加载顺序,而不是搜索顺序) [英] Changing Windows DLL load order? (load order, not search order)

查看:1184
本文介绍了更改Windows DLL加载顺序? (加载顺序,而不是搜索顺序)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我在这个可执行文件中使用了两个不同的第三方DLL : foo.dll bar.dll 并且应用程序必须隐式链接到这些DLL,这是我不能使用<$



(注意:这不是我不能调用 LoadLibrary / code>,但这些DLL需要静态链接(C ++ DLL与 __ declspec(dllexport)),所以我调用 LoadLibrary 没有任何意义,因为excutable加载器已经调用它。)



这两个DLL不有任何依赖彼此,也就是说,它们的加载顺序是未定义的,只要我能告诉(和应该不相关)。 (两者的依赖性基本上只在标准的windows dll(kernel32,msvcrt等)



我现在有问题,我想控制这些DLLs,这是我希望foo.dll总是加载( DLL_PROCESS_ATTACH )之前bar.dll。



是否有可能告诉Windows DLL Loader在另一个之前加载一个DLL?



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



编辑:根据此答案 / 此博客条目,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将最后加载。

$

> ...






(注释)



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






我为此添加了一个理由:(但,我仍然对此感兴趣。我知道如何解决MFC问题。

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



MFC调试DLL在卸载时会转储所有未释放的内存。现在,如果你的进程有一个第二个DLL,这是独立于MFC,并且这个第二个DLL释放DLL_PROCESS_DETACH上的内存,MFC报告机制将报告假内存泄漏,如果MFC DLL在其他dll之前卸载。 p>

如果可以确保调试MFC DLL首先加载/卸载所有独立DLL的最后,那么所有其他DLL本身已经清理后,MFC不会

解决方案


我还没有找到的是如何影响这个负载order ...


我没有任何线索为什么我没有尝试过,但似乎导入部分的顺序的结果模块确实取决于 lib 文件提供给链接器的顺序。

 配置属性 - >链接器 - >附加依赖关系... 

这里列出的lib文件首先也在导入部分,含义加载器将按顺序导入这些(模数依赖)。



因此,要回答这一部分:只需以正确的顺序向链接器提供lib文件。



:我试过在VS2005,它似乎工作。我不知道这是否记录在某个地方,或者如果它在VC ++的较新版本中更改。






更新:当它工作的时候,今天我碰到加载顺序受链接程序命令行顺序影响的情况 lib 文件。 (Still)没有线索为什么。 (Still VS2005)



我已经设法通过添加有问题的DLL到延迟加载的DLL列表中(例如 Macke的回答)。





Say I have one executable: app.exe

I use 2 different 3rd party DLLs in this executable: foo.dll bar.dll and the Application must link implicitly to these DLLs, that is I cannot use ::LoadLibrary to load them.

(Note: It's not that I cannot call LoadLibrary, but these DLLs require static linking (C++ DLLs with __declspec(dllexport)), so me calling LoadLibrarydoesn't make any sense because the excutable loader has already called it.)

These two DLLs do not have any dependencies on each other, that is, their load order is undefined as far as I can tell (and should be irrelevant). (Dependencies of both are basically only on the standard windows dlls (kernel32, msvcrt, etc.)

I now have the problem that I wish to control the load order of these DLLs, that is I wish that foo.dll is always loaded (DLL_PROCESS_ATTACH) before bar.dll.

Is it somehow possible to tell the Windows DLL Loader to load one DLL before another?

Edit: To check the DLL load order of an executable, one can use the DUMPBIN.exe utility: (Just launch the Visual Studio Command Prompt)

Edit: As per this answer / this blog entry, the NT Loader does walk the import section sequentially. (Which will result in independent DLLs being loaded in the order they appear in the import section.)

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 found out yet is how to influence this load order ...


(Notes)

[a] : This means of course that e.g. kernel32.dll will be loaded first, because msvcr80d.dll will depend on 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.)

The Microsoft MFC DLL in it's debug version has memory leak detection built in. (As far as I can tell, it's the same mechanism used by _CrtSetDbgFlag and related tools.)

The MFC debug DLL will dump all unfreed memory when it is unloaded. Now, if you have a second DLL in your process, that is independent of MFC, and this second DLL deallocates memory on DLL_PROCESS_DETACH, the MFC reporting mechanism will report false memory leaks, if the MFC DLL is unloaded before the other dll.

If one could make sure that the debug MFC DLL is loaded first / unloaded last of all independent DLLs, then all other DLLs would already have cleaned up after themselves and MFC wouldn't report false leaks.

解决方案

What I haven't found out yet is how to influence this load order ...

I have no clue why I hadn't tried this, but it seems the import section order of the resulting module does depend on the order in which the lib files are provided to the linker.

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

The lib files listed here first are also first in the import section, meaning the loader will import these in order (modulo dependencies).

So, to answer that part: Just provide the lib files in the correct order to the linker.

Note: I have tried that on VS2005 and it appears to work. I don't know whether that is documented somewhere or if it changed in newer versions of VC++.


Update: While it worked back then, today I hit the case that the load order was not to be influenced by the linker command line order of the lib files. (Still) No clue why. (Still VS2005)

I have however managed to make it work by adding the problematic DLLs to the list of delay loaded DLLs (like in Macke's answer).


这篇关于更改Windows DLL加载顺序? (加载顺序,而不是搜索顺序)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆