views:

965

answers:

4

Hi,

we use a self-written 32bit C++ DLL from our C# applications. Now we've noticed that when the C# applications are run on a 64bit system, the 64bit runtime is automatically used and of course the 32bit DLL can not be accessed from the 64bit runtime.

My question is: is there a way of using the 32bit DLL? If not, if I created a 64bit version of the DLL, would it be easily possible to let the application choose which one to P/Invoke to?

I'm thinking of creating two helper classes in C#: One that imports the functions from the 32bit DLL and one that imports from the 64bit DLL, then creating a wrapper class with one function for each imported function that calls either the 32bit importer or the 64bit importer depending on the "bittyness" of the OS. Would that work?

Or is there another easy way to do things?

+1  A: 

You can flag the .Net app to only target x86 architecture

Rowland Shaw
Yes, that works, we've tried, but of course I want the application to run in 64bit mode when on 64bit systems.
Thorsten Dittmar
If you want it to run in 64 bit mode, then you need all the libraries that it imports to also be 64 bit - you could then wrap these in a static class and handle the logic as to which to call at runtime
Rowland Shaw
So basically you're saying that what I suggested in my question is the way to go?
Thorsten Dittmar
Well, you cannot mix x86 and x64 in a single process, so you either need to go x86 only, or the magic wrapper that you'd already considered.
Rowland Shaw
OK, thanks. I'll consider your answer as the solution as the comment gave me the right idea.
Thorsten Dittmar
A: 

I had similar problem but it was with Unrar.dll being either 32 or 64bit.

There can be two approaches to make it work:

a)

#if x64
// ... define all x64 imports here
#else
// ... define all x86 imports here
#endif

And compile application for 32Bit and 64bit.

b) Another way was to create an interface for the imports and implement 32 bit and 64 bits versions separately.

If 32 bit, instantiate the 32 bit implementation, else instantiate the 64 bit implementation.

MadBoy
Yes, we could do that, but of course it would be nicer to not have to think of compiling for both platforms all the time...
Thorsten Dittmar
+1  A: 

You need to make sure that you're only using P/Invoke calls against a 64bit DLL when compiling in 64bit.

One option is to move all of your "methods" into a standard interface (or abstract base class), and provide 2 implementations, one 32bit and one 64bit. You can have a factory method construct the appropriate instance of the class depending on the size of IntPtr.

This allows an "AnyCPU" app to correctly, at runtime, determine which DLL to P/Invoke into, and does work.

Reed Copsey
A: 

Create a helper class that wraps both 64bit and 32bit DLLS, and use IntPtr.Size to determine which to call.

if (IntPtr.Size == 8)
{
    Helper.SomeMethod64();
}
else
{
    Helper.SomeMethod32();
}
Chris Almond