java22 ffm 用法


这里用java调用了C语言标准库中的sstrlen方法

import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SymbolLookup;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;

public class FFMTestWindows {
  public static void main(String[] args) throws Throwable {
    // 1. 获得一个链接器——访问外部函数的中心元素
    Linker linker = Linker.nativeLinker();

    // 2. 获取常用库的Lookup对象
    SymbolLookup stdlib = linker.defaultLookup();

    // 3. 获取C标准库中"strlen"函数的地址
    MemorySegment strlenAddress = stdlib.find("strlen").orElseThrow();

    // 4. 定义strlen函数的输入和输出参数
    FunctionDescriptor descriptor =
        FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS);

    // 5. 获取"strlen"函数的句柄
    MethodHandle strlen = linker.downcallHandle(strlenAddress, descriptor);

    // 6. 获得一个受限的内存区域(可以显式关闭的内存区域)
    try (Arena offHeap = Arena.ofConfined()) {

      // 7. 将Java字符串转换为C字符串并将其存储在堆外内存中
      MemorySegment str = offHeap.allocateFrom("asdfasdfasdfasdfasdf");

      // 8. 调用"strlen"函数
      long len = (long) strlen.invoke(str);
      System.out.println("len:" + len);
    }
  }
}