小编典典

根据x64 / x86更改C#DllImport目标代码

c#

我有使用DLLImport导入的外部c ++ dll。如果我的应用程序在x64中编译,则需要导入该dll的x64版本,如果它是x86构建,则需要x86
dll。

实现此目标的最佳方法是什么?

理想情况下,我想要一些预处理器指令,但是我知道这在c#中不起作用?

更多信息:DLL由设置为AnyCPU的项目导入。父项目是确定应用程序编译为x64还是x86的项目。我们为不同的客户编译这两个版本-
我想在两个版本中共享子项目。


阅读 629

收藏
2020-05-19

共1个答案

小编典典

这主要是一个部署问题,只需让您的安装程序根据目标计算机上的Windows版本复制正确的DLL。

但是没有人喜欢这样做。动态调用正确的DLL函数非常痛苦,您必须为每个导出的函数编写委托类型,并使用LoadLibrary + GetProcAddress
+ Marshal.GetDelegateForFunctionPointer创建委托对象。

但是没有人喜欢这样做。比较轻松的方法是对函数进行两次声明,为其指定不同的名称,并使用[DllImport]属性中的EntryPoint属性指定真实名称。然后在要调用的运行时进行测试。

但是没有人喜欢这样做。最有效的技巧是引导Windows为您加载正确的DLL。您要做的第一件事是将DLL复制到Windows不会查找的目录中。最好的方法是在构建目录中创建一个“
x86”和“ x64”子目录,并将适当的DLL复制到每个目录中。为此,可以编写一个构建后事件来创建目录并复制DLL。

然后通过点按SetDllDirectory()告诉Windows。您指定的路径将被添加到Windows搜索DLL的目录中。像这样:

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

class Program {
    static void Main(string[] args) {
        var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        path = Path.Combine(path, IntPtr.Size == 8 ? "x64" : "x86");
        bool ok = SetDllDirectory(path);
        if (!ok) throw new System.ComponentModel.Win32Exception();
        //etc..
    }
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool SetDllDirectory(string path);
}

请考虑让代码在64位模式下运行实际上是否对您有用。唯一需要真正好处的是,很少需要从中获得的巨大虚拟内存地址空间。您仍然需要支持需要在2
GB情况下正确运行的32位版本。

2020-05-19