在C#DllImport中使用32位或64位DLL

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (43)

这是情况,我在我的dot.net应用程序中使用基于C的dll。有2个DLL,一个是32位的叫MyDll32.dll,另一个是64位的叫MyDll64.dll的版本。

有一个静态变量包含DLL文件名:字符串DLL_FILE_NAME。

并以如下方式使用它:

[DllImport(DLL_FILE_NAME, CallingConvention=CallingConvention.Cdecl, EntryPoint=Func1")]
private static extern int is_Func1(int var1, int var2);

迄今为止很简单。

正如你可以想象的那样,该软件是在“Any CPU”打开的情况下编译的。

我还有以下代码来确定系统是否应该使用64位文件或32位文件。

#if WIN64
        public const string DLL_FILE_NAME = "MyDll64.dll";
#else
        public const string DLL_FILE_NAME = "MyDll32.dll";        
#endif

现在你应该看到问题了.DLL_FILE_NAME是在编译时定义的,而不是在执行时间,所以根据执行上下文没有加载正确的dll。

什么才是解决这个问题的正确方法?我不想要两个执行文件(一个用于32位,另一个用于64位)?如何在DllImport语句中使用DLL_FILE_NAME 之前设置它?

提问于
用户回答回答于

我发现最简单的方法是使用不同的名称导入两个方法,并调用正确的方法。在调用完成之前,DLL不会被加载:

[DllImport("MyDll32.dll", EntryPoint = "Func1", CallingConvention = CallingConvention.Cdecl)]
private static extern int Func1_32(int var1, int var2);

[DllImport("MyDll64.dll", EntryPoint = "Func1", CallingConvention = CallingConvention.Cdecl)]
private static extern int Func1_64(int var1, int var2);

public static int Func1(int var1, int var2) {
    return IntPtr.Size == 8 /* 64bit */ ? Func1_64(var1, var2) : Func1_32(var1, var2);
}
用户回答回答于

这是另一种替代方法,它要求两个DLL具有相同的名称并放置在不同的文件夹中。例如:

  • win32/MyDll.dll
  • win64/MyDll.dll

诀窍是LoadLibrary在CLR执行之前手动加载DLL 。它会看到MyDll.dll已经被加载并使用它。

这可以在父类的静态构造函数中轻松完成。

static class MyDll
{
    static MyDll()
    {            
        var myPath = new Uri(typeof(MyDll).Assembly.CodeBase).LocalPath;
        var myFolder = Path.GetDirectoryName(myPath);

        var is64 = IntPtr.Size == 8;
        var subfolder = is64 ? "\\win64\\" : "\\win32\\";

        LoadLibrary(myFolder + subfolder + "MyDll.dll");
    }

    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibrary(string dllToLoad);

    [DllImport("MyDll.dll")]
    public static extern int MyFunction(int var1, int var2);
}

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励