Visual Studio: "Target CPU" setting in "Advanced Compiler Settings". What does it do?
Visual Studio 2010 (paid edition) gives a selection of four target CPUs for .NET programs: AnyCPU, x86, x64 and Itanium.
What exactly do those settings do?
I noticed that (on a x64 Windows 7 machine), the binaries created with AnyCPU and x86 are of the same size and binaries created with x64 or Itanium are of the same size (but smaller than the first). Binaries created for x86 also appear to run in WoW64, while same-size binaries compiled for AnyCPU do not. Binaries optimised for Itanium do not run at all on Windows 7 x64 (which makes sense).
I assume Windows 开发者_StackOverflow中文版runs AnyCPU binaries in whatever the native mode is (x64 in my case) and runs x86 in WoW64 on 64 bit machines (x64 and Itanium). But how do the binary sizes come in?
Any CPU allows the application or library to run as either a 64bit process or a 32bit process, depending of the bitness of the operating system the process is launched on.
x86 applications will always run as 32bit application regardless of the bitness of the operating system.
x64 applications will only run on a 64bit operating system. This is also sometimes called AMD64 as AMD created this 64bit instruction set.
Itanium is for the Itanium CPU.
If you have an Any CPU application and it loads an x86 library the application will work under 32bit Windows, but will throw an exception under 64bit Windows.
When you specify the architecture for your application or library you are telling the framework that your application will only work with that architecture. For instance if your applications does something that is specific to the x86 architecture you want to make sure it is not loaded into a 64bit process or an Itanium process. You do this by setting the target CPU.
If you do something specific to the x86 architecture and you compile to Any CPU your application will work under 32bit windows as the .NET runtime will be in 32bit mode. If your application is run under a 64Bit os or an Itanium os the runtime will look at your application seeing AnyCPU and try to use native 64bit code. Your application will then fail. If your specify x86 then the runtime will start in 32bit mode and your application will run correctly.
The setting is telling the Framework what architectures it is safe to run under.
What is actually happening is some of the metadata for the application is set differently. You can see this information with dumpbin.exe Here is an example of the output for an AnyCPU library
bin\Debug>dumpbin /CLRHEADER bitnesstest.dll Microsoft (R) COFF/PE Dumper Version 10.00.30319.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file bitnesstest.dll File Type: DLL clr Header: 48 cb 2.05 runtime version 2058 [ 5D0] RVA [size] of MetaData Directory 1 flags IL Only 0 entry point token 0 [ 0] RVA [size] of Resources Directory 0 [ 0] RVA [size] of StrongNameSignature Directory 0 [ 0] RVA [size] of CodeManagerTable Directory 0 [ 0] RVA [size] of VTableFixups Directory 0 [ 0] RVA [size] of ExportAddressTableJumps Directory 0 [ 0] RVA [size] of ManagedNativeHeader Directory
and an x86 library
bin\Debug>dumpbin /CLRHEADER bitnesstest.dll Microsoft (R) COFF/PE Dumper Version 10.00.30319.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file bitnesstest.dll File Type: DLL clr Header: 48 cb 2.05 runtime version 2058 [ 5D0] RVA [size] of MetaData Directory 3 flags IL Only 32-Bit Required 0 entry point token 0 [ 0] RVA [size] of Resources Directory 0 [ 0] RVA [size] of StrongNameSignature Directory 0 [ 0] RVA [size] of CodeManagerTable Directory 0 [ 0] RVA [size] of VTableFixups Directory 0 [ 0] RVA [size] of ExportAddressTableJumps Directory 0 [ 0] RVA [size] of ManagedNativeHeader Directory
To show the difference between x64 and IA64 - Itanium you can use dumpbin with the /HEADERS switch. The /CLRHEADERS are the same for both as was noted in the comments.
From MSDN:
The Target CPU (Platform target in C#) project property specifies whether the compiler should optimize compilation for a specific CPU type, for example, a 64-bit processor. You can set the target platform to all CPU types or to a specific CPU type of x86, x64, or Itanium. By default, this option is set to AnyCPU (Any CPU in C#), which specifies that the compiler should not optimize compilation for a specific CPU type.
AnyCPU causes the JIT to run the code in the Architecture of the Machine the code is being JITted on.
Setting it to any specific Architecture will cause it to be built to be only ran by the JIT in that specific Architecture.
So as to why any CPU doesn't run under WOW64 on a 64 bit machine it's because that is for x86 binaries where yours are being executed as x64.
BTW, changing the CPU option will also change the default locations for the debug/release versions of the compiled code from path\bin\debug to path\bin\x86\debug etc. You may want to remove the path\bin\debug and path\bin\release directories to prevent accidentally grabbing a really old version of your application.
精彩评论