你能在.Net Core中动态加载跨平台的Native / Unmanaged dll / libs吗?

问题描述 投票:6回答:2

在.Net Core中,您可以使用[DllImport]进行PInvoke,

但是如果你想动态加载和映射本机api调用,DllImport并不能解决问题。

在Windows上,我们使用DllImport到LoadModule处理了这个问题。然后,您可以使用GetProcAddress将地址映射到您可以调用的委托,从而有效地动态加载api调用。

有没有办法在.Net Core中开箱即用,这样你的逻辑加载工作就可以在Linux,Mac OSX和Windows上跨平台工作?

这可以建立,但我试图看看有没有办法在追逐那只兔子之前做到这一点。

c# .net-core asp.net-core-mvc asp.net-core-2.0 asp.net-core-1.0
2个回答
4
投票

一个潜在的解决方案是my answer与SO问题Load unmanaged static dll in load context

你可以在AssemblyLoadContext包中使用System.Runtime.Loader

您对LoadUnmanagedDll()的实现包含加载平台相关本机库的逻辑:

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);
}

runtimes/platform/native/nupkg convention,但你可以使用你喜欢的任何路径。

你的pinvoke方法将类似于:

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

通过共享接口调用nng_aio_alloc等本机方法将触发nng库的加载,并调用LoadUnmanagedDll()函数。


1
投票

在.NetCore Repo上打开一个问题后,我被告知这将被添加到.Net Core,但不会在2.1中。

目前,用户在github上创建了一个Prototype Implementation:

https://github.com/mellinoe/nativelibraryloader

© www.soinside.com 2019 - 2024. All rights reserved.