什么是“ Any CPU”编译目标,它生成什么样的文件?我检查了此“任何CPU”构建的输出可执行文件,发现它们是x86可执行文件(谁看不到它!)。因此,将可执行文件定向到x86与“任何CPU”之间有什么区别吗?
我注意到的另一件事是,托管C ++项目没有该平台作为选项。这是为什么?这是否意味着我对“任何CPU”可执行文件都是纯32位可执行文件的怀疑是正确的?
#1 楼
当加载到64位进程中时,AnyCPU程序集将JIT转换为64位代码;当加载到32位进程中时,AnyCPU程序集将JIT转换为32位。通过限制CPU,您会说:由需要32位或64位的程序集使用(可能是
不受管理的)。
评论
那么,如何在C ++中生成将JIT转换为x64的程序集?
– Galets
09年2月5日在16:48
C ++项目可以编译为本机代码,因此不涉及JIT编译器...因此,您无法执行所要求的操作。
–cplotts
2010年5月25日14:53
MS通过此链接提供的一些信息:msdn.microsoft.com/en-us/library/zekwfyz4.aspx
– Doug J. Huras
2015年2月25日在14:55
安东尼,您好,请更新您的答案。 32位首选选项。该答案和此答案包含最新信息。
–user247702
18 Mar 22 '18在9:41
这个答案不再正确。这些年来,AnyCPU的含义已经改变了好几次。
–P.Brian.Mackey
18年4月19日在21:00
#2 楼
我认为已经讲了大多数重要的内容,但我只是想补充一件事:如果您以Any CPU身份进行编译并在x64平台上运行,那么您将无法加载32位DLL文件,因为您的应用程序不是在WoW64中启动的,但是那些DLL文件需要在其中运行。如果您以x86进行编译,则x64系统将在WoW64中运行您的应用程序,您将能够加载32位DLL文件。
因此,如果您的依赖项可以在任一环境中运行,那么我认为您应该选择“ Any CPU”,而如果您具有32位依赖项,则应该选择x86。 Microsoft的这篇文章对此做了一些解释:
/ CLRIMAGETYPE(指定CLR图像的类型)
顺便说一句,此其他Microsoft文档也同意x86通常是更可移植的选择:
选择x86通常是应用程序包最安全的配置
,因为它几乎可以在所有设备上运行。在某些设备上,具有x86配置的应用程序
包将无法运行,例如Xbox或某些
IoT核心版设备。但是,对于PC而言,x86软件包是最安全的选择,并且对设备部署的影响最大。 Windows 10设备的相当一部分
继续运行xbr版本的Windows
Windows。
评论
也许您可以编辑答案以说出如何确定给定的DLL是否仅为32位。据我所知,这应该可以解决。我认为我们希望DLL也是“任何CPU”,而不只是x86。
– Dan W
13年7月10日在11:01
+1重要区别。需要使用32位依赖项(未这样确定)。无法找出神秘的运行时错误消息。凭直觉改变了cpu的目标,它起作用了,但是却去寻找“为什么”。总有一天,当所有东西都是64位,并且不兼容的问题看起来像16bit vs 32bit那样古朴,这将是美好的。
–杰拉德·戴维斯(Gerald Davis)
2014年3月25日17:23
@GeraldDavis-我同意。具有讽刺意味的是,没有技术原因无法混合使用32位和64位依赖项(只是CLR中缺少thunk层),当我看到.NET时,我对.NET感到失望。部署时仍然需要考虑其他因素(考虑到这是VM / JIT,这将是提供更多附加值的机会)。
– Codenheim
2014年3月31日22:42
@mrjoltcola:甚至比微软更糟糕的是,我决定的原因是我无法理解注册表项应该拆分为32位和64位Universe,即使它们控制屏幕颜色,默认设置等。
–超级猫
2014年5月16日21:45
这就是我一直在寻找的答案...谢谢!
– Daminion Software的Murat
2014年12月12日上午9:57
#3 楼
这是一个快速的概述,解释了不同的构建目标。根据我的经验,如果您要构建一个既可以在x86平台上运行又可以在x64平台上运行的项目,特定的x64优化,我会将该版本更改为专门说“ x86”。
这样做的原因有时是您可能会遇到一些DLL文件冲突或某些代码,这些代码最终会在x64环境中崩溃导致WOW崩溃。通过专门指定x86,x64 OS会将应用程序视为纯x86应用程序,并确保一切运行顺利。
评论
如果您在服务器环境中撰写文章并希望您的应用程序能够使用超过2GB的内存,那可能会很糟糕。您还选择不使用某天可能会出现的任何x64 JIT优化。
–奥斯汀·哈里斯(Austin Harris)
13年5月13日在20:45
我停止AnyCPU编译时遇到的所有运行时问题,就是我停止使用它作为生成选项所需要的全部理由,除非有人明确要求在两者上均可使用的二进制文件。在过去的十年中,我还没有人要求x64上的x86二进制文件。
–kayleeFrye_onDeck
18年5月18日在23:42
“通过专门指定x86,x64操作系统会将应用程序视为纯x86应用程序,并确保一切运行顺利。” -对不起,我不同意。 x64 OS仍将在WOW64中运行您的x86应用
–曼迪普(Mandeep Janjua)
18-10-16在16:30
对于那些不完全了解其影响的人来说,这只是个坏建议。 @AustinHarris就是一个很好的例子。想象一下,一个Web worker进程仅限于几个GB的RAM(我最近在生产中不得不处理这个问题)。
–rgoliveira
18年11月13日在17:55
#4 楼
归功于《通过C#进行CLR》一书,请参见:评论
这是截至2018年9月6日和VS 15.8.0的最准确答案
– Raikol Amaro
18-09-6在16:18
#5 楼
请查看文章Visual Studio .NET平台目标说明。默认设置“任何CPU”表示该程序集将在当前当前运行的CPU上本地运行。继续前进。意思是,它将在64位计算机上以64位运行,在32位计算机上以32位运行。如果从64位应用程序调用
程序集,它将作为
64位程序集执行,依此类推。
上面的链接已经被删除。据报告已损坏,因此这是另一篇带有类似解释的文章:.NET 4.5和Visual Studio 11中AnyCPU的真正含义
评论
链接已断开-立即转到托管域。
–乔恩·亚当斯(Jon Adams)
17年12月10日在17:58
我在第二篇文章中添加了具有类似信息的链接。万一该域被重新激活,我离开了第一个链接。
– DCNYAM
17年12月11日在13:41
该链接也断开了。
–dynamichael
12月13日下午5:05
#6 楼
“任何CPU”表示启动程序时,.NET Framework将根据操作系统的位数确定是以32位还是64位运行程序。有区别在x86和任何CPU之间:在x64系统上,为X86编译的可执行文件将作为32位可执行文件运行。
只要怀疑,只需转到Visual Studio 2008命令行,然后运行以下命令。
dumpbin YourProgram.exe /headers
它会告诉您程序的细节,以及更多内容。
评论
如果内置于“ any cpu”中,则它将在dumpbin标头中显示为32bit。
–麒麟头
13年11月12日在17:23
#7 楼
任何CPU都意味着它将可以在任何平台上运行。这是因为托管代码类似于Java。可以将其视为编译为运行时.NET Framework解释的字节码。C ++没有此选项,因为它被编译为特定于平台的机器代码。 br />
评论
+1用于回答其他人没有做过的问题的一部分(关于没有将AnyCPU作为选项的C ++项目)。
–cplotts
2010年5月25日14:44
可以将C ++ / CLI编译为IL代码,而无需任何机器代码(/ clr:pure)。但是sizeof(void *)仍然需要在C ++中是一个编译时常量。因此,即使不涉及任何机器代码,您仍然无法创建可同时在32位和64位上运行的二进制文件。
–丹尼尔(Daniel)
4月30日10:29
#8 楼
我建议阅读这篇文章。使用AnyCPU时,语义如下:
如果进程在32位Windows上运行系统,它作为32位进程运行。 CIL被编译为x86机器代码。
如果该进程在64位Windows系统上运行,则它将作为32位进程运行。 CIL被编译为x86机器代码。
如果该进程在ARM Windows系统上运行,则它将作为32位进程运行。 CIL被编译为ARM机器代码。
评论
只有当“首选32位”被选中。
–佛罗里达冬季
17年9月11日在16:03
自Visual Studio 11以来的默认设置
–默瓦尔德
18年1月19日在5:52
@Moerwald我相信这是一个已修复的错误。如果您阅读了mamczas所引用的文章,那么作者将写道:“在当前的Visual Studio UI中,“首选32位”显示为灰色且未选中,实际上是启用的……”;在我的VS(15.8.0)版本中,该选项仍显示为灰色且未选中,但是,它可以按预期工作(已编译程序集的CorFlags部分中的标志32BITPREF = FALSE)
– Raikol Amaro
18-09-6在16:23
评论
决定使用哪个平台目标时还要考虑的另一件事:如果Startup项目的目标是Any CPU,并且在64位OS上运行,则您将失去编辑和继续调试的能力。 (您实际上是在调试64位进程)。您可以将Startup项目的目标设为x86,以在调试时规避此问题。 (从启动项目引用的程序集可能继续以任何CPU为目标。@CristiDiaconescu现在可以使用VS2013编辑并继续
我认为这里应该注意项目是应用程序还是类库,因为为后者设置目标位数可能会影响平台对消费应用程序的可用性。我遇到了一个x86库被AnyCPU应用程序占用的问题,在该应用程序中必须将Prefer设置为32位以避免加载错误。