{"id":627,"date":"2025-09-14T13:19:38","date_gmt":"2025-09-14T12:19:38","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=627"},"modified":"2025-10-01T13:22:11","modified_gmt":"2025-10-01T12:22:11","slug":"nutzung-von-arrays-in-jni","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=627","title":{"rendered":"Nutzung von Arrays in JNI"},"content":{"rendered":"\n<p>Das Java Native Interface (JNI) erm\u00f6glicht Java-Programmen die Interaktion mit nativem Code, meist in C oder C++. Diese Schnittstelle ist besonders dann wichtig, wenn Leistungskritische Operationen oder der Zugriff auf Plattformfunktionen erforderlich sind, die Java selbst nicht direkt bereitstellt. Ein h\u00e4ufiger Anwendungsfall in JNI ist die Arbeit mit Arrays, da Daten h\u00e4ufig in Form von Arrays zwischen Java und nativem Code ausgetauscht werden. Arrays in JNI zu handhaben erfordert jedoch besondere Sorgfalt, da Java-Arrays verwaltet werden und Garbage Collection unterliegen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Grundlegendes zu Arrays in JNI<\/strong><\/h2>\n\n\n\n<p>In Java gibt es primitive Arrays (z.B. int[], float[]) und Objektarrays (String[], Object[]). JNI unterscheidet diese und stellt f\u00fcr jede Art spezifische Funktionen zur Verf\u00fcgung. Alle JNI-Arraytypen sind Subtypen von jarray. Zu den wichtigsten Arraytypen geh\u00f6ren:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>jintArray f\u00fcr int[]<\/li>\n\n\n\n<li>jfloatArray f\u00fcr float[]<\/li>\n\n\n\n<li>jdoubleArray f\u00fcr double[]<\/li>\n\n\n\n<li>jbyteArray f\u00fcr byte[]<\/li>\n\n\n\n<li>jcharArray f\u00fcr char[]<\/li>\n\n\n\n<li>jbooleanArray f\u00fcr boolean[]<\/li>\n\n\n\n<li>jobjectArray f\u00fcr beliebige Objektarrays (Object[])<\/li>\n<\/ul>\n\n\n\n<p>Arrays in JNI werden \u00fcber Zeiger auf interne JVM-Strukturen repr\u00e4sentiert. Das bedeutet, dass man in C\/C++ nicht direkt auf den Speicher wie in nativen Arrays zugreifen kann, sondern JNI-Funktionen verwenden muss, um die Daten zu lesen oder zu schreiben.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Zugriff auf Arrayelemente<\/strong><\/h2>\n\n\n\n<p>JNI bietet zwei grundlegende Methoden, um auf Arrayelemente zuzugreifen:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Copy-Methode<\/strong>: Das Array wird kopiert, und \u00c4nderungen m\u00fcssen explizit zur\u00fcckgeschrieben werden.<\/li>\n\n\n\n<li><strong>Direct-Access-Methode<\/strong>: Es wird ein Zeiger auf die Elemente des Arrays zur\u00fcckgegeben, der direkten Zugriff erm\u00f6glicht. Der Speicher bleibt jedoch weiterhin unter Kontrolle der JVM.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Beispiel f\u00fcr ein<\/strong> <strong>int[]<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">JNIEXPORT void JNICALL Java_MyClass_processArray\n  (JNIEnv *env, jobject obj, jintArray <span class=\"hljs-keyword\">array<\/span>) {\n\n    <span class=\"hljs-comment\">\/\/ Array-L\u00e4nge ermitteln<\/span>\n    jsize length = (*env)-&gt;GetArrayLength(env, <span class=\"hljs-keyword\">array<\/span>);\n\n    <span class=\"hljs-comment\">\/\/ Zugriff auf die Elemente (Copy)<\/span>\n    jint *elements = (*env)-&gt;GetIntArrayElements(env, <span class=\"hljs-keyword\">array<\/span>, <span class=\"hljs-keyword\">NULL<\/span>);\n    <span class=\"hljs-keyword\">if<\/span> (elements == <span class=\"hljs-keyword\">NULL<\/span>) <span class=\"hljs-keyword\">return<\/span>; <span class=\"hljs-comment\">\/\/ Fehlerbehandlung<\/span>\n\n    <span class=\"hljs-comment\">\/\/ Verarbeitung<\/span>\n    <span class=\"hljs-keyword\">for<\/span> (jsize i = <span class=\"hljs-number\">0<\/span>; i &lt; length; i++) {\n        elements&#91;i] *= <span class=\"hljs-number\">2<\/span>; <span class=\"hljs-comment\">\/\/ Beispiel: alle Werte verdoppeln<\/span>\n    }\n\n    <span class=\"hljs-comment\">\/\/ \u00c4nderungen zur\u00fcckschreiben und Speicher freigeben<\/span>\n    (*env)-&gt;ReleaseIntArrayElements(env, <span class=\"hljs-keyword\">array<\/span>, elements, <span class=\"hljs-number\">0<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Parameter von ReleaseIntArrayElements:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>0: \u00c4nderungen \u00fcbernehmen und Speicher freigeben.<\/li>\n\n\n\n<li>JNI_ABORT: \u00c4nderungen verwerfen, Speicher freigeben.<\/li>\n\n\n\n<li>JNI_COMMIT: \u00c4nderungen \u00fcbernehmen, Speicher aber noch nicht freigeben.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Direktes Arbeiten ohne Kopie<\/strong><\/h3>\n\n\n\n<p>F\u00fcr sehr gro\u00dfe Arrays oder Performance-kritische Anwendungen kann GetPrimitiveArrayCritical verwendet werden, um unn\u00f6tige Kopien zu vermeiden. Dabei muss jedoch der Zugriff sehr schnell erfolgen, da die JVM w\u00e4hrenddessen m\u00f6glicherweise die Garbage Collection pausiert.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">jint *data = (*env)-&gt;GetPrimitiveArrayCritical(env, <span class=\"hljs-keyword\">array<\/span>, <span class=\"hljs-keyword\">NULL<\/span>);\n<span class=\"hljs-comment\">\/\/ Verarbeitung<\/span>\n(*env)-&gt;ReleasePrimitiveArrayCritical(env, <span class=\"hljs-keyword\">array<\/span>, data, <span class=\"hljs-number\">0<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\"><strong>Arbeiten mit Objektarrays<\/strong><\/h2>\n\n\n\n<p>Objektarrays (jobjectArray) erfordern besondere Aufmerksamkeit, da die Elemente selbst Objekte sind. Man greift \u00fcber GetObjectArrayElement auf einzelne Elemente zu und muss diese nach der Nutzung mit DeleteLocalRef freigeben, um den lokalen Referenz-Cache nicht zu \u00fcberlaufen.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">JNIEXPORT void JNICALL Java_MyClass_printStrings\n  (JNIEnv *env, jobject obj, jobjectArray <span class=\"hljs-keyword\">array<\/span>) {\n\n    jsize length = (*env)-&gt;GetArrayLength(env, <span class=\"hljs-keyword\">array<\/span>);\n\n    <span class=\"hljs-keyword\">for<\/span> (jsize i = <span class=\"hljs-number\">0<\/span>; i &lt; length; i++) {\n        jstring str = (jstring)(*env)-&gt;GetObjectArrayElement(env, <span class=\"hljs-keyword\">array<\/span>, i);\n\n        <span class=\"hljs-keyword\">const<\/span> char *cstr = (*env)-&gt;GetStringUTFChars(env, str, <span class=\"hljs-keyword\">NULL<\/span>);\n        printf(<span class=\"hljs-string\">\"%s\\n\"<\/span>, cstr);\n        (*env)-&gt;ReleaseStringUTFChars(env, str, cstr);\n\n        (*env)-&gt;DeleteLocalRef(env, str);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\"><strong>Erstellung von Arrays in JNI<\/strong><\/h2>\n\n\n\n<p>JNI erlaubt es auch, neue Arrays im nativen Code zu erstellen und an Java zur\u00fcckzugeben:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">JNIEXPORT jintArray JNICALL Java_MyClass_createArray\n  (JNIEnv *env, jobject obj, jint size) {\n\n    jintArray <span class=\"hljs-keyword\">array<\/span> = (*env)-&gt;NewIntArray(env, size);\n    <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">array<\/span> == <span class=\"hljs-keyword\">NULL<\/span>) <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">NULL<\/span>; <span class=\"hljs-comment\">\/\/ Fehler<\/span>\n\n    jint fill&#91;size];\n    <span class=\"hljs-keyword\">for<\/span> (int i = <span class=\"hljs-number\">0<\/span>; i &lt; size; i++) fill&#91;i] = i;\n\n    (*env)-&gt;SetIntArrayRegion(env, <span class=\"hljs-keyword\">array<\/span>, <span class=\"hljs-number\">0<\/span>, size, fill);\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">array<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>F\u00fcr Objektarrays muss zus\u00e4tzlich die Klasse des Elements angegeben werden:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">jclass cls = (*env)-&gt;FindClass(env, <span class=\"hljs-string\">\"java\/lang\/String\"<\/span>);\njobjectArray <span class=\"hljs-keyword\">array<\/span> = (*env)-&gt;NewObjectArray(env, size, cls, <span class=\"hljs-keyword\">NULL<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\"><strong>Wichtige Best Practices<\/strong><\/h2>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Lokale Referenzen freigeben<\/strong>: JNI speichert lokale Referenzen pro Thread; zu viele Referenzen f\u00fchren zu einem Speicher\u00fcberlauf.<\/li>\n\n\n\n<li><strong>Korrektes Freigeben von Speicher<\/strong>: Bei Get*ArrayElements oder GetPrimitiveArrayCritical muss Release* immer aufgerufen werden.<\/li>\n\n\n\n<li><strong>Performance beachten<\/strong>: F\u00fcr gro\u00dfe Arrays oder intensive Verarbeitung Direct-Access-Methoden bevorzugen.<\/li>\n\n\n\n<li><strong>Thread-Sicherheit<\/strong>: JNI-Aufrufe sollten nur von Threads erfolgen, die korrekt an die JVM gebunden sind.<\/li>\n\n\n\n<li><\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th><strong>JNI-Funktion<\/strong><\/th><th><strong>Beschreibung<\/strong><\/th><\/tr><\/thead><tbody><tr><td>GetArrayLength(JNIEnv*, jarray)<\/td><td>Gibt die L\u00e4nge eines Arrays zur\u00fcck. Funktioniert f\u00fcr alle Arraytypen.<\/td><\/tr><tr><td>GetIntArrayElements(JNIEnv*, jintArray, jboolean*)<\/td><td>Liefert einen Zeiger auf die Elemente eines int[]. \u00c4nderungen k\u00f6nnen zur\u00fcckgeschrieben werden.<\/td><\/tr><tr><td>ReleaseIntArrayElements(JNIEnv*, jintArray, jint*, jint)<\/td><td>Gibt die Elemente frei. Parameter steuern, ob \u00c4nderungen \u00fcbernommen werden (0), verworfen werden (JNI_ABORT) oder \u00fcbernommen, aber Speicher nicht freigegeben wird (JNI_COMMIT).<\/td><\/tr><tr><td>GetPrimitiveArrayCritical(JNIEnv*, jarray, jboolean*)<\/td><td>Liefert direkten Zugriff auf ein primitives Array ohne Kopie. Schneller, aber die JVM kann nicht garbage-collecten, solange das Array gesperrt ist.<\/td><\/tr><tr><td>ReleasePrimitiveArrayCritical(JNIEnv*, jarray, void*, jint)<\/td><td>Gibt ein mit GetPrimitiveArrayCritical gesperrtes Array frei.<\/td><\/tr><tr><td>GetObjectArrayElement(JNIEnv*, jobjectArray, jsize)<\/td><td>Liefert ein einzelnes Objekt aus einem Objektarray (Object[]).<\/td><\/tr><tr><td>SetObjectArrayElement(JNIEnv*, jobjectArray, jsize, jobject)<\/td><td>Setzt ein Element in einem Objektarray.<\/td><\/tr><tr><td>NewIntArray(JNIEnv*, jsize)<\/td><td>Erstellt ein neues int[] in der JVM.<\/td><\/tr><tr><td>SetIntArrayRegion(JNIEnv*, jintArray, jsize start, jsize len, const jint* buf)<\/td><td>Kopiert einen Block von Werten in ein Array.<\/td><\/tr><tr><td>NewObjectArray(JNIEnv*, jsize, jclass, jobject initialElement)<\/td><td>Erstellt ein neues Objektarray (Object[]) mit optionalem Initialelement.<\/td><\/tr><tr><td>GetStringUTFChars(JNIEnv*, jstring, jboolean*)<\/td><td>Liefert ein UTF-8-C-String-Pendant zu einem Java-String. Muss mit ReleaseStringUTFChars freigegeben werden.<\/td><\/tr><tr><td>ReleaseStringUTFChars(JNIEnv*, jstring, const char*)<\/td><td>Gibt den von GetStringUTFChars erhaltenen Speicher frei.<\/td><\/tr><tr><td>DeleteLocalRef(JNIEnv*, jobject)<\/td><td>L\u00f6scht eine lokale Referenz, um den Referenz-Cache der JVM nicht zu \u00fcberlasten.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Diese Tabelle fasst die wichtigsten Funktionen zusammen und zeigt, welche f\u00fcr <strong>primitive Arrays<\/strong> und welche f\u00fcr <strong>Objektarrays<\/strong> relevant sind.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Fazit<\/strong><\/h2>\n\n\n\n<p>Die Arbeit mit Arrays in JNI ist zentral f\u00fcr effiziente native Java-Erweiterungen. W\u00e4hrend primitive Arrays \u00fcber spezialisierte Funktionen schnell bearbeitet werden k\u00f6nnen, erfordern Objektarrays besondere Vorsicht hinsichtlich Referenzmanagement. Durch das Verst\u00e4ndnis der Copy- und Direct-Access-Methoden, gepaart mit sauberem Speicher- und Referenzhandling, lassen sich sichere und performante JNI-Module entwickeln. Wer JNI korrekt einsetzt, kann die Vorteile nativer Performance nutzen, ohne die Sicherheit und Stabilit\u00e4t der Java-Laufzeitumgebung zu gef\u00e4hrden.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das Java Native Interface (JNI) erm\u00f6glicht Java-Programmen die Interaktion mit nativem Code, meist in C oder C++. Diese Schnittstelle ist besonders dann wichtig, wenn Leistungskritische Operationen oder der Zugriff auf Plattformfunktionen erforderlich sind, die Java selbst nicht direkt bereitstellt. Ein h\u00e4ufiger Anwendungsfall in JNI ist die Arbeit mit Arrays, da Daten h\u00e4ufig in Form von [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-627","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=627"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/627\/revisions"}],"predecessor-version":[{"id":628,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/627\/revisions\/628"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}