tags:

views:

372

answers:

2

I have an existing C# application written for .NET 2.0 and targetting AnyCPU at the moment. It currently references some third party .NET DLLs which I don't have the source for (and I'm not sure if they were built for x86, x64 or AnyCPU).

If I want to run my application specifically on a 64 bit Windows OS, which platform should I target in order for my app to run without errors? My understanding at the moment is to target:

  • x86: If at least one third party .NET dll is built for x86 or use p/Invoke to interface with Win32 DLLs. Application will run in 32 bit mode on both 32 bit and 64 bit OSes.
  • x64: If all third party .NET dlls are already built for x64 or AnyCPU. Application will only run in 64 bit OSes.
  • AnyCPU: If all third party .NET dlls are already built for AnyCPU. Application will run in 32 bit mode on 32 bit OSes and 64 bit on 64 bit OSes.

Also, am I right to believe that while targetting AnyCPU will generate no errors when building a application referencing third party x86 .NET DLLs, the application will throw a runtime exception when it tries to load these DLLs when it runs on a 64 bit OS.

Hence, as long as one of my third party DLLs is doing p/Invoke or are x86, I can only target x86 for this application?

+2  A: 

You can do P/Invoke from an AnyCPU DLL, you just need to be a bit more careful about the P/Invoke definitions (i.e. that you're not inadvertently assuming 32-bit or something). The problem is that it's kind of hard to know if a 3rd party DLL is doing the right thing without Reflector and disassembling it (unless the developer specifically states 64-bit support of course).

But other than that, you're pretty much spot-on.

To be honest, for 99% of applications, targetting x86 is perfectly acceptable. It's a relatively small number of applications that actually benefit from being 64-bit. (Performance issues typically come out as a bit of a wash: more registers are offset by the register renaming of x86 mode and larger data structures because pointers are twice as big [and in a reference-heavy system like .NET that's even worse])

Dean Harding
+1  A: 

I was curious as to this specific part of your question.

Also, am I right to believe that while targetting AnyCPU will generate no errors when building a application referencing third party x86 .NET DLLs, the application will throw a runtime exception when it tries to load these DLLs when it runs on a 64 bit OS.

So I tried it out. I created a DLL project ClassLibrary1 that targeted x86, then added a ConsoleApplication1 that targeted AnyCPU and referenced the other project. I made sure to actually use a class from the ClassLibrary1 project in the Main method.

Visual Studio gave me no warnings or complaints about referencing or building the application. When I ran the application (on a 64 bit OS) and the ClassLibrary1 assembly was loaded, I was greeted with a BadImageFormatException.

If I changed ConsoleApplication1 to target x64, I get compiler warnings but the compilation succeeds and the same exception occurs at runtime.

So to answer your question, yes you could very well run into trouble if your referenced assemblies (or any assemblies loaded at runtime for that matter) are not also compiled for AnyCPU. If you are unsure, and you don't need the additional address space, I'd stick to targeting x86. If you are sure your dependencies are compiled for AnyCPU, then you can target AnyCPU if you'd like but be sure to do plenty of testing in both processor architectures.

Josh Einstein
AnyCPU is the default targetted platform for my VS instance, which is plainly alright when you have no other dependencies other than the .NET framework. Once other dependencies are introduced, the assumption that the app will continue to work on 64 bit platforms simply because the application is targetted for AnyCPU and compiles without problems is going to be a painful one. Thanks for answering :)
Mr Roys