这是我的问题:在PCL库中,我将从C ++ DLL中调用非托管代码。该DLL有两个版本(x86和x64),出于性能原因,应根据嵌入PCL库的平台引用正确的库。
由于[DllImport]
属性需要一个常量字符串作为库名,因此这种非常方便的方式使得无用,因为要在运行时确定正确的库。有一些“hubby”方法可以手动加载函数(LoadLibrary
,GetProcaddress
和GetDelegateForFunctionPointer
),但我会让程序员更方便。
因此,声明外部函数不是问题。好吧,C#编译器检测到外部并担心这一事实,即使用缺少的[DllImport]
属性,在加载类型时可能无法解析外部。好的,我定义了一个属性[MyImport]
并将其放在外部声明和宾果游戏中,至少编译器很高兴。
在运行时,我当然得到一个TypeLoadException,因为我的外部确实没有得到解决。这提出了两个问题:
1)为什么编译器对任何属性都满意? 关于使用该属性以解决挂起的外部问题,加载器是否有任何魔法?这可以通过提供由属性实现的接口直接完成。这样,运行时将查找外部搜索的属性,以实现那些实现“魔术”接口的属性。
2)如何以可以实现自己的加载器的方式捕获TypeLoadException? 该加载器将迭代给定类型的所有外部,读取[MyImport]属性并以这种方式解析外部。
如果可以实现这两个想法中的一个,或者是否有其他解决方案可以解决上述问题?
我很欣赏英语课程,但实际上并不是我要求的: - ))
基督教。
答案 0 :(得分:1)
实际上,我选择了汉斯提到的解决方案,在评论部分进一步说明。
正如他所提到的,整个问题是一个部署问题,而不是通过变通方法开发来解决的问题。所以,我给了两个平台版本相同的名称,让它们驻留在不同的目录中 - 像这样:
SystemTera.MyPCL.dll
x86\SystemTera.Platform.dll
x64\SystemTera.Platform.dll
启动时,我将加载程序指向正确的平台版本:
public static class Platform
{
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetDllDirectory(string pathName) ;
public static void Setup()
{
if (Environment.Is64BitProcess)
SetDllDirectory("./x64/") ;
else // default Win32
SetDllDirectory("./x86/") ;
}
}
当我进一步参考平台库时,加载器/抖动执行正确的工作:
public class MyClass
{
[DllImport("SystemTera.Platform.dll")]
static extern void MyPlatformFunction() ;
public void DoTheJob()
{
MyPlatformFunction() ;
}
}
使用框架提供的现有概念,这是一个很好的解决方案。