ネイティブ・イメージの外部関数およびメモリーAPI

外部関数およびメモリー(FFM) APIは、Javaコードとネイティブ・コードの相互の対話を可能にするネイティブ・インタフェースです。JEP 442では、JavaプラットフォームのプレビューAPIであり、--enable-previewで有効にする必要があります。"制限された"ネイティブ操作(ネイティブ・コードへのコールまたはネイティブ・コードからのコールのハンドルの作成を含む)を実行できるモジュールは、--enable-native-access=を使用して指定する必要があります。このページでは、ネイティブ・イメージでのFFM APIのサポートの概要を示します。

外部メモリー

通常、外部メモリー機能がサポートされます。共有領域は、現在サポートされていません。

外部関数

FFM APIを使用すると、Javaコードがネイティブ関数に対してdownをコールでき、逆にネイティブ・コードがupをコールしてメソッド・ハンドルを介してJavaコードを呼び出すことができます。これらの2種類のコールはそれぞれ「ダウンコール」および「アップコール」と呼ばれ、まとめて「外部コール」と呼ばれます。

現在、ダウンコールのみがサポートされており、AMD64アーキテクチャでのみサポートされています。

ネイティブ関数の検索

FFM APIは、ネイティブ・ライブラリ内の関数を名前で検索するためのSymbolLookupインタフェースを提供します。SymbolLookup.loaderLookup()は、現在サポートされている唯一の種類のSymbolLookupです。

外部コールの登録

実行時にネイティブ・コードへのコールを実行するには、イメージ・ビルド時にサポート・コードを生成する必要があります。したがって、native-imageツールには、実行時にダウンコールを実行できる関数を特徴付ける記述子を指定する必要があります。

たとえば次のような記述子は、カスタムのFeatureを使用して登録できます。

import static java.lang.foreign.ValueLayout.*;

class ForeignRegistrationFeature implements Feature { 
  public void duringSetup(DuringSetupAccess access) {
    RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.ofVoid());
    RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.ofVoid(), Linker.Option.isTrivial());
    RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT));
    RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.of(ADDRESS, JAVA_INT, JAVA_INT), Linker.Option.firstVariadicArg(1));
    RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.ofVoid(JAVA_INT), Linker.Option.captureCallState("errno"));
  }
}

カスタム機能をアクティブ化するには、--features=com.example.ForeignRegistrationFeature (機能クラスの完全修飾名)をnative-imageに渡す必要があります。これは、native-image.propertiesファイルを使用して実行することをお勧めします。

アップコール

アップコールはまだサポートされていません。