gpt4 book ai didi

c# - 实现类似 [DllImport] 的机制

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:17:24 25 4
gpt4 key购买 nike

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

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

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

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

1) 为什么编译器对任何属性都满意?加载程序是否有关于使用该属性来解析挂起的外部的任何魔法?这可以通过提供一个由属性实现的接口(interface)来直接完成。这样,运行时将查找外部搜索的属性,以寻找实现“魔术”接口(interface)的属性。

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

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

虽然我很喜欢英语课,但这实际上不是我想要的:-))

基督徒。

最佳答案

实际上,我采用了 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() ;
}
}

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

关于c# - 实现类似 [DllImport] 的机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24981288/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com