我有一个本机 DLL,有 32 位和 64 位版本 (x86)。我想创建一个适用于两种体系结构(任何 CPU)的包装器,并根据当前环境(32 位或 64 位,在运行时!)加载 DLL 的正确版本。这个过程应该自动发生,这样我的 DLL 的用户就不需要针对特定的体系结构。
有没有关于如何做到这一点的最佳实践?有什么例子可以指导我吗?
我找到了一种可能的解决方案,该解决方案为每个架构使用托管代理,然后使用Assembly.Resolve
加载正确版本的事件。然而,除了 2 个非托管库之外,这还要求我拥有 3 个托管程序集,这似乎有点矫枉过正。
还有其他解决办法吗?
这是我在许多项目中使用过的解决方案:
- 使用“面向 32 位的名称”命名 32 位程序集。为了
示例 MyAssembly.Native.x86.dll
- 使用“面向 64 位的名称”命名 64 位程序集。例如 MyAssembly.Native.x64.dll
- 将托管程序集编译为“任何 Cpu”
- 以相同的路径运送所有东西
以下是我声明 P/Invoke 方法的方式:
[DllImport("MyAssembly.Native.x86.dll", EntryPoint = "MyTest")]
private static extern void MyTest86(MyType myArg);
[DllImport("MyAssembly.Native.x64.dll", EntryPoint = "MyTest")]
private static extern void MyTest64(MyType myArg);
这是相应的“MyTest”函数,这是我将始终使用的函数(其他函数在这里只是为了正确的位数绑定)。它与其他 P/Invoke 具有相同的签名:
public static void MyTest(MyType myArg)
{
if (IntPtr.Size == 8)
{
MyTest64(myArg);
return;
}
MyTest86(myArg);
}
优点是:
- 您可以在同一路径中传送所有二进制文件(DLL、EXE...)
- 您支持具有相同文件布局的 32 位和 64 位进程和操作系统
- 您不必求助于 Win32 api 来更改 dll 加载路径
不便之处在于:
- 你将有 1 个“真实”方法的 3 个方法声明
- 由于适应性测试,您将损失一些 CPU 周期
- 根据您的上下文,有时您无法更改本机 DLL 名称,因此您不能这样做
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)