|
|
Java Native Interface Programming |
Similar tojstring,jarrayrepresents 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
GetIntArrayElementsto 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
GetIntArrayElementspoints 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; }ReleaseIntArrayElementsenables the JNI to copy back and freebodyif it is a copy of the original Java array, or "unpin" the Java array if it has been pinned in memory. Forgetting to callReleaseIntArrayElementsresults 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:
GetBooleanArrayElementsaccesses elements in a Java boolean array.GetByteArrayElementsaccesses elements in a Java byte array.GetCharArrayElementsaccesses elements in a char array.GetShortArrayElementsaccesses elements in a short array.GetIntArrayElementsaccesses elements in an int array.GetLongArrayElementsaccesses elements in a long array.GetFloatArrayElementsaccesses elements in a float array.GetDoubleArrayElementsaccesses elements in a double array.Accessing a Small Number of Elements
Note that the
Get<type>ArrayElementsfunction 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>ArrayRegionfunctions. 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.
GetObjectArrayElementreturns the object element at a given index.SetObjectArrayElementupdates the object element at a given index.
|
|
Java Native Interface Programming |