Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you dynamically load cross platform Native/Unmanaged dlls/libs in .Net Core?

In .Net Core, you can PInvoke with [DllImport],

But if you want to dynamically load and map native api calls, DllImport doesn't solve the problem.

On windows we handled this with a DllImport to LoadModule. Then you could use GetProcAddress to map an address to a delegate which you could then call, effectively dynamically loading api calls.

Is there any way to do this in .Net Core out of the box so that your logic doing the loading works cross platform on Linux, Mac OSX, and Windows?

This can be built, but I'm trying to see if there's a way to do this before I chase that rabbit.

like image 242
Ryan Mann Avatar asked Mar 14 '18 05:03

Ryan Mann


1 Answers

One potential solution is related to my answer to the SO question Load unmanaged static dll in load context:

You can use AssemblyLoadContext in System.Runtime.Loader package.

Your implementation for LoadUnmanagedDll() contains the logic to load platform dependent native libraries:

string arch = Environment.Is64BitProcess ? "-x64" : "-x86";
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
    var fullPath = Path.Combine(assemblyPath, "runtimes", "osx" + arch, "native", "libnng.dylib");
    return LoadUnmanagedDllFromPath(fullPath);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
    var fullPath = Path.Combine(assemblyPath, "runtimes", "linux" + arch, "native", "libnng.so");
    return LoadUnmanagedDllFromPath(fullPath);
}
else // RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
{
    var fullPath = Path.Combine(assemblyPath, "runtimes", "win" + arch, "native", "nng.dll");
    return LoadUnmanagedDllFromPath(fullPath);
}

The runtimes/platform/native/ is the nupkg convention but you can use any path you like.

Your pinvoke methods will be similar to:

[DllImport("nng", CallingConvention = CallingConvention.Cdecl)]
public static extern int nng_aio_alloc(out nng_aio aio, AioCallback callback, IntPtr arg);

Calling a native method like nng_aio_alloc through the shared interface will trigger then load of nng library and your LoadUnmanagedDll() function will get called.

like image 198
Jake Avatar answered Oct 04 '22 00:10

Jake