Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import external dll based on 64bit or 32bit OS

I have a dll that comes in both 32bit and 64bit version. My .NET WinForm is configured for "Any CPU" and my boss will not let us have separate installs for the different OS versions. So I am wondering: if I package both dlls in the install, then is there a way to have the WinForm determine if its 64bit/32bit and load the proper dll.

I found this article for determining version. But i am not sure how to inject the proper way to define the DLLImport attribute on the methods i wish to use. Any ideas?

like image 917
Mike_G Avatar asked Apr 07 '10 15:04

Mike_G


People also ask

Can a 64-bit DLL call a 32-bit DLL?

On 64-bit Windows, a 64-bit process cannot load a 32-bit dynamic-link library (DLL).

How can I run a 32-bit DLL on a 64-bit machine?

The recommended solution is to recompile the DLL from the source code for a 32-bit target architecture. Alternatively, you can load the DLL in a 64-bit LabVIEW VI or EXE and communicate between 64-bit LabVIEW and 32-bit LabVIEW using Shared Variables or other networking technologies.

Can 64-bit python load 32-bit DLL?

64-bit EXEs cannot load 32-bit DLLs. (And vice versa: 32-bit EXEs cannot load 64-bit DLLs.)


2 Answers

You could take advantage of the SetDllDirectory API function, it alters the search path for unmanaged assemblies. Store your 32-bit DLLs in the x86 subdirectory of the app install directory, the 64-bit DLLs in the x64 subdirectory.

Run this code at app startup before you do any P/Invoke:

using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
...

    public static void SetUnmanagedDllDirectory() {
        string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        path = Path.Combine(path, IntPtr.Size == 8 ? "x64 " : "x86");
        if (!SetDllDirectory(path)) throw new System.ComponentModel.Win32Exception();
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool SetDllDirectory(string path);
like image 63
Hans Passant Avatar answered Sep 23 '22 20:09

Hans Passant


Can you import them both and make the decision about which one to call via .NET instead?

For example:

[DllImport("32bit.dll", CharSet = CharSet.Unicode, EntryPoint="CallMe")]
public static extern int CallMe32 (IntPtr hWnd, String text, String caption, uint type);

[DllImport("64bit.dll", CharSet = CharSet.Unicode, EntryPoint="CallMe")]
public static extern int CallMe64 (IntPtr hWnd, String text, String caption, uint type);
like image 33
Kieron Avatar answered Sep 22 '22 20:09

Kieron