4

这是我的问题:在 PCL 库中,我将从 C++ DLL 调用非托管代码。该 DLL 有两个版本(x86 和 x64),出于性能原因,应根据嵌入 PCL 库的平台引用正确的库。

由于该[DllImport]属性需要一个常量字符串作为库名称,因此这种非常方便的方式变得无用,因为正确的库将在运行时确定。有一些手动加载函数的“hubby”方法(和) LoadLibrary,但我会让程序员更方便。GetProcaddressGetDelegateForFunctionPointer

所以,声明一个外部函数不是问题。好吧,C# 编译器检测到外部并担心这样一个事实,即缺少[DllImport]属性,加载类型时可能无法解析外部。好的,我定义了一个属性[MyImport],并把它放在了外部声明和宾果游戏中,至少编译器很高兴。

在运行时,我当然会得到一个 TypeLoadException 因为我的外部确实没有解决。这就提出了两个问题:

1)为什么编译器对任何属性都满意?加载程序在使用该属性来解决待处理的外部问题方面是否有任何魔力?这可以通过提供一个由属性实现的接口来直接完成。这样,运行时将查找外部搜索的属性,以查找那些实现“魔术”接口的属性。

2) 如何以可以实现自己的加载器的方式捕获 TypeLoadException?该加载程序将从给定类型迭代所有外部,读取 [MyImport] 属性并以这种方式解析外部。

如果可能实现这两个想法之一,或者是否有任何其他解决方案可以解决上述问题?

我很欣赏英语课,但这实际上不是我想要的:-))

基督教。

4

1 回答 1

1

实际上,我采用了 Hans 提到的解决方案,在评论部分更下方。

正如他所提到的,整个问题是一个部署问题,而不是通过变通方法开发来解决的问题。所以,我给这两个平台版本赋予了相同的名称,并让它们驻留在不同的目录中——就像这样:

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() ;
    }
}

使用框架提供的现有概念,这是一个很好的解决方案。

于 2014-07-29T12:31:18.937 回答