c++ - Windows:构建同一 DLL 的 32 位和 64 位版本

标签 c++ windows dll 32bit-64bit

作为新契约(Contract)职位培训的一部分,我的任务是构建两个 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,但在我进行安装时却大吃一惊。

我对这个问题进行了广泛的研究,最终通过在 Depends.exe 中打开“完整路径”找到了原因,所以我已经了解了 SxS(并排)和 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。

最佳答案

这可能有助于理解 Windows 如何搜索 dll:
MSDN: Dynamic-Link Library Search Order

加载器将选择它首先看到的(在搜索列表中)具有匹配名称的任何 dll。 DLL 是 64 位还是 32 位并不重要。我相当确定它甚至会尝试加载它,如果它是一个重命名为 .dll 的文本文件 也许您的同事将他的 dll 放在系统文件夹中或与应用程序版本并排放置。

我发现一个简单的处理方法是为 32 位和 64 位的 dll 使用不同的名称。 example32.dll 和 example64.dll。

关于c++ - Windows:构建同一 DLL 的 32 位和 64 位版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23090789/

相关文章:

c++ - 成员类可以从它的父类继承吗?

python - 从 Python 运行 pdftotext

windows - 启用鼠标阴影的脚本?

c# - 在使用时换出 DLL

c# - 如何使生成的 EXE 适用于所有 .NET Framework 版本?

c++ - 如果我确定每个线程总是将相同的值写入共享内存,我应该使用锁吗?

c++ - 在顶点着色器中进行变换时在 OpenGL 中选择对象

c++ - 如何获取系统的IP地址

c# - 如何将 WPF 用户控件创建为 dll,然后在另一个 WPF 应用程序中查看它?

c++ - 请解释语言环境中互斥锁的必要性