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

2021-12-30 02:31:48 +08:00
 jim9606

最近在改一个 .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 之后行为会变化吗?
2231 次点击
所在节点    C#
4 条回复
Meano
2021-12-30 03:44:27 +08:00
method 名称一致的话,import 一次就好,把 dll 文件写成一样的文件名,不同平台的 dll 放在不同目录下,只要在调用之前(比如静态构造函数内)修改程序运行时的环境变量 Path 加入对应平台 dll 存放目录路径即可;或者调用 Win32 函数 SetDllDirectory()。
elfive
2021-12-30 06:32:13 +08:00
听上去,应该是用 C++/CLI 实现一个兼容层比较合适。
我负责的项目原生也只有 C++的 SDK ,客户要求提供 C#接口,我们也只能做一套 C++/CLI 接口出去。
Soar360
2021-12-30 15:34:05 +08:00
可以先根据不同平台调用一下 kernel32.dll 的 LoadLibrary 方法,然后就只用写一个 Wrapper 了。
第二个问题需要实际测试,遇到再说吧。
jim9606
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 目录,会出问题吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/825186

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX