aKz*_*enT 4 .net c# dll pinvoke
我有一个 32 位和 64 位版本 (x86) 的本机 DLL。我想创建一个适用于两种架构(任何 CPU)的包装器,并根据当前环境(32 位或 64 位,运行时!)加载正确版本的 DLL。这个过程应该自动发生,所以我的 DLL 的用户不需要针对特定的体系结构。
有没有关于如何做到这一点的最佳实践?任何可以指导我的例子?
我找到了一种可能的解决方案,它为每个架构使用托管代理,然后使用该Assembly.Resolve事件加载正确的版本。但是,这要求我除了 2 个非托管库之外还有 3 个托管程序集,这似乎有点过头了。
还有其他解决方案吗?
我这样做的方法是在LoadLibrary对库调用任何 p/invoke 之前先 p/invoke 调用。
LoadLibrary加载它并传递 DLL 的完整路径。这依赖于 32 位和 64 位具有相同名称的非托管 DLL。如果情况并非如此,那么你就有麻烦了。在这种情况下,您可能需要通过 p/invoking 显式绑定到 DLL GetProcAddress。这一点也不好玩。或者你实现西蒙在他的回答中描述的那种脚手架。
这是我在许多项目中使用的解决方案:
这是我声明 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);
Run Code Online (Sandbox Code Playgroud)
这是相应的“MyTest”函数,我将一直使用它(其他函数只是为了正确的位绑定)。它具有与其他 P/Invoke 相同的签名:
public static void MyTest(MyType myArg)
{
if (IntPtr.Size == 8)
{
MyTest64(myArg);
return;
}
MyTest86(myArg);
}
Run Code Online (Sandbox Code Playgroud)
优点是:
不便之处在于: