Click here to Skip to main content
15,881,281 members
Articles / Programming Languages / C#
Tip/Trick

.NET Interop with 32 and 64-bit DLLs

Rate me:
Please Sign up or sign in to vote.
4.28/5 (16 votes)
11 Dec 2014CPOL1 min read 57.1K   20   20
A novel solution to the 32 vs 64-bit DLL interop problem

Introduction

This is maybe a novel solution to the 64 vs 32-bit DLL problem when doing P/Invoke (aka DllImport) in .NET.

Background

When building a .NET assembly for the "AnyCPU" target, you don't know until run-time if it will be running in a 64-bit or 32-bit process. If the assembly calls on a native DLL that is also distributed with the assembly, then you must install the correct native DLL -- 32-bit or 64-bit. This creates headaches, requiring either multiple install packages or other work to ensure the proper DLL gets installed.

One solution is to target x86 for the .NET assembly and distribute it with a 32-bit native DLL. But that wastes performance on 64-bit machines.

Using the Code

Here's a solution which allows you to distribute a single install package and still get the correct DLL to run with the .NET assembly.

First, there is a .NET interface defined which will permit access to the native DLL functions. For example:

C#
public interface xyz { int Add(int a, int b); }

Now, build two versions of the native DLL with different names, for example, "Native-x86.dll" and "Native-x64.dll".

Next, define two implementations for the interface; one uses DllImport on the 32-bit DLL and the other one uses the 64-bit DLL.

C#
public xyz_x86 : xyz
{
    private const string DLL_Filename = "Native-x86.dll";
    
    [DLLImport(DLL_Filename)] private static extern int NativeAdd(int a, int b);
    public int Add(int a, int b) { return NativeAdd(a,b); }
}

Now just make an exact copy of this class and change the DLL_Filename:

C#
public xyz_x64 : xyz
{
    private const string DLL_Filename = "Native-x64.dll";
    
    [DLLImport(DLL_Filename)] private static extern int NativeAdd(int a, int b);
    public int Add(int a, int b) { return NativeAdd(a,b); }
}

At runtime, it is now just a matter of choosing the implementation that does not throw an exception:

C#
static void Main()
{
    xyz MyAdder = new xyz_x86();
    try { int junk = MyAdder.Add(1,2); } catch { MyAdder = new xyz_x64(); }
    // Now MyAdder is connected to a working DLL!
}

Now, there is only one install package and it installs both x86 and x64 DLLs... one of them won't work but that's okay now.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionAlternative solution Pin
Vahid_N17-Dec-14 0:08
Vahid_N17-Dec-14 0:08 
GeneralMy vote of 2 Pin
dandingus12-Dec-14 12:01
dandingus12-Dec-14 12:01 
GeneralRe: My vote of 2 Pin
Member 10284041 VJ14-Dec-14 21:38
professionalMember 10284041 VJ14-Dec-14 21:38 
GeneralRe: My vote of 2 Pin
dandingus15-Dec-14 4:30
dandingus15-Dec-14 4:30 
GeneralRe: My vote of 2 Pin
Kiriander16-Dec-14 22:01
Kiriander16-Dec-14 22:01 
GeneralRe: My vote of 2 Pin
Zzzzzoltan19-Dec-14 12:08
Zzzzzoltan19-Dec-14 12:08 
GeneralMy vote of 2 Pin
Thandermax12-Dec-14 6:55
Thandermax12-Dec-14 6:55 
GeneralMy vote of 1 Pin
Richard James Moss12-Dec-14 4:33
professionalRichard James Moss12-Dec-14 4:33 
GeneralMy vote of 1 Pin
GerVenson12-Dec-14 2:29
professionalGerVenson12-Dec-14 2:29 
I was a bit disappointed after i expected much more from the Article ... I expected a more deeper look into a solution for this problem then the usage of an Interface ( Strategy Pattern ) ... i would like to agree with the previews Comment an would say this is too basic. Anyway i thing that the Try-And-Error mehtod that you are describing, is not longer state of the art in modern programming. Keep in mind that an Exception represents an "Unexpected" error! This is expected and you could resolve the error Optimistically by simply Check the Assembly to be exists instead of just throw an error.
GeneralMy vote of 3 Pin
wpte12-Dec-14 2:00
wpte12-Dec-14 2:00 
GeneralMy vote of 5 Pin
Klaus Luedenscheidt11-Dec-14 19:26
Klaus Luedenscheidt11-Dec-14 19:26 
SuggestionSuggesstion for Improvement PinPopular
FIorian Schneidereit11-Dec-14 19:01
FIorian Schneidereit11-Dec-14 19:01 
GeneralRe: Suggesstion for Improvement Pin
du57in17-Dec-14 4:57
du57in17-Dec-14 4:57 
GeneralRe: Suggesstion for Improvement Pin
Zzzzzoltan19-Dec-14 12:11
Zzzzzoltan19-Dec-14 12:11 
GeneralMy vote of 1 Pin
Youzelin11-Dec-14 18:35
Youzelin11-Dec-14 18:35 
GeneralRe: My vote of 1 Pin
Garth J Lancaster11-Dec-14 19:43
professionalGarth J Lancaster11-Dec-14 19:43 
GeneralRe: My vote of 1 Pin
Member 250108311-Dec-14 22:37
Member 250108311-Dec-14 22:37 
GeneralRe: My vote of 1 Pin
Garth J Lancaster11-Dec-14 22:51
professionalGarth J Lancaster11-Dec-14 22:51 
GeneralRe: My vote of 1 Pin
Youzelin17-Dec-14 19:58
Youzelin17-Dec-14 19:58 
GeneralRe: My vote of 1 Pin
Zzzzzoltan19-Dec-14 12:14
Zzzzzoltan19-Dec-14 12:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.