在加载上下文中加载非托管静态dll [英] Load unmanaged static dll in load context

查看:135
本文介绍了在加载上下文中加载非托管静态dll的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有本地非托管dll,它是静态的,如果我想并行运行它,则每次需要库执行某些工作时都必须加载该dll。在.NET中,我将使用AppDomain并在需要时加载此dll,但在NET Core中,AppDomains已消失(目前)。我看过AssemblyLoadContext,但是LoadUnmanagedDll没有适当的文档。可以在netstandard1.6中完成吗?



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



如果我可以加载dll

解决方案

一种方法:

在某些情况下,每次调用PInvoke都会解决此问题。 >


  1. System.Runtime.Loader.AssemblyLoadContext
  2. 导出类
  3. 覆盖 Load(AssemblyName assemblyName)调用 LoadFromAssemblyPath()或在默认上下文中将null返回到后备状态

  4. 覆盖 IntPtr LoadUnmanagedDll(string unmanagedDllName)调用 LoadUnmanagedDllFromPath()加载本地dll

  5. 通过某些已知的接口

  6. 间接访问您的pinvoke方法并加载本机/非托管库。 ol>

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


    1. 调用代码

    2. Pinvoke代码

    3. 前两个共享的接口

    在调用代码中:

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

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



    需要共享接口,因此类型为在编译时已知。如果调用代码直接引用了pinvoke库,则其类型将不同于通过加载上下文获得的类型。



    参考文献:




    I have native unmanaged dll which is static and must be loaded each time when I need library to do some work if i want to run it in parallel. In .NET I would use AppDomain and load this dll when i need it, but in NET Core AppDomains are gone (for now). I have looked at AssemblyLoadContext but there is no proper documentation with LoadUnmanagedDll. Can this be done in netstandard1.6?

    Edit Currently code is called with PInvoke and is working perfectly. Problem is because nature of this unmanged dll, when I try to call it in parallel throws AccessViolationException because two or more task wants to access same memory.

    If I could load dll for each time that in some context and then call PInvoke on that this problem would be gone.

    解决方案

    One approach:

    1. Derive class from System.Runtime.Loader.AssemblyLoadContext
    2. Override Load(AssemblyName assemblyName) calling LoadFromAssemblyPath() or returning null to fallback on default context
    3. Override IntPtr LoadUnmanagedDll(string unmanagedDllName) calling LoadUnmanagedDllFromPath() to load your native dll
    4. Indirectly access your pinvoke methods and load the native/unmanaged library through some known interface

    Step 4 is the part you need to adjust based on the structure of the existing code. In my case, I created 3 assemblies:

    1. Calling code
    2. Pinvoke code
    3. Interfaces shared by the first two

    In the calling code:

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

    When instance of nameOfTypeThatCallsPinvoke attempts to use pinvoke method your LoadUnmanagedDll() override on the load context will get called.

    The shared interfaces are needed so types are known at compile-time. If the calling code references the pinvoke library directly it's types will differ from those obtained through the load context.

    References:

    这篇关于在加载上下文中加载非托管静态dll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆