根据x64 / x86更改C#DllImport目标代码
可能重复:
预处理器指令C#
我有一个外部的c + + dll导入使用DLLImport。 如果我的应用程序正在x64编译我需要导入此dll的x64版本,如果它是x86版本,我需要x86 dll。
达到这个目标的最好方法是什么?
理想情况下,我想要一些预处理指令,但我知道这不适用于C#?
更多信息:该DLL正在被设置为AnyCPU的项目导入。 父项目是确定应用程序编译为x64还是x86的项目。 我们为不同的客户编译两个版本 – 我想在两个版本中共享子项目。
这主要是一个部署问题,只需要您的安装程序根据目标机器上的Windows版本复制正确的DLL即可。
但没有人喜欢这样做。 dynamic地禁止正确的DLL函数是非常痛苦的,你必须为每个导出的函数编写委托types,并使用LoadLibrary + GetProcAddress + Marshal.GetDelegateForFunctionPointer来创build委托对象。
但没有人喜欢这样做。 不太痛苦的做法是声明两次函数,赋予不同的名称,并使用[DllImport]属性中的EntryPoint属性指定实名。 然后在运行时testing你想要调用的。
但没有人喜欢这样做。 最有效的技巧是引导Windows为您加载正确的DLL。 首先你要做的就是将DLL复制到一个Windows不能查找的目录中。 最好的方法是在build目录中创build一个“x86”和“x64”子目录,并将相应的DLL复制到每个目录中。 通过编写创build目录的后构build事件并复制这些DLL来完成此操作。
然后通过禁止SetDllDirectory()告诉Windows。 您指定的path将被添加到WindowssearchDLL的目录中。 喜欢这个:
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位版本。
使用不同的名称添加x86和x86_64 DLL导入,然后可以通过检查Environment.Is64BitProcess(或如果使用<.Net 4)的IntPtr.size的值,在运行时根据体系结构有条件地调用它们。 无论项目是构build为x86,x86_64还是AnyCPU,这都可以工作
或者,设置2个不同的构buildconfiguration – 一个只做x86,一个只做x86_64,为每个构build一个条件编译符号,并在你的自定义符号上使用#ifdef。