我有使用DLLImport导入的外部c ++ dll。如果我的应用程序在x64中编译,则需要导入该dll的x64版本,如果它是x86构建,则需要x86 dll。
实现此目标的最佳方法是什么?
理想情况下,我想要一些预处理器指令,但是我知道这在c#中不起作用?
更多信息:DLL由设置为AnyCPU的项目导入。父项目是确定应用程序编译为x64还是x86的项目。我们为不同的客户编译这两个版本- 我想在两个版本中共享子项目。
这主要是一个部署问题,只需让您的安装程序根据目标计算机上的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位版本。