JNI 数组

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,C++,c,jni,Access)