You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行时动态选择DllImport的加载路径以适配32/64位不同DLL

最优实现方案(代码改动量极小,无需修改原有P/Invoke声明)

该方案完全适配你需要最小化代码改动、方便合并上游更新的需求,原有项目中所有的[DllImport]声明、外部方法调用逻辑不需要做任何修改,仅需在程序入口处添加少量初始化代码即可:

步骤1:整理原生DLL文件

将32位DLL重命名为你原DllImport中NativeLibraryName对应的文件名(比如你原代码定义为const string NativeLibraryName = "MyNative.dll",就统一命名为MyNative.dll),放在程序根目录的x86子文件夹中;64位DLL同样命名为MyNative.dll,放在程序根目录的x64子文件夹中。

步骤2:添加启动时动态设置DLL搜索路径逻辑

在程序入口方法(比如Program.Main)的最开头添加以下代码:

using System;
using System.IO;
using System.Runtime.InteropServices;

// 导入Windows系统DLL搜索路径配置API,跨平台场景可对应替换为系统对应接口
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool SetDllDirectory(string lpPathName);

static void Main(string[] args)
{
    // 执行原有逻辑前先配置正确的DLL搜索路径
    string archDirectory = Environment.Is64BitProcess ? "x64" : "x86";
    string dllSearchPath = Path.Combine(AppContext.BaseDirectory, archDirectory);
    SetDllDirectory(dllSearchPath);

    // 原有业务逻辑完全保留,无需改动
    // ...
}

.NET Core 3.0/.NET 5+ 专属优化方案

如果你使用的是高版本.NET runtime,还可以用原生提供的DllImport解析器实现,连目录分层都不需要,两个不同位数的DLL可以直接放在程序根目录用不同名称命名,同样不需要修改原有P/Invoke声明:

using System.Reflection;
using System.Runtime.InteropServices;

static void Main(string[] args)
{
    // 注册自定义DLL导入解析逻辑
    NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), (libraryName, assembly, searchPath) =>
    {
        // 仅处理目标原生库的解析,其他库走默认逻辑
        if (libraryName == NativeLibraryName)
        {
            string realDllName = Environment.Is64BitProcess ? "MyNative_x64.dll" : "MyNative_x86.dll";
            return NativeLibrary.Load(Path.Combine(AppContext.BaseDirectory, realDllName));
        }
        return IntPtr.Zero;
    });

    // 原有业务逻辑完全保留
    // ...
}

以上两种方案的所有新增代码都集中在程序入口位置,和原有业务代码、P/Invoke声明完全隔离,后续合并上游项目更新时不会产生任何冲突。

内容的提问来源于stack exchange,提问作者GameDevAlien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:54:07