Let's assume we have the following three dlls:
anycpu.dll -- compiled "any cpu"
x86.dll -- compiled "x86"
x64.dll -- compiled "x64"
And the following three exes:
anycpu.exe -- compiled "any cpu"
x86.exe -- compiled "x86"
x64.exe -- compiled "x64"
What happens if you try to use these exes and dlls together? We have to consider two possible scenarios, running on a 32-bit machine and running on a 64-bit machine...
On a 32-bit x86 machine:
anycpu.exe -- runs as a 32-bit process, can load anycpu.dll and x86.dll, will get BadImageFormatException if it tries to load x64.dll
x86.exe -- runs as a 32-bit process, can load anycpu.dll and x86.dll, will get BadImageFormatException if it tries to load x64.dll
x64.exe -- will get BadImageFormatException when it tries to run
On a 64-bit x64 machine:
anycpu.exe -- runs as a 64-bit process, can load anycpu.dll and x64.dll, will get BadImageFormatException if it tries to load x86.dll
x86.exe -- runs as a 32-bit process, can load anycpu.dll and x86.dll, will get BadImageFormatException if it tries to load x64.dll
x64.exe -- runs as a 64-bit process, can load anycpu.dll and x64.dll, will get BadImageFormatException if it tries to load x86.dll
The Platform Target is an often overlooked option in the build configuration for Visual Studio 2005 and 2008 projects. For C# projects, you will find this option on the Project Properties dialog under the build tab. For VB.net projects, the setting is found on the Advanced Compiler Settings dialog which is made available via the Advanced Compile Options button on the Compile tab of the Project Properties. The list of available options are:
- Any CPU
- x86
- x64
- Itanium
The meaning of these options is often misunderstood. Based on their names, one might think that the compiler will generate code differently based upon the setting. However, the C# and VB.net compilers only generate IL code that is taken to native code by the CLR at runtime using the just-in-time compiler (unless ngen is used but that is another discussion). The fact is that this setting actually does not affect the build of the assembly in any way except to set the platform status information on the assembly’s CLR header. In other words, the Platform Target setting is meant to communicate the platform that the developer intends to be compatible with.
The default setting, Any CPU, means that the assembly will run natively on the CPU is it currently running on. Meaning, it will run as 64-bit on a 64-bit machine and 32-bit on a 32-bit machine. If the assembly is called from a 64-bit application, it will perform as a 64-bit assembly and so on.
If the project is set to x86, this means the project is intended to run only as a 32-bit process. A 64-bit process will be unable to call into an assembly set as X86. Reasons to set your project as x86 include dependencies upon native DLLs that are only available in 32-bit or making native calls assuming 32-bit . Applications and assemblies marked for x86 can still run on 64-bit Windows. However they run under WOW64. Visual Studio itself runs under this emulation mode since it is a 32-bit application.
Setting the project to x64 will specify that the assembly must run under 64-bit Windows. Attempting to run the assembly on 32-bit Windows or call the assembly from a 32-bit process will result in a runtime error.
The final, and likely least common, setting is Itanium. This setting specifies that the assembly will only run on an Itanium processor. The only reason to set your project for Itanium is if it has dependencies on native DLLs compiled specifically for the Itanium processor.
Developers should be aware that simply marking Platform Target of an assembly as Any CPU does not guarantee that it will run on both 32-bit and 64-bit Windows. In fact, since Any CPU is the default setting, there are likely many applications that actually depend upon 32-bit processing but are not marked as such. These assemblies will fail under 64-bit Windows when run from a 64-bit process so it is important to perform testing for your applications before users are migrated to 64-bit. The somewhat increasing popularity of Vista x64 will soon elevate the importance of this type of testing.
Another point to be aware of when attempting to migrate to 64-bit processing for .Net applications is the dependency upon assemblies originally built using Visual Studio 2002 and 2003. All assemblies targeting .Net 1.0 and 1.1 will be 32-bit only (x86) so these assemblies will need to be upgraded to newer versions, if available, or the functionality will need to be replaced in order for the process to execute as 64-bit.
Here are some excellent links on MSDN that should be required reading before migrating a complex project to 64-bit Windows:
Reference: http://blogs.msdn.com/b/joshwil/archive/2005/04/08/406567.aspx, http://visualstudiohacks.com/articles/visual-studio-net-platform-target-explained/