Wywołanie kodu C z Javy
FFM pozwala Javie wywoływać biblioteki C bezpośrednio, bez kodu szablonowego JNI ani znajomości Javy po stronie C.
public class CallCFromJava {
static { System.loadLibrary("strlen-jni"); }
public static native long strlen(String s);
public static void main(String[] args) {
long ret = strlen("Bambi");
System.out.println("Return value " + ret); // 5
}
}
// Run javac -h to generate the .h file, then write C:
// #include "CallCFromJava.h"
// #include <string.h>
// JNIEXPORT jlong JNICALL Java_CallCFromJava_strlen(
// JNIEnv *env, jclass clazz, jstring str) {
// const char* s = (*env)->GetStringUTFChars(env, str, NULL);
// jlong len = (jlong) strlen(s);
// (*env)->ReleaseStringUTFChars(env, str, s);
// return len;
// }
void main() throws Throwable {
try (var arena = Arena.ofConfined()) {
// Use any system library directly — no C wrapper needed
var stdlib = Linker.nativeLinker().defaultLookup();
var foreignFuncAddr = stdlib.find("strlen").orElseThrow();
var strlenSig = FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS);
var strlenMethod = Linker.nativeLinker() .downcallHandle(foreignFuncAddr, strlenSig);
var ret = (long) strlenMethod.invokeExact(arena.allocateFrom("Bambi"));
System.out.println("Return value " + ret); // 5
}
}
// Your own C library needs no special Java annotations:
// long greet(char* name) {
// printf("Hello %s\n", name);
// return 0;
// }
Kod C pozostaje zwykłym C
Funkcja C nie wymaga adnotacji JNI ani kodu szablonowego JNIEnv — każdą istniejącą bibliotekę C można wywołać bez zmian.
Większa elastyczność
Bezpośrednie wywoływanie większości istniejących bibliotek C/C++ bez pisania kodu adaptera ani generowania plików nagłówkowych.
Prostszy przepływ pracy
Nie trzeba zatrzymywać się, uruchamiać javac -h i implementować interfejsu zdefiniowanego w wygenerowanym pliku .h.
Ustandaryzowane w JDK 22 (marzec 2024); wcześniej w fazie inkubacji od JDK 14
Java oferuje dwa podejścia do wywoływania natywnego kodu C/C++: tradycyjne JNI oraz nowoczesne API FFM. W JNI deklarujesz metodę jako native, uruchamiasz javac -h, aby wygenerować plik nagłówkowy C, a następnie implementujesz funkcję przy użyciu uciążliwego JNI C API (JNIEnv, jstring itp.). FFM, wprowadzone jako standardowe API w Java 22, eliminuje to wszystko: kod C pozostaje zwykłym C — bez żadnych konwencji JNI. Dzięki temu wywołanie istniejących bibliotek C/C++ bez modyfikacji jest znacznie łatwiejsze. Strona Java używa Arena do bezpiecznego zarządzania pamięcią poza stertą oraz MethodHandle do downcallu, zapewniając zarówno elastyczność, jak i bezpieczeństwo.