次の方法で共有


ネイティブ AOT とのネイティブ コード相互運用

ネイティブ コード相互運用機能は、マネージド コードからアンマネージド ライブラリにアクセスしたり、マネージド ライブラリをアンマネージド コード (反対方向) に公開したりできるテクノロジです。

ネイティブ コード相互運用機能は、ネイティブ AOT デプロイと非 AOT デプロイでも同様に機能しますが、ネイティブ AOT として発行する場合は、いくつかの詳細が異なります。

P/Invoke の直接呼び出し

互換性を高める目的で、AOT コンパイル バイナリの P/Invoke 呼び出しは、既定で実行時に遅延してバインドされます。 オペレーティング システムに付属する動的ローダーによって起動中にバインドされる、選択した P/Invoke メソッドの直接呼び出しを生成するように AOT コンパイラを構成できます。 直接呼び出しによって参照されるアンマネージド ライブラリとエントリ ポイントは、常に実行時に使用できる必要があります。そうしないと、ネイティブ バイナリの起動に失敗します。

直接 P/Invoke 呼び出しの利点は次のとおりです。

  • 安定した状態のパフォーマンスが向上します。
  • アンマネージ依存関係を静的にリンクできるようにします。

プロジェクト ファイル内の <DirectPInvoke> 項目を使用して、直接 P/Invoke 生成を構成できます。 項目名には、モジュール内のすべてのエントリ ポイントの直接呼び出しを有効にする <modulename>、または特定のモジュールとエントリ ポイントの直接呼び出しを有効にする <modulename!entrypointname> のいずれかを指定できます。

外部ファイル内のエントリ ポイントの一覧を指定するには、プロジェクト ファイル <DirectPInvokeList> 項目を使用します。 リストは、直接 P/Invoke 呼び出しの数が多く、個々の <DirectPInvoke> 項目を使用して指定するのは現実的でない場合に便利です。 ファイルには、 #以降の空の行とコメントを含めることができます。

例:

<ItemGroup>
  <!-- Generate direct PInvoke calls for everything in __Internal -->
  <!-- This option replicates Mono AOT behavior that generates direct PInvoke calls for __Internal -->
  <DirectPInvoke Include="__Internal" />
  <!-- Generate direct PInvoke calls for everything in libc (also matches libc.so on Linux or libc.dylib on macOS) -->
  <DirectPInvoke Include="libc" />
  <!-- Generate direct PInvoke calls for Sleep in kernel32 (also matches kernel32.dll on Windows) -->
  <DirectPInvoke Include="kernel32!Sleep" />
  <!-- Generate direct PInvoke for all APIs listed in DirectXAPIs.txt -->
  <DirectPInvokeList Include="DirectXAPIs.txt" />
</ItemGroup>

Windows では、ネイティブ AOT は、サポートされているすべてのバージョンの Windows で使用できるダイレクト P/Invoke メソッドの事前設定された一覧を使用します。

Warnung

ダイレクト P/Invoke メソッドは、ネイティブ AOT ランタイム ライブラリではなく、オペレーティング システムの動的ローダーによって解決されるため、ダイレクト P/Invoke メソッドは DefaultDllImportSearchPathsAttributeを考慮しません。 ライブラリの検索順序は、オペレーティング システムによって定義されている動的ローダー規則に従います。 一部のオペレーティング システムとローダーでは、リンカー フラグを使用して動的読み込みを制御する方法が用意されています (Windows での /DEPENDENTLOADFLAG や Linux での -rpath など)。 リンカー フラグを指定する方法の詳細については、「 リンク」 セクションを参照してください。

リンク

アンマネージド ライブラリに対して静的にリンクするには、Windows 上の<NativeLibrary Include="filename" /> ファイルと Unix に似たシステム上の.lib ファイルを指す.aを指定する必要があります。

例:

<ItemGroup>
  <!-- Generate direct PInvokes for Dependency -->
  <DirectPInvoke Include="Dependency" />
  <!-- Specify library to link against -->
  <NativeLibrary Include="Dependency.lib" Condition="$(RuntimeIdentifier.StartsWith('win'))" />
  <NativeLibrary Include="Dependency.a" Condition="!$(RuntimeIdentifier.StartsWith('win'))" />
</ItemGroup>

ネイティブ リンカーに追加のフラグを指定するには、 <LinkerArg> 項目を使用します。

例:

<ItemGroup>
  <!-- link.exe is used as the linker on Windows -->
  <LinkerArg Include="/DEPENDENTLOADFLAG:0x800" Condition="$(RuntimeIdentifier.StartsWith('win'))" />

  <!-- Native AOT invokes clang/gcc as the linker, so arguments need to be prefixed with "-Wl," -->
  <LinkerArg Include="-Wl,-rpath,'/bin/'" Condition="$(RuntimeIdentifier.StartsWith('linux'))" />
</ItemGroup>

ネイティブ エクスポート

ネイティブ AOT コンパイラは、空でない UnmanagedCallersOnlyAttribute プロパティを持つEntryPointで注釈が付けられたメソッドをパブリック C エントリ ポイントとしてエクスポートします。 これにより、AOT コンパイル済みモジュールを外部プログラムに動的または静的にリンクすることができます。 パブリッシュされたアセンブリで UnmanagedCallersOnly マークされているメソッドのみが考慮されます。 プロジェクト参照または NuGet パッケージ内のメソッドはエクスポートされません。 詳細については、 NativeLibrary のサンプルを参照してください。