What are the differences between 32 and 64-bit .NET (4) applications?
Often 32-bit applications have problems running on 64-bit machines and conversely. I know I can declare an integer as int32 and int64 (certainly int64 on 32-bit systems make problems). Are there other differences between programming an 32 OR 64-bit or a both 32 AND 64-bit compatible application?
Some differences:
32-bit and 64-bit applications can only load DLLs of the same bitness. This can be an issue for managed projects if your platform target is "Any CPU" and you reference or P/Invoke 32-bit native DLLs. The issue arises when your "Any CPU" program runs on a 64-bit machine, since your application runs as a 64-bit process. When it tries to load the 32-bit native DLL dependency, it will throw an exception (BadImageFormatException
) and likely crash.
There are also filesystem and registry issues. A WOW64 process that tries to read from C:\Program Files
will end up getting redirected to C:\Program Files (x86)
unless it first disables Windows filesystem redirection (see Wow64DisableWow64FsRedirection
). For versions of Windows before Windows 7, there were also registry reflection issues that were similar to the filesystem redirection issues mentioned above. The MSDN article Registry Reflection explains it well.
Platform-specific types like IntPtr
will have different sizes. This could be an issue in code that assumes a fixed size (serialization, marshaling).
There are separate physical directories for the 32- and 64-bit files in the GAC. For my system, they are at C:\Windows\Microsoft.NET\assembly\GAC_32
and C:\Windows\Microsoft.NET\assembly\GAC_64
.
The virtual address space size of 32- and 64-bit applications is different. For 32-bit applications, the size is either 2 GB (default) or 3 GB (with 4GT enabled). For 64-bit applications, the size is 8 TB. The 32-bit address space can be a limitation for very large applications.
A little more obscure, but a lot of interprocess Win32 calls won't work between a 32- and 64-bit process. For example, a 32-bit process can fail when trying to call ReadProcessMemory
on a 64-bit process. The same goes for WriteProcessMemory
, EnumProcessModules
, and a lot of similar methods. This can be seen in C# applications if you try to enumerate the modules of a 64-bit application from a 32-bit application using the System.Diagnostics.Process.Modules
API.