.Net Coreでは、[DllImport]を使用してPInvokeを実行できます。
ただし、ネイティブAPI呼び出しを動的にロードしてマップする場合、DllImportは問題を解決しません。
Windowsでは、これをDllImport toLoadModuleで処理しました。次に、GetProcAddressを使用して、アドレスをデリゲートにマップし、それを呼び出すことができます。これにより、API呼び出しが効果的に動的に読み込まれます。
.Net Coreでこれをすぐに実行して、読み込みを行うロジックがLinux、Mac OSX、およびWindowsのクロスプラットフォームで機能するようにする方法はありますか?
これは構築できますが、そのウサギを追いかける前に、これを行う方法があるかどうかを確認しようとしています。
考えられる解決策の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()
関数が呼び出されます。
.NetCore Repoで問題を開いた後、これは.Net Coreに追加される予定であると通知されましたが、2.1には含まれません。
現在、githubにユーザーが作成したプロトタイプの実装があります。