GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |
GeezerVison is showing en.wikibooks.org — Foreign Function and Memory API - Wikibooks, open books for an open world
import java.lang.foreign.*; public class ForeignMemoryExample { public static void main(String[] args) { try (Arena arena = Arena.ofConfined()) { MemorySegment segment = arena.allocate(5 * Double.BYTES); for (int i = 0; i < 5; ++i) { segment.setAtIndex(ValueLayout.JAVA_DOUBLE, i, i * 1.1); } for (int i = 0; i < 5; ++i) { double value = segment.getAtIndex(ValueLayout.JAVA_DOUBLE, i); System.out.printf("Value at index %d: %d%n", i, value); } } } } In a sense, Java Foreign Function and Memory API allows for direct memory allocation outside the JVM heap (i.e. the operating system heap), through As a foreign function interface, import java.lang.foreign.*; import java.lang.invoke.MethodHandle; public class ForeignFunctionExample { public static void main(String[] args) throws Throwable { Linker linker = Linker.nativeLinker(); SymbolLookup stdlib = linker.defaultLookup(); MethodHandle printf = linker.downcallHandle( stdlib.findOrThrow("printf"), FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS) ); MethodHandle strlen = linker.downcallHandle( stdlib.findOrThrow("strlen"), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS) ); try (Arena arena = Arena.ofConfined()) { MemorySegment formatString = arena.allocateUtf8String("Hello, %s!\n"); MemorySegment argString = arena.allocateUtf8String("World"); printf.invokeExact(formatString, argString); // prints "Hello, World!" long len = (long)strlen.invokeExact(formatString); // len = 5 } } } To call C++ code using FFM, it can be done like so: In C++ (as libmylib.so on UNIX, mylib.dll on Windows): module; #ifdef _WIN32 #define EXPORT_API __declspec(dllexport) #else #define EXPORT_API [[gnu::visibility("default")]] #endif export module org.wikibooks.native.example; import std; export extern "C" { EXPORT_API void printGreeting(const char* name) { std::println("Hello, {}!", name); } EXPORT_API double sin(double x) { return std::sin(x); } EXPORT_API double cos(double x) { return std::cos(x); } } In Java: 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.invoke.MethodHandle; import java.lang.invoke.MethodType; public class FFMExample { public static void main(String[] args) throws Throwable { System.loadLibrary("mylib"); Linker linker = Linker.nativeLinker(); SymbolLookup lookup = SymbolLookup.loaderLookup(); try (Arena arena = Arena.ofConfined()) { MethodHandle printGreetingHandle = linker.downcallHandle( lookup.find("printGreeting").orElseThrow(), MethodType.methodType(void.class, MemorySegment.class), FunctionDescriptor.of(ValueLayout.JAVA_VOID, ValueLayout.ADDRESS) ); printGreetingHandle.invoke("John Doe"); MethodHandle sinHandle = linker.downcallHandle( lookup.find("sin").orElseThrow(), MethodType.methodType(double.class, double.class), FunctionDescriptor.of(ValueLayout.JAVA_DOUBLE, ValueLayout.JAVA_DOUBLE) ); double result = (double)sinHandle.invoke(Math.PI / 3); System.out.printf("sin(pi/3) = %s", result); MethodHandle cosHandle = linker.downcallHandle( lookup.find("cos").orElseThrow(), MethodType.methodType(double.class, double.class), FunctionDescriptor.of(ValueLayout.JAVA_DOUBLE, ValueLayout.JAVA_DOUBLE) ); double result = (double)cosHandle.invoke(Math.PI / 3); System.out.printf("cos(pi/3) = %s", result); } } } | |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |