Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions content/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
id: 113
slug: "call-c-from-java"
title: "Calling out to C code from Java"
category: "language"
difficulty: "advanced"
jdkVersion: "22"
oldLabel: "Java 1.1+"
modernLabel: "Java 22+"
oldApproach: "JNI (Java Native Interface)"
modernApproach: "FFM (Foreign Function & Memory API)"
oldCode: |-
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;
// }
modernCode: |-
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"));
IO.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;
// }
summary: "FFM lets Java call C libraries directly, without JNI boilerplate or C-side Java knowledge."
explanation: "Java has two approaches for calling native C/C++ code: the traditional\
\ JNI and the modern FFM API. With JNI, you declare a method as native, run javac -h\
\ to generate a C header file, then implement the function using the cumbersome JNI\
\ C API (JNIEnv, jstring, etc.). FFM, introduced as a standard API in Java 22,\
\ eliminates all of that: C code is just plain C — no JNI conventions needed. This\
\ makes it far easier to call existing C/C++ libraries without modification. The\
\ Java side uses Arena for safe off-heap memory management and MethodHandle for the\
\ downcall, ensuring both flexibility and safety."
whyModernWins:
- icon: "👁"
title: "C code stays plain C"
desc: "The C function requires no JNI annotations or JNIEnv boilerplate — any existing C library can be called as-is."
- icon: ""
title: "More flexible"
desc: "Directly call most existing C/C++ libraries without writing adapter code or generating header files."
- icon: "🛠️"
title: "Easier workflow"
desc: "No need to stop, run javac -h, and implement the interface defined in the generated .h file."
support:
state: "available"
description: "Standardized in JDK 22 (March 2024); previously incubating since JDK 14"
prev: "language/compact-canonical-constructor"
next: "enterprise/servlet-vs-jaxrs"
related:
- "io/file-memory-mapping"
- "language/compact-source-files"
- "language/unnamed-variables"
docs:
- title: "JEP 454: Foreign Function & Memory API"
href: "https://openjdk.org/jeps/454"
- title: "java.lang.foreign package (Java 22)"
href: "https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/foreign/package-summary.html"
2 changes: 1 addition & 1 deletion content/language/compact-canonical-constructor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ support:
state: "available"
description: "Widely available since JDK 16 (March 2021)"
prev: "language/static-members-in-inner-classes"
next: "enterprise/servlet-vs-jaxrs"
next: "language/call-c-from-java"
related:
- "language/records-for-data-classes"
- "language/flexible-constructor-bodies"
Expand Down
17 changes: 17 additions & 0 deletions translations/content/ar/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "استدعاء كود C من Java"
oldApproach: "JNI (واجهة Java الأصيلة)"
modernApproach: "FFM (واجهة برمجة الدوال الخارجية والذاكرة)"
summary: "تتيح FFM لـ Java استدعاء مكتبات C مباشرةً، دون الحاجة إلى كليشيهات JNI أو معرفة Java على جانب C."
explanation: "تمتلك 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 للاستدعاء النازل، مما يضمن المرونة والأمان."
whyModernWins:
- icon: "👁"
title: "كود C يبقى C نقياً"
desc: "لا تحتاج دالة C إلى تعليقات JNI أو كليشيهات JNIEnv — يمكن استدعاء أي مكتبة C موجودة مباشرةً."
- icon: ""
title: "أكثر مرونة"
desc: "استدعِ معظم مكتبات C/C++ الموجودة مباشرةً دون كتابة كود محوّل أو توليد ملفات ترويسة."
- icon: "🛠️"
title: "سير عمل أسهل"
desc: "لا حاجة للتوقف وتشغيل javac -h وتنفيذ الواجهة المُعرَّفة في ملف .h المُوَلَّد."
support:
description: "تم توحيده في JDK 22 (مارس 2024)؛ كان في مرحلة الحضانة منذ JDK 14"
17 changes: 17 additions & 0 deletions translations/content/bn/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: Java থেকে C কোড কল করা
oldApproach: JNI (Java Native Interface)
modernApproach: FFM (Foreign Function & Memory API)
summary: FFM জাভাকে JNI বয়লারপ্লেট বা C-সাইডে Java জ্ঞান ছাড়াই সরাসরি C লাইব্রেরি কল করতে দেয়।
explanation: "Java-তে নেটিভ C/C++ কোড কল করার দুটি পদ্ধতি রয়েছে: ঐতিহ্যগত JNI এবং আধুনিক FFM API। JNI-এর সাথে, আপনি একটি মেথড native হিসেবে ঘোষণা করেন, C হেডার ফাইল তৈরি করতে javac -h চালান, তারপর কষ্টকর JNI C API (JNIEnv, jstring ইত্যাদি) ব্যবহার করে ফাংশন ইমপ্লিমেন্ট করেন। Java 22-এ স্ট্যান্ডার্ড API হিসেবে প্রবর্তিত FFM এই সব বাদ দেয়: C কোড শুধু সাধারণ C — কোনো JNI কনভেনশন প্রয়োজন নেই। এটি পরিবর্তন ছাড়াই বিদ্যমান C/C++ লাইব্রেরি কল করা অনেক সহজ করে তোলে। Java সাইড নিরাপদ অফ-হিপ মেমরি ম্যানেজমেন্টের জন্য Arena এবং ডাউনকলের জন্য MethodHandle ব্যবহার করে, যা নমনীয়তা এবং নিরাপত্তা উভয়ই নিশ্চিত করে।"
whyModernWins:
- icon: "👁"
title: C কোড সাদামাটা C-ই থাকে
desc: C ফাংশনে কোনো JNI অ্যানোটেশন বা JNIEnv বয়লারপ্লেট প্রয়োজন নেই — যেকোনো বিদ্যমান C লাইব্রেরি যেমন আছে তেমনি কল করা যায়।
- icon: ""
title: আরও নমনীয়
desc: অ্যাডাপ্টার কোড লেখা বা হেডার ফাইল তৈরি না করেই বেশিরভাগ বিদ্যমান C/C++ লাইব্রেরি সরাসরি কল করুন।
- icon: "🛠️"
title: সহজতর ওয়ার্কফ্লো
desc: "থামার, javac -h চালানোর এবং জেনারেটেড .h ফাইলে সংজ্ঞায়িত ইন্টারফেস ইমপ্লিমেন্ট করার প্রয়োজন নেই।"
support:
description: JDK 22-এ মানসম্পন্ন (মার্চ 2024); পূর্বে JDK 14 থেকে ইনকিউবেটিং
17 changes: 17 additions & 0 deletions translations/content/de/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "C-Code aus Java aufrufen"
oldApproach: "JNI (Java Native Interface)"
modernApproach: "FFM (Foreign Function & Memory API)"
summary: "FFM ermöglicht es Java, C-Bibliotheken direkt aufzurufen, ohne JNI-Boilerplate oder Java-Kenntnisse auf der C-Seite."
explanation: "Java bietet zwei Ansätze zum Aufrufen von nativem C/C++-Code: das traditionelle JNI und die moderne FFM API. Bei JNI deklarieren Sie eine Methode als native, führen javac -h aus, um eine C-Header-Datei zu generieren, und implementieren die Funktion mit der umständlichen JNI-C-API (JNIEnv, jstring usw.). FFM, als Standard-API in Java 22 eingeführt, eliminiert all das: C-Code bleibt reines C — keine JNI-Konventionen erforderlich. Dies macht es viel einfacher, bestehende C/C++-Bibliotheken ohne Änderungen aufzurufen. Die Java-Seite verwendet Arena für sicheres Off-Heap-Speichermanagement und MethodHandle für den Downcall, was sowohl Flexibilität als auch Sicherheit gewährleistet."
whyModernWins:
- icon: "👁"
title: "C-Code bleibt reines C"
desc: "Die C-Funktion benötigt keine JNI-Annotationen oder JNIEnv-Boilerplate — jede vorhandene C-Bibliothek kann direkt aufgerufen werden."
- icon: ""
title: "Flexibler"
desc: "Die meisten vorhandenen C/C++-Bibliotheken können direkt aufgerufen werden, ohne Adaptercode zu schreiben oder Header-Dateien zu generieren."
- icon: "🛠️"
title: "Einfacherer Workflow"
desc: "Kein Stoppen, kein Ausführen von javac -h und kein Implementieren der in der generierten .h-Datei definierten Schnittstelle."
support:
description: "In JDK 22 standardisiert (März 2024); zuvor seit JDK 14 in der Inkubationsphase"
17 changes: 17 additions & 0 deletions translations/content/es/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: Llamar a código C desde Java
oldApproach: JNI (Java Native Interface)
modernApproach: FFM (Foreign Function & Memory API)
summary: FFM permite a Java llamar directamente a bibliotecas C sin el código repetitivo de JNI ni conocimiento de Java en el lado C.
explanation: "Java tiene dos enfoques para llamar a código nativo C/C++: el tradicional JNI y la moderna API FFM. Con JNI, se declara un método como native, se ejecuta javac -h para generar un archivo de encabezado C y se implementa la función usando la complicada API JNI de C (JNIEnv, jstring, etc.). FFM, introducida como API estándar en Java 22, elimina todo eso: el código C es simplemente C puro — sin necesidad de convenciones JNI. Esto facilita mucho la llamada a bibliotecas C/C++ existentes sin modificaciones. El lado Java usa Arena para la gestión segura de memoria fuera del heap y MethodHandle para el downcall, garantizando flexibilidad y seguridad."
whyModernWins:
- icon: "👁"
title: El código C permanece como C puro
desc: "La función C no requiere anotaciones JNI ni código JNIEnv repetitivo — cualquier biblioteca C existente puede llamarse tal cual."
- icon: ""
title: Más flexible
desc: "Llama directamente a la mayoría de las bibliotecas C/C++ existentes sin escribir código adaptador ni generar archivos de encabezado."
- icon: "🛠️"
title: Flujo de trabajo más sencillo
desc: "No es necesario detenerse, ejecutar javac -h e implementar la interfaz definida en el archivo .h generado."
support:
description: Estandarizado en JDK 22 (marzo 2024); anteriormente en incubación desde JDK 14
17 changes: 17 additions & 0 deletions translations/content/fr/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: Appeler du code C depuis Java
oldApproach: JNI (Java Native Interface)
modernApproach: FFM (Foreign Function & Memory API)
summary: FFM permet à Java d'appeler directement des bibliothèques C, sans code répétitif JNI ni connaissance de Java côté C.
explanation: "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é."
whyModernWins:
- icon: "👁"
title: Le code C reste du C pur
desc: "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."
- icon: ""
title: Plus flexible
desc: "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."
- icon: "🛠️"
title: Workflow simplifié
desc: "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é."
support:
description: Standardisé dans JDK 22 (mars 2024) ; auparavant en incubation depuis JDK 14
17 changes: 17 additions & 0 deletions translations/content/it/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: Chiamare codice C da Java
oldApproach: JNI (Java Native Interface)
modernApproach: FFM (Foreign Function & Memory API)
summary: "FFM consente a Java di chiamare direttamente librerie C, senza boilerplate JNI né conoscenza di Java lato C."
explanation: "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."
whyModernWins:
- icon: "👁"
title: Il codice C rimane C puro
desc: "La funzione C non richiede annotazioni JNI né boilerplate JNIEnv — qualsiasi libreria C esistente può essere chiamata così com'è."
- icon: ""
title: Più flessibile
desc: "Chiama direttamente la maggior parte delle librerie C/C++ esistenti senza scrivere codice adattatore né generare file di intestazione."
- icon: "🛠️"
title: Flusso di lavoro più semplice
desc: "Nessuna necessità di fermarsi, eseguire javac -h e implementare l'interfaccia definita nel file .h generato."
support:
description: Standardizzato in JDK 22 (marzo 2024); precedentemente in incubazione da JDK 14
17 changes: 17 additions & 0 deletions translations/content/ja/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: JavaからCコードを呼び出す
oldApproach: JNI(Java Native Interface)
modernApproach: FFM(Foreign Function & Memory API)
summary: "FFMを使えば、JNIのボイラープレートやC側でのJavaの知識なしに、JavaからCライブラリを直接呼び出せる。"
explanation: "Javaにはネイティブな C/C++ コードを呼び出す2つのアプローチがあります:従来のJNIとモダンなFFM APIです。JNIでは、メソッドをnativeとして宣言し、javac -hを実行してCヘッダーファイルを生成し、煩雑なJNI C API(JNIEnv、jstringなど)を使って関数を実装する必要があります。Java 22で標準APIとして導入されたFFMは、そのすべてを不要にします:Cコードはただの普通のC — JNIの慣例は不要です。これにより、既存のC/C++ライブラリを変更なしに呼び出すことがはるかに容易になります。Javaサイドでは、安全なオフヒープメモリ管理にArenaを、ダウンコールにMethodHandleを使用し、柔軟性と安全性の両方を確保します。"
whyModernWins:
- icon: "👁"
title: Cコードは普通のCのまま
desc: "C関数にJNIアノテーションもJNIEnvのボイラープレートも不要 — 既存のCライブラリをそのまま呼び出せます。"
- icon: ""
title: より柔軟
desc: "アダプターコードを書いたりヘッダーファイルを生成したりせずに、ほとんどの既存C/C++ライブラリを直接呼び出せます。"
- icon: "🛠️"
title: ワークフローが簡単
desc: "javac -hを実行して生成された.hファイルで定義されたインターフェースを実装するために作業を止める必要がありません。"
support:
description: JDK 22で標準化(2024年3月);JDK 14からインキュベーション中
17 changes: 17 additions & 0 deletions translations/content/ko/language/call-c-from-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "Java에서 C 코드 호출하기"
oldApproach: "JNI (Java Native Interface)"
modernApproach: "FFM (Foreign Function & Memory API)"
summary: "FFM은 JNI 보일러플레이트나 C 측의 Java 지식 없이 Java가 C 라이브러리를 직접 호출할 수 있게 합니다."
explanation: "Java에는 네이티브 C/C++ 코드를 호출하는 두 가지 접근 방식이 있습니다: 전통적인 JNI와 현대적인 FFM API입니다. JNI를 사용하면 메서드를 native로 선언하고, javac -h를 실행하여 C 헤더 파일을 생성한 다음, 번거로운 JNI C API(JNIEnv, jstring 등)를 사용하여 함수를 구현해야 합니다. Java 22에서 표준 API로 도입된 FFM은 이 모든 것을 없애줍니다: C 코드는 그냥 순수한 C — JNI 규약이 필요 없습니다. 이를 통해 기존 C/C++ 라이브러리를 수정 없이 훨씬 쉽게 호출할 수 있습니다. Java 측에서는 안전한 오프힙 메모리 관리를 위해 Arena를, 다운콜을 위해 MethodHandle을 사용하여 유연성과 안전성을 모두 보장합니다."
whyModernWins:
- icon: "👁"
title: "C 코드는 순수한 C 그대로"
desc: "C 함수에는 JNI 어노테이션이나 JNIEnv 보일러플레이트가 필요 없습니다 — 기존 C 라이브러리를 그대로 호출할 수 있습니다."
- icon: ""
title: "더 유연함"
desc: "어댑터 코드를 작성하거나 헤더 파일을 생성하지 않고도 대부분의 기존 C/C++ 라이브러리를 직접 호출할 수 있습니다."
- icon: "🛠️"
title: "더 쉬운 워크플로"
desc: "멈춰서 javac -h를 실행하고 생성된 .h 파일에 정의된 인터페이스를 구현할 필요가 없습니다."
support:
description: "JDK 22에서 표준화됨 (2024년 3월); 이전에는 JDK 14부터 인큐베이팅"
Loading