Load unmanaged static dll in load context

2019-05-30 23:59发布

问题:

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.

回答1:

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:

  • AssemblyLoadContext design doc
  • Post about using AssemblyLoadContext to load plugins (code on github)
  • Post about using AssemblyLoadContext with a native library (code on github) (Disclaimer: mine)


标签: c# .net-core