Windows:同时构建同一DLL的32位和64位版本
Windows: Building both 32-bit and 64-bit versions of the same DLL
作为我新合同职位培训的一部分,我的任务是构建两个DLL和两个cppunit单元测试程序。一切顺利。
当我尝试运行其中一个单元测试程序时,我发现两个DLL(单元测试程序使用的)都混合了32位和64位元素。我下载了DependencyWalker(Dependens.exe),并跟踪DLL获取输入的问题。32位库位于名为C:\AppName\bin的目录中,64位库位于C:\AppName\bin64中。
由于DLL要到运行时(实际加载时间)才能加载,并且DLL与.exe不在同一目录中,并且PATH将这两个文件夹的搜索顺序显示为"C:\AppName\bin64;C:\AppName\bin;",因此当我尝试运行单元测试时,我收到一个错误,告诉我有64位模块与32位模块混合,并拒绝运行。我通过将bin64重命名为SAVE_bin64来解决这个问题,这样加载程序将无法找到它,默认为其他目录,并加载正确的DLL。
我的同事也接到了同样的任务。他没有这样的困难。不仅如此,我之前已经成功运行了该程序,但在使用公司安装设施安装了一些模块后遇到了这个问题。由于安装是在后台进行的,除了foo阻止我的构建外,我不知道它做了什么。
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:动态链接库搜索顺序
加载程序将选择它首先看到的(在搜索列表中)具有匹配名称的任何dll。DLL是64位还是32位并不重要。我很确定,如果它是一个重命名为.dll的文本文件,它甚至会尝试加载它也许你的同事把他的dll放在了系统文件夹中,或者与应用程序版本并排。
我发现处理这个问题的一个简单方法是为32位和64位的dll使用不同的名称。example32.dll和example64.dll。
- 将应用程序从32位移植到64位时出现问题
- qmake:检测目标位宽(32 位或 64 位)
- 如何在 64 位 vb.net Windows 应用程序中引用 32 位 dll
- 浮点数为 32 位和 64 位二进制表示形式
- 如何在 64 位平台上计算 32 位哈希C++?
- 制定目标需要32和64位的DLL构建
- 在32、64位正确存储容器大小
- 如何将 32 位有符号整数放入更高的 32 位 64 位无符号整数中
- 与同时32和64位客户端同时使用Process COM服务器
- C++使用 MSI 自动化 API 32 和 64 位的应用程序
- 算法C/C++:用n和d 32或64位整数计算(2^n)%d的最快方法
- 32位- 64位进程间通信
- visual c++ Windows Shell Extensions - Win7 32位- 64位兼容性问题
- 如何在运行的C++/Qt应用程序中检测底层Windows是否为32或64位版本
- 正确(独立于32位/64位)将浮点数保存为二进制流
- 32 位 64 位 - 警告:右移计数 >= 32 位计算机上的类型宽度
- 澄清:移植32到64位
- 使用C++检测Windows体系结构(32或64位)-wProcessorArchitecture显示错误的结果
- 如何编写可转换代码,32位/64位
- c++:如何在Windows 32和64位获取最新的Java路径