Visual Studio“任何 CPU”目标是啥意思?

Posted

技术标签:

【中文标题】Visual Studio“任何 CPU”目标是啥意思?【英文标题】:What does the Visual Studio "Any CPU" target mean?Visual Studio“任何 CPU”目标是什么意思? 【发布时间】:2009-02-05 16:43:26 【问题描述】:

我对 Visual Studio 2008 中的 .NET 平台构建选项有些困惑。

什么是“Any CPU”编译目标,它生成什么样的文件?我检查了这个“任何 CPU”构建的输出可执行文件,发现它们是 x86 可执行文件(谁不会看到它的到来!)。那么,将可执行文件定位到 x86 与“任何 CPU”之间有什么区别吗?

我注意到的另一件事是托管 C++ 项目没有此平台作为选项。这是为什么?这是否意味着我对“任何 CPU”可执行文件是普通 32 位可执行文件的怀疑是正确的?

【问题讨论】:

在决定使用哪个平台目标时要考虑的另一件事:如果 启动项目 的目标是 Any CPU 并且您在 64 位操作系统上运行,您在调试时无法编辑并继续。 (您正在有效地调试 64 位进程)。您可以将 Startup project 设为目标 x86 以在调试时规避此问题。 (从启动项目引用的程序集可能会继续以Any CPU为目标。 @CristiDiaconescu 使用 VS2013 编辑和继续现在是可能的 我认为这里应该注意一下项目是应用程序还是类库,因为为后者设置目标位数可能会影响其对消费应用程序的可用性,具体取决于平台。我遇到了一个 x86 库被 AnyCPU 应用程序使用的问题,我必须设置 Prefer 32-bit 以避免加载错误。 【参考方案1】:

AnyCPU 程序集在加载到 64 位进程时将 JIT 到 64 位代码,在加载到 32 位进程时将 JIT 到 32 位。

通过限制 CPU,您会说:程序集正在使用某些东西(可能 非托管),需要 32 位或 64 位。

【讨论】:

那么,我如何生成在 C++ 中 JIT 到 x64 的程序集? C++ 项目编译为本机代码,因此不涉及 JIT 编译器......因此,您不能按照您的要求进行操作。 来自 MS 的一些信息在此链接:msdn.microsoft.com/en-us/library/zekwfyz4.aspx 嗨 Anthony,请更新您的答案 w.r.t. the 32-bit preferred option。 This answer 和 this answer 包含最新信息。 这个答案不再正确。多年来,AnyCPU 的含义发生了数次变化。【参考方案2】:

我想大部分重要的东西都已经说了,但我只是想补充一点:如果你编译为 Any CPU 并在 x64 平台上运行,那么你不会能够加载 32 位 DLL 文件,因为您的应用程序不是在 WoW64 中启动的,但是那些 DLL 文件需要在那里运行。

如果您编译为 x86,则 x64 系统将在 WoW64 中运行您的应用程序,您将能够加载 32 位 DLL 文件。

所以我认为如果您的依赖项可以在任一环境中运行,您应该选择“Any CPU”,但如果您有 32 位依赖项,请选择 x86。 Microsoft 的这篇文章对此进行了一些解释:

/CLRIMAGETYPE (Specify Type of CLR Image)

顺便说一句,this other Microsoft documentation 同意 x86 通常是更便携的选择:

选择 x86 通常是应用程序包最安全的配置 因为它几乎可以在所有设备上运行。在某些设备上,应用程序 x86 配置的包将无法运行,例如 Xbox 或某些 物联网核心设备。但是,对于 PC,x86 包是最安全的 选择并具有最大的设备部署范围。一个实质性的 部分 Windows 10 设备继续运行 x86 版本的 窗户。

【讨论】:

也许您可以编辑您的答案,说明如何确定给定的 DLL 是否仅为 32 位。据我所知,this 应该可以解决这个问题。我认为我们希望 DLL 也是“任何 CPU”,而不仅仅是 x86。 +1 是一个重要的区别。需要使用 32 位依赖项(未确定为这样)。无法弄清楚神秘的运行时错误消息。预感改变了 cpu 目标并且它工作但去寻找“为什么”。当一切都是 64 位并且不兼容问题看起来像现在 16 位和 32 位一样古怪时,总有一天会很好。 @GeraldDavis - 我同意。具有讽刺意味的是,没有技术原因不能混合 32 位和 64 位依赖项(只是 CLR 中缺少一个 thunking 层),当我看到 bit-在部署时仍然需要考虑 ness (考虑到这是一个 VM / JIT,这将是一个提供更多附加值的机会)。 @mrjoltcola: 比这更糟糕的是微软出于某种原因决定的方式,我无法理解注册表项应该被拆分为 32 位和 64 位域,即使它们控制诸如屏幕颜色、默认设置等 这是我正在寻找的答案...谢谢!【参考方案3】:

感谢本书"CLR via C#",请参阅:

【讨论】:

这是截至 09/06/2018 和 VS 15.8.0 的最准确答案【参考方案4】:

这里是 a quick overview,它解释了不同的构建目标。

根据我自己的经验,如果您希望构建一个可在 x86 和 x64 平台上运行的项目,并且您没有任何特定的 x64 优化,我会将构建更改为专门说“x86. "

这样做的原因是有时您可能会在 x64 环境中获得一些冲突的 DLL 文件或导致崩溃的代码 WoW。通过明确指定 x86,x64 操作系统会将应用程序视为纯 x86 应用程序,并确保一切顺利运行。

【讨论】:

如果您为服务器环境编写并希望您的应用程序能够使用超过 2GB 的内存,这可能会很糟糕。您还可以选择退出任何有朝一日可能会出现的 x64 JIT 优化。 我在 AnyCPU 编译中遇到的大量运行时问题是我停止使用它作为构建选项所需要的全部理由,除非有人明确要求在两者上都可以使用的二进制文件。 10 多年来,我没有任何人请求 x64 之上的 x86 二进制文件。 “通过明确指定 x86,x64 操作系统会将应用程序视为纯 x86 应用程序,并确保一切顺利运行。” - 对不起,我不同意。 x64 操作系统仍将在 WOW64 中运行您的 x86 应用程序 对于那些不完全了解它会产生的影响的人来说,这只是一个糟糕的建议。 @AustinHarris 举了一个很好的例子。想象一下一个仅限于几 GB RAM 的 Web Worker 进程(我最近不得不在生产中处理这个问题)。【参考方案5】:

查看文章Visual Studio .NET Platform Target Explained

默认设置“Any CPU”表示程序集将运行 本机在当前运行的 CPU 上。意思是,它将运行 在 64 位机器上为 64 位,在 32 位机器上为 32 位。如果 从 64 位应用程序调用程序集,它将作为 64位汇编等等。

上面的链接已经被报坏了,所以这里有另一篇类似解释的文章:What AnyCPU Really Means As Of .NET 4.5 and Visual Studio 11

【讨论】:

【参考方案6】:

“Any CPU”表示当程序启动时,.NET Framework 会根据操作系统的位数来判断程序是以 32 位还是 64 位运行。

x86Any CPU 之间存在区别:在 x64 系统上,为 X86 编译的可执行文件将作为 32 位可执行文件运行。

就您的怀疑而言,只需转到 Visual Studio 2008 命令行并运行以下命令。

dumpbin YourProgram.exe /headers

它会告诉您程序的位数,以及更多信息。

【讨论】:

如果它内置在“any cpu”中,它将在dumpbin headers中显示为32bit。【参考方案7】:

任何 CPU 意味着它可以在任何平台上工作。这是因为托管代码类似于 Java。将其视为被编译为 .NET Framework 在运行时解释的字节码。

C++ 没有此选项,因为它被编译为特定于平台的机器代码。

【讨论】:

+1 用于回答其他人没有做过的问题的一部分(关于没有 AnyCPU 作为选项的 C++ 项目)。 C++/CLI 可以编译为 IL 代码,无需任何机器代码 (/clr:pure)。但是 sizeof(void*) 在 C++ 中仍然需要是编译时常量;因此,即使不涉及机器代码,您仍然无法创建同时适用于 32 位和 64 位的二进制文件。【参考方案8】:

我推荐阅读this post。

使用AnyCPU时,语义如下:

如果进程在 32 位 Windows 系统上运行,它将作为 32 位进程运行。 CIL 编译为 x86 机器码。 如果进程在 64 位 Windows 系统上运行,它将作为 32 位进程运行。 CIL 被编译成 x86 机器码。 如果进程在 ARM Windows 系统上运行,它将作为 32 位进程运行。 CIL 被编译为 ARM 机器代码。

【讨论】:

Only if "Prefer 32-bit" is selected. 这是自 Visual Studio 11 以来的默认设置 @Moerwald 我相信这是一个已修复的错误。如果您阅读了post mamczas 的引用,作者写道“在当前的 Visual Studio UI 中,“首选 32 位”已灰显且未选中,实际上它已启用……”;在我的 VS (15.8.0) 版本中,该选项仍然灰显且未选中,但是,它按预期工作(在已编译程序集的 CorFlags 部分中标记 32BITPREF = FALSE)

以上是关于Visual Studio“任何 CPU”目标是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

启动visual studio时taskscheduler引发了异常是啥原因?

如何根据开发人员的操作系统架构在 Visual Studio 中复制文件?

visual studio 和visual studio code 的区别是啥?

^ 在 Visual Studio C++ 中是啥意思? [复制]

Microsoft Visual C++与Visual Studio的区别是啥?

Visual Studio Team System 的最佳功能是啥?