情况是这样的,我在dot.net应用程序中使用了一个基于C的动态链接库。有两个dll,一个是称为MyDll32.dll的32位版本,另一个是称为MyDll64.dll的64位版本。
有一个静态变量保存着DLL文件名: string DLL_FILE_NAME。
它的用法如下:
[DllImport(DLL_FILE_NAME, CallingConvention=CallingConvention.Cdecl, EntryPoint=Func1")]
private static extern int is_Func1(int var1, int var2);
到目前为止很简单。
可以想象,该软件是在“任意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之前,如何设置它?
发布于 2012-06-01 23:08:29
我发现最简单的方法是导入两个具有不同名称的方法,并调用正确的方法。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);
}
当然,如果您有许多导入,手动维护可能会变得相当麻烦。
发布于 2015-06-29 20:24:34
在本例中,我应该这样做(创建两个文件夹,x64和x86 +将具有相同名称的相应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();
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetDllDirectory(string path);
}
发布于 2015-07-01 22:20:56
另一种方法可能是
public static class Sample
{
public Sample()
{
string StartupDirEndingWithSlash = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) + "\\";
string ResolvedDomainTimeFileName = StartupDirEndingWithSlash + "ABCLib_Resolved.dll";
if (!File.Exists(ResolvedDomainTimeFileName))
{
if (Environment.Is64BitProcess)
{
if (File.Exists(StartupDirEndingWithSlash + "ABCLib_64.dll"))
File.Copy(StartupDirEndingWithSlash + "ABCLib_64.dll", ResolvedDomainTimeFileName);
}
else
{
if (File.Exists(StartupDirEndingWithSlash + "ABCLib_32.dll"))
File.Copy(StartupDirEndingWithSlash + "ABCLib_32.dll", ResolvedDomainTimeFileName);
}
}
}
[DllImport("ABCLib__Resolved.dll")]
private static extern bool SomeFunctionName(ref int FT);
}
https://stackoverflow.com/questions/10852634
复制相似问题