【问题标题】:C# compiling for 32/64 bit, or for any cpu puzzlerC# 编译为 32/64 位,或任何 cpu 谜题
【发布时间】:2011-11-11 13:35:42
【问题描述】:

这个问题与之前关于 SO 的问题有关

Any CPU question 1Any CPU Question 2

我有一个最初使用 Visual Studio 2005 在 Win XP 上构建的应用程序(别笑!)。这个应用程序调用了我们的 win32 C++ dll。调用 C++ dll 的 C# 组件是使用“Any CPU”配置构建的,并且在 Win XP 上运行愉快,没有任何问题。

我们现在正在迁移到 Win 7,并且我们的应用程序的发布版本(基于 Win XP 和 VC 2005 构建)运行良好。然而,随着向我们的用户推出 win 7,我们现在有机会迁移到 VS 2010,并且我已经使用 VC 2010 在 win 7 上构建了 C# 组件,但是现在在运行这个版本时,我得到很多“无法加载 abc。 dll”,其中 abc.dll 是我们的 win32 c++ 组件。

我知道使用 x86 配置重新编译 C# 程序集可以解决问题,但我不明白的是使用 Win-XP/Visual Studio 2005(任何 CPU 配置)构建的发行版 c# 程序集如何能够运行Win 7没有任何问题?当然,这些使用“任何 CPU”构建的 C# 程序集在 Win 7 中加载时应该 JIT 到 64 位代码,并导致 BadImageFormatException 或其他错误,因为它们调用 Win32 C++ dll。


更新:我在下面的 cmets 中要求提供更多信息。

  1. 在我的 Windows 7 机器上,我右键单击我的计算机并查看属性。系统信息显示“系统类型:64 位操作系统”,确认这是 Win64 操作系统。

  2. 在 Windows XP 的 VC2005 中打开解决方案 查看解决方案的配置管理器时,我可以确认 所有 C# 项目是平台类型“任何 CPU”。

  3. 在 64 位 Win 7 机器上运行发布版本(在 VC2005/win xp 上完成)时,我的任务管理器显示图像名称为“Test.exe *32”,这确认它是 jit'd并加载到 32 位进程中。

【问题讨论】:

  • 两种情况下的目标环境位数是否相同?这可能是另一个偷偷摸摸的变化?
  • 这里发生了一些你没有告诉我们的事情。 AnyCPU 程序集将是 64 位系统上的 64 位进程。它在哪里建造并不重要。
  • 只有 EXE 项目上的平台目标设置很重要,它决定了进程的位数。请注意,构建 + 配置管理器中的活动平台选择适用于托管项目。
  • 哦哦!从 XP/VS2005 组合执行构建时,使用 Windows 7 中的任务管理器检查位数。如果您的 exe 加载了 *32,则为 32 位,如果不是,则为 64 位。让我们知道 XP/VS2005 构建是作为 32 位还是 64 位执行的。
  • 您确定原始版本运行的 Windows 7 系统是 64 位系统吗?毕竟,并非所有的 Windows 7 安装都是 64 位的。

标签: c#


【解决方案1】:

在Win7下,进程是64位的。 64 位进程中不能有 32 位 DLL,这是 Windows 的一个非常基本的设计限制。

而且这个托管代码 EXE 调用到 32 位 DLL 的事实从一开始并不明显 - P/Invoke 以及 COM 互操作通过后期绑定工作。所以加载了 EXE,加载器不检查依赖项 - 一方面,依赖项可能是有条件的 - 然后 DLL 加载时间到了,古怪接踵而至。

是的,如果您有已知的 32 位依赖项的托管代码,您最好在编译时指定 32 位 CPU。或者将 C++ 部分重新编译为 64 位,这也是一种选择。

【讨论】:

  • 那么为什么他没有必须用 VS2005 指定 32 位?
  • 感谢 Seva,但您错过了重点,Branko 明白了:问题是为什么它在使用“任何 CPU”的 Win XP/VC2005 上运行但在使用 Win 7/ 构建时不起作用VC2010“任何 CPU”
  • 也许构建机器的位数会影响 EXE 映像...不确定:) 从这个问题来看,在 Win7 机器上构建 VS2005 会产生什么结果并不明显。
  • @Seva “也许构建机器位数会影响 EXE 映像”。不。“从这个问题来看,在 Win7 机器上构建 VS2005 会产生什么结果并不明显。”是的。 AnyCPU 目标在 x64 系统上运行 x64,在 x86 系统上运行 x86。
  • 您的意思是不是:“这是任何操作系统的一个非常基本的限制”。
【解决方案2】:

我可以确认您应该得到 BadImageFormatException。 XP上的编译是否有可能被严重欺骗以至于它实际上并没有构建AnyCPU,而是构建标记为AnyCPU的x86。我还可以确认,有可能对项目文件进行严重的欺骗,以至于它会这样做,并且项目升级组件会因此而窒息。

【讨论】:

  • monkeyed ...这是一个新的技术术语:-)。我认为你的意思是编译成 IL 代码?
【解决方案3】:

一种可能的解释是,您在 32 位开发系统上的解决方案中的一个项目具有对 32 位程序集的二进制引用,这将强制它作为 32 位进程加载,即使在 64-位系统。

【讨论】:

  • 如果我的进程的入口点在 C# exe 中,那么肯定必须将其 JIT 转换为 32 位/64 位 exe 并首先加载到适当的进程中,然后调用 win 32 (无论如何都是后期绑定的)应该生成异常(错误的图像格式)......或者我在这里错过了什么?
  • 根据我的经验,虽然本机 DLL 确实是后期绑定的,并且如果存在位不匹配会生成您提到的异常,但对编译为 32 位的托管 DLL 的非项目引用确实会强制执行作为 32 位应用程序启动的进程。
猜你喜欢
  • 2011-07-10
  • 2018-08-04
  • 1970-01-01
  • 2021-06-25
  • 2011-04-12
  • 1970-01-01
  • 2014-01-12
  • 2020-12-10
  • 1970-01-01
相关资源
最近更新 更多