Language متقدم

تتيح FFM لـ Java استدعاء مكتبات C مباشرةً، دون الحاجة إلى كليشيهات JNI أو معرفة Java على جانب 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;
// }
هل ترى مشكلة في هذا الكود؟ أخبرنا.
👁

كود C يبقى C نقياً

لا تحتاج دالة C إلى تعليقات JNI أو كليشيهات JNIEnv — يمكن استدعاء أي مكتبة C موجودة مباشرةً.

أكثر مرونة

استدعِ معظم مكتبات C/C++ الموجودة مباشرةً دون كتابة كود محوّل أو توليد ملفات ترويسة.

🛠️

سير عمل أسهل

لا حاجة للتوقف وتشغيل javac -h وتنفيذ الواجهة المُعرَّفة في ملف .h المُوَلَّد.

الأسلوب القديم
JNI (واجهة Java الأصيلة)
الأسلوب الحديث
FFM (واجهة برمجة الدوال الخارجية والذاكرة)
منذ JDK
22
الصعوبة
متقدم
استدعاء كود C من Java
متاح

تم توحيده في JDK 22 (مارس 2024)؛ كان في مرحلة الحضانة منذ JDK 14

تمتلك Java نهجين لاستدعاء كود C/C++ الأصيل: JNI التقليدي وواجهة FFM الحديثة. مع JNI، تُعلن عن الدالة بوصفها native، ثم تُشغّل javac -h لتوليد ملف ترويسة C، وتُنفّذ الدالة باستخدام JNI C API المعقّدة (JNIEnv وjstring وما إلى ذلك). تُزيل FFM المُقدَّمة كواجهة برمجة قياسية في Java 22 كل ذلك: كود C يبقى C عادياً — دون الحاجة لاتفاقيات JNI. هذا يُسهّل استدعاء مكتبات C/C++ الموجودة دون تعديل. يستخدم الجانب Java كائن Arena لإدارة الذاكرة خارج الكومة بأمان، وMethodHandle للاستدعاء النازل، مما يضمن المرونة والأمان.