作为我对新合同职位的培训的一部分,我的任务是构建两个DLL和两个cppunit单元测试程序。一切都建成了。
当我尝试运行其中一个单元测试程序时,我发现两个DLL(由单元测试程序使用)混合了32位和64位元素。我下载了Dependency Walker(Depends.exe)并跟踪DLL获取输入的问题。 32位库位于名为C:\ AppName \ bin的目录中,64位库位于C:\ AppName \ bin64中。
由于DLLS在运行时(实际加载时间)之前未加载,并且因为DLL与.exe不在同一目录中,并且由于PATH将这两个文件夹的搜索顺序显示为" C: \ AppName \ bin64; C:\ AppName \ bin;",当我尝试运行单元测试时,我收到一个错误,告诉我有64位模块混入32位模块,并拒绝跑。我通过将bin64重命名为SAVE_bin64来修复此问题,以便加载程序无法找到它,默认为其他目录,并加载正确的DLL。
我的办公室伙伴收到了同样的任务。他没有这样的困难。不仅如此,我之前已经让程序成功运行,但在使用公司安装工具安装了一些模块后遇到了问题。由于安装发生在后台,我不知道它做了什么,除了foo-barring我的构建。
Visual Studio C ++(非托管)构建过程中的某些内容已经在.exe中包含了足够的信息,以便让加载程序知道在哪里找到正确的DLL,但在安装时会被搞砸。
我在这个问题上进行了广泛的研究,然后通过打开" Full Paths"在Depends.exe中,所以我已经了解了SxS(Side-by-Side)和DLL重定向,这两者都不相关。
所以,问题是,Windows加载器是如何一次找到正确的DLL而不是另一个;如何在他的机器上找到正确的DLL,但不是我的?
提前致谢。
编辑添加:
我再试了一次实验。我的bin64仍然重命名为SAVE_bin64,我将两个库(libB.dll依赖于libA.dll)和单元测试程序(都依赖于libB.dll)构建为32位。然后我将SAVE_bin64重命名为bin64,这样如果加载器完全依赖于PATH变量来定位相关DLL,则由于32/64位不匹配,单元测试程序将无法运行。但是,单元测试程序运行,成功地从72个模块中找到一个错误。
这表明Visual Studio 2010 C ++编译器/链接器能够以某种方式将依赖DLL的正确位置嵌入到可执行程序中,因此加载器不必依赖PATH变量来查找DLL。
答案 0 :(得分:1)
这可能有助于理解Windows如何搜索dll:
MSDN: Dynamic-Link Library Search Order
加载程序将选择它首先看到的具有匹配名称的dll(在搜索列表中)。 DLL是64位还是32位并不重要。我相当肯定,如果它是一个重命名为.dll的文本文件,它甚至会尝试加载它 也许您的同事将他的dll放在系统文件夹中或与应用程序版本并排。
我发现一种简单的方法可以解决32位和64位dll的不同名称。 example32.dll和example64.dll。