JDK

Java 17 新機能(4)

JEP 412: 外部メモリと外部関数 (Incubator)

Javaランタイム外部のメモリにアクセスしたり,ネイティブ関数を呼び出すためのAPIを提供します。以前からJNIなどの方法でアクセスすることは可能でしたが,実装が大変である上にパフォーマンスにも課題がありました。より洗練されたAPIを提供しようという意図で開発されています。

  • 外部メモリの割り当て
  • 構造化された外部メモリの操作とアクセス
  • 外部リソース(リソーススコープ)のライフサイクル管理と外部関数の呼び出し

以下のプログラムではC言語の文字列の長さを返すsize_t strlen(const char *s)を呼び出します。コンパイル時には,–add-modules jdk.incubator.foreignオプションをつける必要があります。また,実行には–add-modules jdk.incubator.foreign オプションに加えて,–enable-native-access=ALL-UNNAMEDオプションもつける必要があります。

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.ResourceScope;
import jdk.incubator.foreign.ValueLayout;
public class ForeignFunction01
{
    public static void main(String[] args) throws Throwable
    {
        strlen("Hello World!");
    }
    private static void strlen(String string) throws Throwable
    {
        MethodHandle strlen = CLinker.getInstance().downcallHandle(
            CLinker.systemLookup().lookup("strlen").get(),
            MethodType.methodType(long.class, MemoryAddress.class),
            FunctionDescriptor.of(CLinker.C_LONG_LONG, CLinker.C_POINTER)
        );
        MemorySegment str = CLinker.toCString(string, ResourceScope.newImplicitScope());
        long length = (long)strlen.invokeExact(str.address()); 
        System.out.printf("Length of string \"%s\" is %d\n", string, length);
    }
}

警告:実験的なモジュールを使用しています: jdk.incubator.foreign
警告1個
WARNING: Using incubator modules: jdk.incubator.foreign
Length of string “Hello World!” is 12

JEP 414: ベクトルAPI (Second Incubator)

ベクトル演算をサポートしているCPUに向けてベクトル演算をサポートするAPIを提供するものである。