| Java Native Interface Programming

## Accessing Java Arrays

> Similar to `jstring`, `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 call `ReleaseIntArrayElements`, as follows:

>       (*env)->ReleaseIntArrayElements(env, arr, body, 0);
>       return sum;
>     }

> `ReleaseIntArrayElements` enables the JNI to copy back and free `body` if it is a copy of the original Java array, or "unpin" the Java array if it has been pinned in memory. Forgetting to call `ReleaseIntArrayElements` 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 the `Get/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