Setting dllimport programmatically in C#

Matt picture Matt · Aug 24, 2009 · Viewed 14.9k times · Source

I am using DllImport in my solution.
My problem is that I have two versions of the same DLL one built for 32 bit and another for 64 bit.

They both expose the same functions with identical names and identical signatures. My problem is that I have to use two static methods which expose these and then at run time use IntPtr size to determine the correct one to invoke.

private static class Ccf_32
{
    [DllImport(myDllName32)]
    public static extern int func1();
}

private static class Ccf_64
{
    [DllImport(myDllName64)]
    public static extern int func1();
}

I have to do this because myDllName32 and myDllName64 must be constant and I have not found a way to set it at run time.

Does anyone have an elegant solution for this so I could get rid of the code duplication and the constant IntPtr size checking.

If I could set the file name, I would only have to check once and I could get rid of a ton of repeated code.

Answer

Josh Sklare picture Josh Sklare · Dec 13, 2009

I prefer to do this by using the LoadLibrary call from kernel32.dll to force a particular DLL to load from a specific path.

If you name your 32-bit and 64-bit DLLs the same but placed them in different paths, you could then use the following code to load the correct based on the version of Windows you are running. All you need to do is call ExampleDllLoader.LoadDll() BEFORE any code referencing the ccf class is referenced:

private static class ccf
{
    [DllImport("myDllName")]
    public static extern int func1();
}

public static class ExampleDllLoader
{
    [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
    private extern static IntPtr LoadLibrary(string librayName);

    public static void LoadDll()
    {
        String path;

        //IntPtr.Size will be 4 in 32-bit processes, 8 in 64-bit processes 
        if (IntPtr.Size == 4)
            path = "c:/example32bitpath/myDllName.dll";
        else
            path = "c:/example64bitpath/myDllName.dll";

        LoadLibrary(path);
    }
}