Language Avanzato

FFM consente a Java di chiamare direttamente librerie C, senza boilerplate JNI né conoscenza di Java lato C.

✕ Java 1.1+
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;
// }
✓ Java 22+
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;
// }
Vedi un problema con questo codice? Faccelo sapere.
👁

Il codice C rimane C puro

La funzione C non richiede annotazioni JNI né boilerplate JNIEnv — qualsiasi libreria C esistente può essere chiamata così com'è.

Più flessibile

Chiama direttamente la maggior parte delle librerie C/C++ esistenti senza scrivere codice adattatore né generare file di intestazione.

🛠️

Flusso di lavoro più semplice

Nessuna necessità di fermarsi, eseguire javac -h e implementare l'interfaccia definita nel file .h generato.

Approccio Vecchio
JNI (Java Native Interface)
Approccio Moderno
FFM (Foreign Function & Memory API)
Dal JDK
22
Difficoltà
Avanzato
Chiamare codice C da Java
Disponibile

Standardizzato in JDK 22 (marzo 2024); precedentemente in incubazione da JDK 14

Java offre due approcci per chiamare codice nativo C/C++: il tradizionale JNI e la moderna API FFM. Con JNI, si dichiara un metodo come native, si esegue javac -h per generare un file di intestazione C, quindi si implementa la funzione usando la complicata JNI C API (JNIEnv, jstring, ecc.). FFM, introdotta come API standard in Java 22, elimina tutto ciò: il codice C rimane puro C — nessuna convenzione JNI richiesta. Questo rende molto più semplice chiamare librerie C/C++ esistenti senza modifiche. Il lato Java usa Arena per la gestione sicura della memoria off-heap e MethodHandle per il downcall, garantendo flessibilità e sicurezza.