V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jim9606
V2EX  ›  C#

.NET 应用加载特定架构 DLL 的正确姿势

  •  
  •   jim9606 · 2021-12-30 02:31:48 +08:00 · 2251 次点击
    这是一个创建于 1057 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在改一个 .NET Framework 4.6.2 的项目,依赖一个非 C#的组件,这个组件只提供 x86 和 x64 的 DLL 。 项目以前的方法是通过 DllImport 分别导入两个 DLL,x86 DLL 绑定 private method_32,x64 DLL 绑定 private method_64,然后在 public method 在运行时判断 Environment.Is64BitProcess 并转发至 method_32 还是 method_64 。

    现在有两个问题:

    1. 有没有办法不用写这个 wrapper? 每导入一个方法都得写三个函数好麻烦;
    2. 在 Windows 10 ARM 系统上会用哪个方法(不考虑已经挂掉的 WinRT 了)?永远选择 x86 DLL 吗? Windows 11 ARM 有了 ARM64EC 之后会不会变成选择 x64 DLL 吗?以及这个项目升级 .NET 6 之后行为会变化吗?
    4 条回复    2021-12-30 21:47:16 +08:00
    Meano
        1
    Meano  
       2021-12-30 03:44:27 +08:00
    method 名称一致的话,import 一次就好,把 dll 文件写成一样的文件名,不同平台的 dll 放在不同目录下,只要在调用之前(比如静态构造函数内)修改程序运行时的环境变量 Path 加入对应平台 dll 存放目录路径即可;或者调用 Win32 函数 SetDllDirectory()。
    elfive
        2
    elfive  
       2021-12-30 06:32:13 +08:00 via iPhone
    听上去,应该是用 C++/CLI 实现一个兼容层比较合适。
    我负责的项目原生也只有 C++的 SDK ,客户要求提供 C#接口,我们也只能做一套 C++/CLI 接口出去。
    Soar360
        3
    Soar360  
       2021-12-30 15:34:05 +08:00
    可以先根据不同平台调用一下 kernel32.dll 的 LoadLibrary 方法,然后就只用写一个 Wrapper 了。
    第二个问题需要实际测试,遇到再说吧。
    jim9606
        4
    jim9606  
    OP
       2021-12-30 21:47:16 +08:00
    @Meano @elfive @Soar360
    目前感觉比较省事的方法是在接口类初始化时通过 SetDllDirectory ,这样 extern 方法只要写一个。
    但我现在不了解的情况是 Windows on ARM 的实际运作情况。AnyCPU (非 Prefer32bit )在这个 OS 上是运行在 64 位 CLR 上的吗?这时可以加载 x86 DLL 吗(通过 xtajit 翻译为 ARM64 )? 如果是 Win11 ARM ,是不是还可以加载 x64 DLL (通过 ARM64EC 翻译为 ARM64 )? 如果在 Environment.Is64BitProcess 为 true 就选择 x64 DLL 目录,会出问题吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3318 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 11:58 · PVG 19:58 · LAX 03:58 · JFK 06:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.