c# - 在加载上下文中加载非托管静态 dll

标签 c# .net-core

我有 native 非托管 dll,它是静态的,如果我想并行运行它,每次我需要库来做一些工作时都必须加载它。在 .NET 中,我会使用 AppDomain 并在需要时加载此 dll,但在 NET Core 中,AppDomains 已消失(目前)。我查看了 AssemblyLoadContext,但没有关于 LoadUnmanagedDll 的适当文档。 netstandard1.6 可以做到吗?

编辑 当前使用 PInvoke 调用代码并且运行良好。问题是因为这个未管理的 dll 的性质,当我尝试并行调用它时抛出 AccessViolationException,因为两个或多个任务想要访问相同的内存。

如果我每次都可以在某些上下文中加载 dll,然后调用 PInvoke,这个问题就会消失。

最佳答案

一种方法:

  1. System.Runtime.Loader.AssemblyLoadContext派生类
  2. 覆盖 Load(AssemblyName assemblyName) 调用 LoadFromAssemblyPath() 或返回 null 以回退到默认上下文
  3. 覆盖 IntPtr LoadUnmanagedDll(string unmanagedDllName) 调用 LoadUnmanagedDllFromPath() 以加载您的 native dll
  4. 间接访问您的 pinvoke 方法并通过一些已知的接口(interface)加载 native /非托管库

第4步是您需要根据现有代码结构进行调整的部分。就我而言,我创建了 3 个程序集:

  1. 调用代码
  2. 调用代码
  3. 前两个共享的接口(interface)

在调用代码中:

var assem = assemblyLoadContext.LoadFromAssemblyName(new 
System.Reflection.AssemblyName(pinvokeAssemblyName));
var type = assem.GetType(nameOfTypeThatCallsPinvoke);
return (ISharedInterface)Activator.CreateInstance(type);

nameOfTypeThatCallsPinvoke 的实例尝试使用 pinvoke 方法时,将调用加载上下文中的 LoadUnmanagedDll() 覆盖。

需要共享接口(interface),以便在编译时知道类型。如果调用代码直接引用 pinvoke 库,它的类型将不同于通过加载上下文获得的类型。

引用资料:

关于c# - 在加载上下文中加载非托管静态 dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43049370/

相关文章:

c# - 无法使用 String.Format 在 WPF 中显示版本字符串

c# - 在 Excel 中编辑嵌入在 Word 文档中的 Excel 对象

c# - Try/Catch/Finally 使用加密资源

c# - EF 核心实体数据访问中的强制转换无效

.net-core - 使用 ClickOnce : how do I make it useable as a command-line app? 部署的 .net 核心控制台应用程序

c# - (C#) 如何获取屏幕的点与像素关系?

c# - ASP.NET 核心,Web API : No route matches the supplied values

c# - .NET Core 2.1 Linux Keycloak 集成\身份验证(OpenID Connect + SSSD)

c# - 如何从继承的 FromBody 模型中获取正确的类型?

c# - 使用serialport.open()时发生I/O异常错误