根据在x64 / x86的变动c#的DllImport目标代码(Change C# DllImpor

2019-06-17 17:46发布

我有一个外部的C ++ DLL使用的DllImport导入。 如果我的应用程序在编译的x64我需要导入这个dll的x64版本,如果它是一个x86版本,我需要的DLL的x86。

什么是实现这一目标的最佳途径?

理想情况下,我想一些预处理指令,但我知道这并不在C#中工作?

更多信息:该DLL正在被设置为AnyCPU项目进口。 父项目是确定应用程序是否编译为64或86之一。 我们编制两个版本针对不同的客户 - 我想分享两个版本中的子项目。

Answer 1:

这主要是部署问题,只要有你的安装程序复制根据目标机器上的Windows版本的权利DLL。

但是,从来没有人喜欢这样做。 动态pinvoking正确的DLL的功能是极大痛苦,你必须写的委托类型为每个导出功能和使用的LoadLibrary + GetProcAddress的+ Marshal.GetDelegateForFunctionPointer创建委托对象。

但是,从来没有人喜欢这样做。 在痛苦少粘性是声明函数的两倍,赋予其不同的名称和使用的函数[DllImport]属性的入口点属性来指定真实姓名。 然后,在这你要调用运行测试。

但是,从来没有人喜欢这样做。 最有效的一招是引导的Windows加载到正确的DLL为您服务。 你要做的第一件事是DLL复制到一个目录,Windows无法找到它。 最好的方法是创建一个“86”,并在您的构建目录中的“64”的子目录和相应的DLL复制到每个。 通过编写创建目录和副本的DLL文件生成后事件做到这一点。

然后通过pinvoking 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位模式下运行的代码实际上是对你有用。 这是很罕见的需要你从中获得巨大的虚拟内存地址空间,唯一的真正的好处。 你仍然需要支持,需要在2G的情况下正常运行32位版本。



Answer 2:

同时添加的x86和x86_64的该进口的DLL名称不同,那么你可以有条件地调用它们依赖于架构在运行时通过检查Environment.Is64BitProcess的值(或IntPtr.size如果你使用<.NET 4.0)。 不管这将工作的项目是否被构建为X86,x86_64的或AnyCPU

另外,设置了2个不同的生成配置 - 一个只做x86和一个只做x86_64的,给每一个条件编译符号和您的自定义符号使用#ifdef来。



文章来源: Change C# DllImport target code depending on x64/x86