Use arraysTag(s): JNI


JNI provides special functions (relative to the type) to access Java arrays.

This example returns the maximum of an int array.

JNIEXPORT jint JNICALL Java_JavaHowTo_max
   (JNIEnv * env, jclass obj, jintArray arr)  {
  int i;
  jsize len = env->GetArrayLength(arr, max = -1;
  jint *body = env->GetIntArrayElements(arr, 0);
  for (max = body[0], i=1; i < len; i++)
    if (max < body[i]) max = body[i];
  env->ReleaseIntArrayElements(arr, body, 0);
  return max;
}
The Java wrapper
class JavaHowTo {
    public static native int max(int [] t);
    static {
        System.loadLibrary("javahowto");
    }
}
The test program
class JNIJavaHowTo {
    public static void main(String[] args) {
        int [] myArray = {4, 7, 5, 9, 2, 0, 1};
        System.out.println(JavaHowTo.max(myArray));
    }
}

Thanks to H. Horn for the following HowTo
Without passing the array directly to the JNI function, it's possible to fetch directly from the class the array.

Note that to get the reflection stuff working, the native method (printArrayR) could'nt be static.

The Java code

class JNIHowTo {
  private static native void printArray (int[] t); // print an int[] array
  private native void printArrayR (); // print int[] array 'myArray' via reflection

  static {
    System.loadLibrary("javahowto");
  }

  private int[] myArray = { 4, 7, 5, 9, 2, 0, 1 };
  public static void main (String[] args) {
    JNIHowTo jht = new JNIHowTo();
    printArray(jht.myArray); // print 'myArray'
    jht.printArrayR(); // print 'myArray' via reflection
  }
}
The JNI code (tested on 64bit Windows / Java 6u24 64bit using mingw 64bit cross compiler (x86_64-w64-mingw32-gcc).
#include "JNIHowTo.h"

JNIEXPORT void JNICALL Java_JNIHowTo_printArray
       (JNIEnv* env, jclass obj, jintArray arr) {
  jsize len = (*env)->GetArrayLength(env, arr);
  printf("int[] : [");
  if (len > 0) {
    jboolean iscopy;
    jint* tab = (*env)->GetIntArrayElements(env, arr, &iscopy);
    for (int i = 0; i < len ; i++) printf(" %d", (int)tab[i]);
    if (iscopy == JNI_TRUE) (*env)->ReleaseIntArrayElements(env, arr, tab, JNI_ABORT);
  }
  printf(" ]\n"); fflush(stdout);
}

JNIEXPORT void JNICALL Java_JNIHowTo_printArrayR (JNIEnv* env, jclass obj) {
  jclass   cls = (*env)->GetObjectClass(env, obj);
  jfieldID fid = (*env)->GetFieldID(env, cls, "myArray", "[I");
  if (fid) {
    jobject arr = (*env)->GetObjectField(env, obj, fid);
    jsize   len = (*env)->GetArrayLength(env, arr);
    printf("via reflection:\nint[] : [");
    if (len > 0) {
      jboolean iscopy;
      jint* tab = (*env)->GetIntArrayElements(env, arr, &iscopy);
      for (int i = 0; i < len ; i++) printf(" %d", (int)tab[i]);
      if (iscopy == JNI_TRUE) (*env)->ReleaseIntArrayElements(env, arr, tab, JNI_ABORT);
    }
    printf(" ]\n"); fflush(stdout);
  }
}

blog comments powered by Disqus