My application is built as a x64 application. After moving to VS2010 I got some problems which seems to be related to some x64/x86 mismatch in referenced dlls. Now I'm moving to target .NET4, and I get even more similar problems.
My question is: What precautions do I need to take regarding mixing x64 and x86. Can it be done at all? I thought x64 applications should be able to use x86 dlls without problems. No? What about the other way? Can a x86 application reference an x64 dll - as long as it is being run on an x64 platform? What are the pitfalls I need to be aware of?
No, a 64-bit process can only load 64-bit DLLs and a 32-bit process can only load 32-bit DLLs. What you're probably thinking of is that a 64-bit operating system can run 32-bit processes.
The main issue with .NET is that - prior to VS2010 - executable projects defaulted to "AnyCPU" which means it would load in the "native" format of the OS it's running on (so 32-bit for 32-bit versions of Windows and 64-bit for 64-bit versions of Windows). The problem with that is that if you tested your application on 32-bit Windows (say) then it could break if you load 32-bit DLLs and tried to run on 64-bit Windows.
In VS2010, they defaulted all executable projects to be "x86" (that is, 32-bit) by default which (for the most part) mitigates the problem.
You can run x86 apps on a 64 bit OS using WOW32 emulation. Some pitfalls that I have encountered - you can't mix and match 32/64 in the same process. So if you intend to run IIS as 64 all the assemblies need to be 64 otherwise you'll have to run In 32 bit mode. 64 bit helps some apps more than others. Running SQL sever's 64 bit version provides several advantages over the 32 bit version, biggest advantage being that yo can install more than 4 GB of memory on the target server and that SQL will be able to use more than 4 GB of memory. It does not benefit IIS as much because IIS typically can't use more than 3 gb of memory. My advice would be to make sure your SQL server/os/version are 64 if possible. It's not going to make a. Huge dfference if the other servers are 64 but typically it's easier to work with and find 32 bit versions.
Related
Supposing I have a windows app developed based on C#. I want to ensure that it works on 32 bit and 64 bit both. But I don't want to change the config settings or application settings time and again. Is there a way to test both variants?
There are a couple of options.
You can target AnyCPU. If you're program is 100% C#/managed code, with no native dependencies, this will cause it to run 64bit on 64bit Operating systems and 32bit on 32bit Operating systems.
Target x86. This will cause it to run 32bit everywhere, which works properly on 64bit Windows (via WOW64). This works properly if you're using native (32bit) libraries, as well.
Make two builds, and two separate deployments. This allows you to use native code and still run 64bit on 64bit operating systems, but is far more work.
Since 32bit applications run well on 64bit operating systems, there is rarely reason to run the program natively in 64bit. This is typically only really beneficial if you're processing large amounts of data and truly need access to larger memory space than you can get in 32bit processes. In .NET, this typically means you'll want to build 64bit if you're going to use more than 1.2-1.6gb of RAM for your program. Otherwise, 32bit will work fine everywhere.
If you target AnyCPU, most .NET programs will run unaltered on 32-bit or 64-bit machines. The code will be jitted to 32-bit or 64-bit code as appropriate for the target operating system.
The exception where you need to use care is when using interop to unmanaged code.
If you do interop to unmanaged code and require to run as 64-bit on a 64-bit platform, you will have to make two builds.
If you do interop to unmanaged code and can accept running as a 32-bit process, target x86. That avoids two builds, and will run your .NET code as a 32-bit process in 32-bit and 64-bit platforms.
I'm using Windows 7 and x64 cpu.
Does it mean that I should always compile with "x64" option in Visual Studio? What about "dll", can I use x86 dll from x64 application? Probably there are other concerns?
This article contains a brief overview of each option.
Here's a small quote:
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.
Generally speaking, you should use AnyCpu all the time.
If you have specific reasons to expect compatibility problems with that, then you'll need to choose x86 or x64 as appropriate.
As noted in the comments, dll's built against specific architectures can require you to build your assembly a certain way. This will be something you'll want to do when you need to, not otherwise.
No... the machine you write your code on/compile/build your software (EXE, DLL...) does not have anything to do with the question which target (x86 / x64 / Any).
IF you want the result of the build to run anywhere you use either x86 or AnyCPU. If you want the result to run on x64 only then you use x64.
There are some cases where you must use x86 or x64 - that is when you use some (3rd-party?) component/library/DLL/ActiveX etc. in your project which is 32 Bit only (then x86) or only 64 Bit only (then x64).
AnyCPU is what I generally recommend. You can see this issue discussed in depth at this SO post.
The only concern is that you cannot go backwards - you can't use an x64 assembly from a x86 application. AnyCPU alleviates this potential pitfall.
I have got a .net application,
Class library (Target Platform set to Any CPU)
Winform Application (Target platform set to Any CPU)
Installer (Target Platform set to X86 and Detected dependencies set for .net framework(x86))
Now when I install this application through setup.exe on a 64-bit machine, it is installed in the Program Files [x86] folder; I guess this is WoW64 feature of emulating 32-bit environment on a 64-bit application.
Now when a client asks to convert it to 64-bit, why does it matter to him if the 32-bit version itself works fine through WoW64? would converting it to 64 bit result in performance benefits?
And when I try to convert it to 64-bit, do I need to change it for all, ie ,
Class Library (change Target platform to 64) (What if I skip this step?)
Winform Application (change target platform to 64) (What if I skip this too?)
Installer (change target platform to 64) [Detected dependencies listing doesn't show any .NET framework x64 option, why?]
Please suggest.
No conversion is necessary, your app already runs as a 64-bit process. Because you used AnyCPU on the EXE project. You installed it to the wrong folder but that doesn't matter much if no other process tries to start yours programmatically. That's exceedingly rare.
Verify this from TaskMgr.exe, Processes tab. A 32-bit process has *32 after its process name.
Make your client happy by changing the Setup project's TargetPlatform setting to x64 so it gets installed in c:\program files. Takes you a few minutes.
You can leave the .NET code projects on AnyCPU, however to install onto 64-bit without hitting the 32-bit WOW stuff you need to change the installer project property that you mention.
If you have custom actions in the installer, these may not work when you change to 64-bit. You might get a BadImageFormatException. To resolve this, you need to faff with the resulting MSI:
http://adamhouldsworth.blogspot.com/2010/10/64bit-custom-actions.html
It won't make much of a difference to the client if your application is standalone. There is no free performance benefit, other than access to more RAM, when going to 64-bit (though the JIT has different types of optimisations available).
The only situation I've seen where 64-bit is required is when you consume that DLL in another application, you cannot mix bit-ness in a single process.
Update: perhaps the lack of a 64-bit framework prerequisite is because you are using VS 2005?
http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/7b00f4e9-64e3-4fb6-9906-880820ecda92
64 bit may or may not give performance differences. A 64 bit application can also utilize (way) more memory than a 32bit application.
If you launch an AnyCpu exe on a 64bit OS it should launch in 64bit (see in the task manager, 32bit processes are appended with *32 there). If you set the application to x64, the library must be either x64 or AnyCpu.
If you do not have native x64-only references you can leave your exe and dll as AnyCpu, but you will need to modify the setup to x64.
As for the framework, on an x64 machine (which is the only place an x64 app will run anyway), the framework always includes both 32 and 64 bit, found in C:\Windows\Microsoft.NET\Framework and Framework64 respectively.
Now when i install this application through setup.exe on a 64-bit machine, it is installed in the
Program Files [x86] folder; I guess this is WOW feature of emulating 32-bit environment on a 64-
bit application.
No, it has NOTHING to do with the program, only with the installer.
•Installer (Target Platform set to X86 and Detected dependencies set for .net framework(x86))
32 bit installer installes it in the 32 bit folder for programs, regarless whether the program is 32 or 64 bit.
Sadly you can not have one installer doing both - you need an installer for 32 and one for 64 bit in concept, by design.
This is totally a design decision on the MSI part and, again, has nothing to do with the program at all.
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.
In general, I think you should not have any problems with managed code.
Potential problems can come from unmanaged code. For example, because variable sizes are different in 32-bit and 64-bit systems, pointers are different, etc. For example, the size of the int variable in C/C++ depends on the system. As for managed code as already mentioned, WoW can handle that.
x64 managed code will use Streaming SIMD Extensions (SSE) for double/float computation instead of x87 Floating Point Unit (FPU) when using x86 managed code.
In addition to other answers, I would like to add one more thing: we can run software of 32-bit system on 64 but conversely is not possible!
I have the 32 bit compiled dll when I try to use it in 64 bit application it fails to load,
So I would like to convert the dll to 64 bit. Its working fine when the platform of the application changed from "Any CPU" or "x64" to "x86". But I want to use it under 64 bit, Since I am going to call the dll from ASP pages.
Please help me out with this.
Windows CAN NOT load a 32bit dll into a 64bit process - this is a limitation that you can not circumvent. This means that if your 32bit DLL does any P/Invokes to other 32bit DLLS (or uses any 32bit .Net DLLS) you will be entirely out of luck (you will need to run the entire website in 32bit).
You are not entirely clear on when it works and when it doesn't. Here are the explanations:
x86 - 32bit - Can not be loaded into a 64bit process.
x64 - 64bit - Can not be executed on a 32bit machine.
AnyCPU - dual - Can be loaded and executed in both environments.
In terms of AnyCPU:
64bit process on 64bit machine - DLL is loaded as 64bit.
32bit process on 32bit machine - DLL is loaded as 32bit.
32bit process on 64bit machine - DLL is loaded as 32bit.
In most cases it's fine to leave it as AnyCPU. However, as I said, if you are using any native or .Net 32bit DLLs you will need to make your entire application 32bit (and there is nothing you can, or Microsoft could, do about this).
x86 flag is usually set for a reason, so it may be bad idea to change it. But if you are absolutely sure, there's an utility, corflags.exe. I have it under C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin. Of course it will help with .net assemblies only.
If you want to load a pure C# DLL in both a 32 and 64 bit process, then the correct choice is AnyCPU. This will compile it the DLL as CPU agnostic and it will be loadable into either type of process.
I'm not 100% sure that's what you're asking though. If it's not can you clarify your question?
you can take a look at http://msdn.microsoft.com/en-us/library/ms164699%28VS.80%29.aspx