Java Native Interface Programming |
Similar tojstring
,jarray
represents references to Java arrays and cannot be directly accessed in C. Our second example,IntArray.java
, contains a native method that totals up the contents of an integer array. You cannot implement the native method by directly addressing the array elements:/* This program is illegal! */ JNIEXPORT jint JNICALL Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr) { int i, sum = 0; for (i=0; i<10; i++) sum += arr[i];Instead, the JNI provides functions that allow you to obtain pointers to elements of integer arrays. The correct way to implement the above function is shown in the native method IntArray.c .
Accessing Arrays of Primitive Elements
First, obtain the length of the array by calling the JNI function
GetArrayLength
. Note that, unlike C arrays, Java arrays carry length information.JNIEXPORT jint JNICALL Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr) { int i, sum = 0; jsize len = (*env)->GetArrayLength(env, arr);Next, obtain a pointer to the elements of the integer array. Our example uses
GetIntArrayElements
to obtain this pointer. You can use normal C operations on the resulting integer array.jint *body = (*env)->GetIntArrayElements(env, arr, 0); for (i=0; i<len; i++) sum += body[i];While, in general, Java arrays may be moved by the garbage collector, the Virtual Machine guarantees that the result of
GetIntArrayElements
points to a nonmovable array of integers. The JNI will either "pin" down the array , or it will make a copy of the array into nonmovable memory. When the native code has finished using the array, it must callReleaseIntArrayElements
, as follows:(*env)->ReleaseIntArrayElements(env, arr, body, 0); return sum; }ReleaseIntArrayElements
enables the JNI to copy back and freebody
if it is a copy of the original Java array, or "unpin" the Java array if it has been pinned in memory. Forgetting to callReleaseIntArrayElements
results in either pinning the array for an extended period of time, or not being able to reclaim the memory used to store the nonmovable copy of the array.The JNI provides a set of functions to access arrays of every primitive type, including boolean, byte, char, short, int, long, float, and double:
GetBooleanArrayElements
accesses elements in a Java boolean array.GetByteArrayElements
accesses elements in a Java byte array.GetCharArrayElements
accesses elements in a char array.GetShortArrayElements
accesses elements in a short array.GetIntArrayElements
accesses elements in an int array.GetLongArrayElements
accesses elements in a long array.GetFloatArrayElements
accesses elements in a float array.GetDoubleArrayElements
accesses elements in a double array.Accessing a Small Number of Elements
Note that the
Get<type>ArrayElements
function might result in the entire array being copied. If you are only interested in a small number of elements in a (potentially) large array, you should instead use theGet/Set<type>ArrayRegion
functions. These functions allow you to access, via copying, a small set of elements in an array.Accessing Arrays of Objects
The JNI provides a separate set of function to access elements of object arrays. You can get and set individual object array elements. You cannot get all the object array elements at once.
GetObjectArrayElement
returns the object element at a given index.SetObjectArrayElement
updates the object element at a given index.
Java Native Interface Programming |