Language Avancé

FFM permet à Java d'appeler directement des bibliothèques C, sans code répétitif JNI ni connaissance de Java côté 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;
// }
Un problème avec ce code ? Dites-le nous.
👁

Le code C reste du C pur

La fonction C n'a besoin d'aucune annotation JNI ni de code JNIEnv répétitif — toute bibliothèque C existante peut être appelée telle quelle.

Plus flexible

Appelez directement la plupart des bibliothèques C/C++ existantes sans écrire de code adaptateur ni générer de fichiers d'en-tête.

🛠️

Workflow simplifié

Inutile de s'arrêter, d'exécuter javac -h et d'implémenter l'interface définie dans le fichier .h généré.

Ancienne Approche
JNI (Java Native Interface)
Approche Moderne
FFM (Foreign Function & Memory API)
Depuis JDK
22
Difficulté
Avancé
Appeler du code C depuis Java
Disponible

Standardisé dans JDK 22 (mars 2024) ; auparavant en incubation depuis JDK 14

Java propose deux approches pour appeler du code natif C/C++ : le JNI traditionnel et la moderne API FFM. Avec JNI, vous déclarez une méthode comme native, exécutez javac -h pour générer un fichier d'en-tête C, puis implémentez la fonction en utilisant la lourde API JNI C (JNIEnv, jstring, etc.). FFM, introduite comme API standard dans Java 22, élimine tout cela : le code C reste du C pur — aucune convention JNI n'est requise. Cela facilite considérablement l'appel de bibliothèques C/C++ existantes sans modification. Le côté Java utilise Arena pour la gestion sécurisée de la mémoire hors tas et MethodHandle pour le downcall, garantissant flexibilité et sécurité.