首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在C# DllImport中使用32位或64位动态链接库

在C# DllImport中使用32位或64位动态链接库
EN

Stack Overflow用户
提问于 2012-06-01 22:56:22
回答 4查看 57.5K关注 0票数 69

情况是这样的,我在dot.net应用程序中使用了一个基于C的动态链接库。有两个dll,一个是称为MyDll32.dll的32位版本,另一个是称为MyDll64.dll的64位版本。

有一个静态变量保存着DLL文件名: string DLL_FILE_NAME。

它的用法如下:

代码语言:javascript
复制
[DllImport(DLL_FILE_NAME, CallingConvention=CallingConvention.Cdecl, EntryPoint=Func1")]
private static extern int is_Func1(int var1, int var2);

到目前为止很简单。

可以想象,该软件是在“任意CPU”打开的情况下编译的。

我还有以下代码来确定系统应该使用64位文件还是32位文件。

代码语言:javascript
复制
#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之前,如何设置它?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-06-01 23:08:29

我发现最简单的方法是导入两个具有不同名称的方法,并调用正确的方法。DLL只有在调用完成后才会被加载,所以这样做没问题:

代码语言:javascript
复制
[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);
}

当然,如果您有许多导入,手动维护可能会变得相当麻烦。

票数 66
EN

Stack Overflow用户

发布于 2015-06-29 20:24:34

在本例中,我应该这样做(创建两个文件夹,x64和x86 +将具有相同名称的相应dll放入这两个文件夹中):

代码语言:javascript
复制
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);
}
票数 17
EN

Stack Overflow用户

发布于 2015-07-01 22:20:56

另一种方法可能是

代码语言:javascript
复制
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);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10852634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档