web-dev-qa-db-ja.com

クロスプラットフォームのネイティブ/アンマネージドdll / libsを.NetCoreに動的にロードできますか?

.Net Coreでは、[DllImport]を使用してPInvokeを実行できます。

ただし、ネイティブAPI呼び出しを動的にロードしてマップする場合、DllImportは問題を解決しません。

Windowsでは、これをDllImport toLoadModuleで処理しました。次に、GetProcAddressを使用して、アドレスをデリゲートにマップし、それを呼び出すことができます。これにより、API呼び出しが効果的に動的に読み込まれます。

.Net Coreでこれをすぐに実行して、読み込みを行うロジックがLinux、Mac OSX、およびWindowsのクロスプラットフォームで機能するようにする方法はありますか?

これは構築できますが、そのウサギを追いかける前に、これを行う方法があるかどうかを確認しようとしています。

9
Ryan Mann

考えられる解決策の1つは、 私の答え からSO質問 ロードコンテキストでアンマネージ静的dllをロードする

System.Runtime.Loader パッケージで AssemblyLoadContext を使用できます。

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規則 ですが、任意のパスを使用できます。

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()関数が呼び出されます。

5
Jake

.NetCore Repoで問題を開いた後、これは.Net Coreに追加される予定であると通知されましたが、2.1には含まれません。

現在、githubにユーザーが作成したプロトタイプの実装があります。

https://github.com/mellinoe/nativelibraryloader

2
Ryan Mann