Setting dllimport programmatically in C#

后端 未结 9 1910
情话喂你
情话喂你 2020-12-30 11:10

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 e

相关标签:
9条回答
  • 2020-12-30 11:35

    I know this is a really old question (I'm new - is it bad to answer an old question?), but I just had to solve this same problem. I had to dynamically reference a 32-bit or 64-bit DLL based on OS, while my .EXE is compiled for Any CPU.

    You can use DLLImport, and you don't need to use LoadLibrary().

    I did this by using SetDLLDirectory. Contrary to the name, SetDLLDirectory adds to the DLL search path, and does not replace the entire path. This allowed me to have a DLL with the same name ("TestDLL.dll" for this discussion) in Win32 and Win64 sub-directories, and called appropriately.

    public partial class frmTest : Form
    {
        static bool Win32 = Marshal.SizeOf(typeof(IntPtr)) == 4;
        private string DLLPath = Win32 ? @"\Win32" : @"\Win64";
    
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool SetDllDirectory(string lpPathName);
        [DllImport("TestDLL.dll", SetLastError = true)]
        static extern IntPtr CreateTestWindow();
    
        private void btnTest_Click(object sender, EventArgs e)
        {
            string dllDir = String.Concat(Directory.GetCurrentDirectory(), DLLPath);
            SetDllDirectory(dllDir);
    
            IntPtr newWindow = CreateTestWindow();
        }
    }
    
    0 讨论(0)
  • 2020-12-30 11:41

    You can't do this the way you want. You need to think of the DllImport attribute as metadata that is used at compile time. As a result you can't change the DLL it is importing dynamically.

    If you want to keep your managed code targeted to "Any CPU" then you either need to import both the 32-bit and 64-bit libraries wrapped as two different functions that you can call depending on the runtime environment or use some additional Win32 API calls to late-load the correct version of the unmanaged assembly at runtime and additional Win32 calls to execute the required methods. The drawback there is that you won't have compile time support for any of that type of code for type safety, etc.

    0 讨论(0)
  • 2020-12-30 11:42

    You can determine whether you are running 64Bits or not by checking the size of the IntPtr type (which is called native int anyways). Then you can load the approriate DLL using an imported LoadLibraryW call, get the function pointer using GetProcAddress, and then, check out Marshal.GetDelegateForFunctionPointer

    This not nearly as complicated as it might look like. You have to DllImport both LoadLibraryW and GetProcAddress.

    0 讨论(0)
提交回复
热议问题