我有一个本机DLL,它有32位和64位版本(x86)。我想创建一个适用于两种体系结构(任何CPU)的包装器,并根据当前环境(32位或64位,在运行时!)加载正确版本的DLL。此过程应自动进行,以便我的DLL用户不需要针对特定的体系结构。
有关于如何做到这一点的最佳做法吗?有什么可以指导我的例子吗?
我找到了一种可能的解决方案,它为每个架构使用托管代理,然后使用Assembly.Resolve
事件加载正确的版本。但是,除了2个非托管库之外,这需要我有3个托管程序集,这看起来有点矫枉过正。
还有其他解决方案吗?
答案 0 :(得分:4)
我这样做的方法是在调用对库的任何p /调用之前调用LoadLibrary
。
LoadLibrary
加载它,传递DLL的完整路径。这依赖于32位和64位具有相同名称的非托管DLL。如果情况并非如此,那么你就麻烦了。在这种情况下,您可能需要通过p /调用GetProcAddress
显式绑定到DLL。这根本不好玩。或者你实现了Simon在他的回答中描述的那种脚手架。
答案 1 :(得分:4)
以下是我在许多项目中使用的解决方案:
以下是我如何声明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);
这是相应的“我的测试”。我将永远使用的功能(其他功能只是为了正确的位数绑定)。它具有与其他P / Invoke相同的签名:
public static void MyTest(MyType myArg)
{
if (IntPtr.Size == 8)
{
MyTest64(myArg);
return;
}
MyTest86(myArg);
}
优点是:
给您带来的不便是:
答案 2 :(得分:0)
查看Microsoft.WinAny.Helper和 DynamicNativeLibrary 类,它可以帮助您满足需要。