为 Windows 编写跨平台(32 位和 64 位兼容)程序(如 .NET 中的 AnyCPU)

Posted

技术标签:

【中文标题】为 Windows 编写跨平台(32 位和 64 位兼容)程序(如 .NET 中的 AnyCPU)【英文标题】:Writing a Cross-Platform (32-bit and 64-bit compatible) Program for Windows (like AnyCPU in .NET) 【发布时间】:2011-01-10 03:28:58 【问题描述】:

.NET 中的“AnyCPU”功能如何工作让我感到困惑:如果系统是 32 位,它将可执行文件加载为本机 32 位,如果系统是 64 位,则加载为 64 位(您可以通过任务管理器轻松确认)。显然,这并非不可能。

问题是,微软究竟是如何做到这一点的? Windows 最初并不知道 .NET 框架,因此 Windows PE 加载器不可能在 PE 头中为 CLR 头寻找任何额外的功能;此功能一定是由某种内核模式扩展添加的。但是 .NET 框架似乎没有安装这样的东西......我完全不知道同一个可执行文件如何同时是本机 32 位和 64 位,特别是因为 mscoree.dll 的反汇编没有'甚至不显示对未记录本机函数的引用。

有没有人知道和/或合理猜测这是如何做到的?这显然是可能的(所以没有说“不可能”之类的话),这让我想尝试编写一个 native 跨平台 EXE...


编辑:

作为旁注,请考虑您如何无法在 64 位 Windows PE 环境中运行 32 位可执行文件...得到某种方式来扩展或修改 PE 加载程序有某种“插件”,对吧?

【问题讨论】:

有一些程序(例如 Process Explores)会执行此操作,我会分发一个 32 位可执行文件,如果可能,它会启动一个 64 位映像。例如。除了 32 位 PE,“AnyCPU”可执行文件是什么? @pst:我完全了解这些,但不,它们是不同的。 AnyCPU 可执行文件从它们在 64 位操作系统上启动的那一刻起就是 64 位的——没有解包,也没有像“让我们将此字节码代码 JIT 为 64 位,然后重新启动 64 位进程”之类的东西。这就是让我感到困惑的原因。 【参考方案1】:

您的问题是基于误解。这是错误:

Windows 最初并不知道 .NET 框架

实际上,从 Windows XP 开始,Windows IS aware of the .NET executable format。 XP 是第一个支持 64 位的 Windows 版本。

因此 PE 标头被标记为 32 位,并且本机导入表引用 32 位 mscoree,这在 Windows 2000 和更早版本上会导致加载 32 位 .NET。 DllMain for mscoree 开始 JITting 应用程序代码并修改主应用程序的入口点。

Windows XP 及更高版本在了解 .NET 元数据后,会识别出它是 AnyCPU 并加载相应的框架。

Here's probably more than you ever wanted to know about the process.

所以不,没有原生的AnyCPU exe。虽然可以在 32 位 PE 中嵌入 16 位 DOS 程序,但不能同时拥有 32 位和 64 位 .exe

【讨论】:

.NET 框架不是在 XP 发布之后出现的吗(至少,我以为我记得的)?我以为XP was released in 2001 和.NET in 2002... @Lambert:开发时期重叠,.NET 开发在 2002 年首次发布之前大约 5 年开始,因此微软有足够的时间将钩子放入 XP。正如我所说,Windows 2000 只有 32 位。无论如何,您应该考虑几年后 Windows XP 64 位版本的发布日期,因为它是第一个需要这种“魔力”的版本。 啊……这就解释了。 (是的,很抱歉,我在您发布之前删除了关于我的评论的 Windows 2000 部分,因为我记得它没有 64 位。)不是我正在寻找的答案,但绝对看起来是正确的;谢谢! :) @Lambert:添加了两个链接,您可能会喜欢阅读以了解更多详情。 @Ben:我已经阅读了第一个链接,但第二个链接是新的。起初我以为这会告诉我关于 WOW64 thunk 和所有这些的信息,而且我没有抱怨已经知道这些,因为 .NET 信息绝对是新的和有用的。感谢您发布这些!希望我能再给一个+1。 :)【参考方案2】:

如果系统具有 WOW64 仿真层(Windows Vista+,不知道 XP),您实际上可以在 x86 可执行文件中包含 x64 代码。 http://vxheavens.com/lib/vrg02.html

我已经测试过这种技术,它适用于 Win7 和 WinVista。我在汇编中编写了一个小存根来解析导入并加载一些为 AMD64 编译的 C 代码。

微软只是说你不能来回转换,因为他们可能会改变它,但我怀疑这会改变,直到底层架构改变以允许像 128 位这样的东西也能运行......那时我怀疑 WOW64将在附近:),WOW128 ftl。

【讨论】:

以上是关于为 Windows 编写跨平台(32 位和 64 位兼容)程序(如 .NET 中的 AnyCPU)的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法让 Windows 64 位上的应用程序在 64 位和 32 位仿真层下执行代码?

32 位和 64 位版本的 windows 操作系统的页面大小是多少?

Windows平台安装MongoDB教程

扫盲32位和64位Windows的区别

最详细的Windows平台安装MongoDB教程

配置 Visual Studio 以创建 32 位和 64 位配置