Array of array in JNI

I have a problem that I've been stuck on for the last few days. I can get one array back from JNI side to java side, but I couldn't get two dimension array back from JNI to JAVA side
JNI side
JNIEXPORT jint JNICALL Java_JNITest_TestCall
(JNIEnv *env, jclass instance, jobject outJava)
OutStruct outObj; // local structure that the C function fills in
jintArray row_flags = (jintArray)(*env)->NewIntArray(env, 5);
jobjectArray arrayOfArrays_tmp = (jobjectArray)(*env)->NewObjectArray(env, 3, (*env)->GetObjectClass(env, row_flags), 0);
jintArray intArr_tmp = (*env)->NewIntArray(env, 5);
jclass objClass = (*env)->GetObjectClass(env,outJava);
jfieldID intNum = (*env)->GetFieldID(env, objClass, "javaIntNum", "I");
jfieldID intArr = (*env)->GetFieldID(env, objClass, "javaIntArr", "[I");
jfieldID arrayOfArrays = (*env)->GetFieldID(env,objClass,"javaArrayOfArrays","[Ljava.lang.reflect.Array");
// call C function to fill in outObj
(*env)->SetIntField(env, outJava,intNum,outObj.bag_roi->xmin);
for (j=0;j<=outObj.bulks->number_of_bulks;j++) {
(*env)->SetIntArrayRegion(env,intArr_tmp,j,1,&outObj.bulks[j].xmin); // this works
(*env)->SetIntArrayRegion(env,row_flags,0,5,&outObj.bulks[j].flags[0]); // this doesn't work
// I want an array of outObj.bulks[j].flags (which is an array of ints) in my java class
(*env)->SetObjectArrayElement(env,arrayOfArrays_tmp,j,row_flags); // this doesn't either
(*env)->SetObjectField(env,outJava,intArr,intArr_tmp);
Java class that corresponds with outJava is as follows:
import java.io.*;
import java.util.*;
public class JOutClass{
public int javaIntNum;
public int[] javaIntArr = new int[5];
public int[][] javaArrayOfArrays = new int[3][5];

Hi, maybe you can glean something from this test case I created when I was fighting with this. We seem to have taken slightly different approaches, but see if it helps at all. The trouble might be that you did not release the array(s) back to the java memory space with ReleaseIntArrayElements.
Also, because the hardcoded array lengths seem unavoidable ...remember that a public final static int field in the class that you compile against jni will also be available in the .h file (not shown in this example). It's still hardcode ...but at least you can alter the constant in the Java class without having to recompile the native code. Anyway, here you go. I have a 3D array example as well ...but that was just plain sick, so I will spare you the nausea.
File TestRaster2DImp.c
#include <jni.h>
#include "TestRaster2D.h"
JNIEXPORT void JNICALL
Java_TestRaster2D_nextGeneration(JNIEnv *env, jobject obj, jobjectArray arr)
  int i, j;
  jint *body[2];
  jintArray oneDim[2];
  jsize len1;
  jsize len2;
  oneDim[0] = (*env)->GetObjectArrayElement(env, arr, 0);
  len1 = (*env)->GetArrayLength(env, arr);
  len2 = (*env)->GetArrayLength(env, oneDim[0]);
  for(i=0; i<len1; i++) {
    oneDim[i] = (*env)->GetObjectArrayElement(env, arr, i);
    body[i] = (*env)->GetIntArrayElements(env, oneDim, 0);
for(j=0; j<len2; j++) {
body[i][j]++;
printf("%d\n", body[i][j] );
printf("\nOut: %d\n", body[0][2] );
printf("Out: %d\n", body[1][2] );
(*env)->ReleaseIntArrayElements(env, oneDim[0], body[0], 0);
(*env)->ReleaseIntArrayElements(env, oneDim[1], body[1], 0);
File TestRaster2D.java
public class TestRaster2D {
  int[][] ra = {
    { 1, 2, 3, 4, 5 },
    { 11, 12, 13, 14, 15 }
  public TestRaster2D() {
    System.out.println( " is " + ra[0][2] );
    System.out.println( " is " + ra[1][2] );
    System.out.print( "\n" );
    nextGeneration( ra );
    System.out.print( "\n" );
    System.out.println( " is " + ra[0][2] );
    System.out.println( " is " + ra[1][2] );
  public native void nextGeneration( int[][] theArray );
  static {
    System.loadLibrary("raster2D");
  public static void main(String[] args) {
    new TestRaster2D();
}Good luck.

Similar Messages

  • Problems creating a Java Array using JNI-HELP!

    Hi,
    I am trying to create a Java Array using JNI.I have posted the code below. The problem is that the oth element is added correctly to the Array but when the JVM gets to the next element...it goes for a toss. It is not able to create a new instance of the object in GetUGEntity() function...there seems to be some problem in creating a new instance of the object!
    Can somebody help me with this?
    jobject GetUGEntity(JNIEnv *env, UF_DISP_j3d_entity_t* entity_list)
         int numVerts=0, numStrips=0;
         jfieldID fid;
         jdoubleArray jTransform=NULL;
         jstring jstrName=NULL;
         jdoubleArray jNormals=NULL;
         //Init an Entity object
         cout<< "**Getting New Class Reference...";
         jclass jEntity = env->FindClass("Lcom/wipro/java3d/rmi/Entity;");
         cout << "**got Class reference..."<<endl;
         if (jEntity == NULL)
              return NULL;
         cout<<"Creating new object instance...";
         jmethodID mIDInit = env->GetMethodID(jEntity, "<init>", "()V");
         cout<<"Got java method id...";
         jobject javaObj = env->NewObject(jEntity, mIDInit);
         if (javaObj==NULL)
              return NULL;
         cout << "Created!" << endl;
         //Entity ID
         cout<< "**Setting eid...";
         fid=env->GetFieldID(jEntity,"eid","I");
         jint eid = (jint)(entity_list)->eid;
         env->SetIntField(javaObj, fid, eid);
         //env->DeleteLocalRef(eid);
         cout << "Done!" << endl;
         cout << "Done!" << endl;
         cout<< "**Returning jobject...";
         return javaObj;
    jobjectArray createJArray(JNIEnv* env, UF_DISP_j3d_entity_t** entity_list, int noOfEntities )
         UF_DISP_j3d_entity_t* tempVar=NULL;
         cout<<"*Creating Jobjectarray...";
         jobjectArray jEntityArray = (jobjectArray) env->NewObjectArray(noOfEntities,
              env->FindClass("Lcom/wipro/java3d/rmi/Entity;"),NULL);
         cout<<"Created!"<<endl;
         for(int i=0; i<noOfEntities;++i)
              tempVar = &(*entity_list);
              if (tempVar !=NULL)
                   cout<<"*Trying to get Entity...."<<endl;
                   jobject jEntity = GetUGEntity(env, tempVar);
                   if (jEntity!= NULL)
                        cout<<"Got Entity!" <<endl;
                        cout <<"*Setting Array Element....";
                        env->SetObjectArrayElement(jEntityArray, i, jEntity);
                        cout << "Done!" << endl;
                   else
                        printf("ERROR: Did not get Entity Reference");
              else
                   printf("ERROR: Got a NULL Reference!");
         return jEntityArray;

    Hi Deepak,
    Could you please let us know upto which line your code is going safe. Try printing the value in the structure before you send that to the method GetUGEntity().
    I am not too sure that would be a problem. But I have faced a problem like this, wherein I tried to access a structure for which I have not allocated memory and hence got exception because of that.
    Since your JNI code seems to be error free, I got doubt on your C part. Sorry.
    Dhamo.

  • C++ do not support  JNi && how to return the array from jni?

    hi,
    1.. I have created the Cpp file to implemement the native method but it seems that the native method can not complie rightly , it tells me follows
    error C2819: type 'JNIEnv_' does not have an overloaded member 'operator ->'
    c:\program files\microsoft visual studio\vc98\include\jni.h(764) : see declaration of 'JNIEnv_'
    c:\users\wangyue\desktop\java_gui\beattrack 5.6 - ������_������_������������ 5.7\beattrack.cpp(202) : error C2227: left of '->GetByteArrayRegion' must point to class/struct/union
    then I use the c file to paste the same code, it can complie rightly , why? I really need my native method to complie rightly in Cpp file, how to solve it?
    2.I want to return a double, for the most simple way, I do the following
    #include "RealBeatTrack_BeatTrack.h"
    JNIEXPORT jdoubleArray JNICALL Java_playaudio_BeatTrack_BeatTrack
    (JNIEnv *env, jobject j, jbyteArray data)
    jdouble outdata[4]={1,2,3,4};
    return (*env)->NewDoubleArray(env, outdata);
    then in the java code, I difine a array to receive it,
    say double mydata[] = new double[4];
    mydata= BeatTrack(buffedata);
    but the java comlier tells me the Exception in thread "Thread-2" java.lang.OutOfMemoryError: Java heap space?
    anyone can help me?
    Thanks

    thanks for your reply
    another problem of my!
    the jni pass the string, I then convert it to the
    const char* filename = env->GetStringUTFChars(fname,NULL);
    then I use the filename to opent the file but fails, what is the problem???
    FILE *fp= fopen(filename,"w"); // there are some problem here!!!
         fprintf(fp, "%s\n","wangyue fighting!");
    the error is as follows
    # An unexpected error has been detected by Java Runtime Environment:
    # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0bfc1a55, pid=7040, tid=11384
    # Java VM: Java HotSpot(TM) Client VM (10.0-b19 mixed mode windows-x86)
    # Problematic frame:
    # C [beattrack.dll+0x1a55]
    # An error report file with more information is saved as:
    # D:\programs\playAudio\hs_err_pid7040.log
    # If you would like to submit a bug report, please visit:
    # http://java.sun.com/webapps/bugreport/crash.jsp
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.
    #

  • Returning byte array in JNI

    Hi,
    I am trying to return an array of byte from JNI to java. I read the tutorial but i still find it hard to understand.
    BYTE *encoded is the variable that has the contents to be sent back to java.
    jbytearray jb=encoded;
    ret jb;
    This does not seem to reurn anything!! Please help

    This is the JNI implementation of the method:
    public native byte[] returnArray (int size, byte initialValue).
    JNIEXPORT jbyteArray JNICALL Java_Test_returnArray
      (JNIEnv *env, jobject This, jint size, jbyte initialValue) {
           //-- No error handling is being done...
           jbyte* buf = new jbyte[size];
           memset (buf, initialValue, size);
           jbyteArray ret = env->NewByteArray(size);
           env->SetByteArrayRegion (ret, 0, size, buf);
           delete[] buf;
           return ret;
    }A jbyte is a signed char (a signed byte). You can mix signed bytes and unsigned bytes in C++ depending on your needs. This JNI method is the functional equivalent of the 100% Java function:
    public byte[] returnArray (int size, byte initialValue) {
        byte[] ret = new byte[size];
        for (int i = 0; i < size; ++i) {
            ret[i] = initialValue;
        return ret;

  • Returning arrays using JNI

    Hi all,
    Hi,
    I am in the process of accessing the MS cryptoPI using java-jni-CryptoAPI. SO far i have been able to suceesfully acessing the cryptoapi functions. There are certificate stores istalled in our windows OS called "root", "CA" and "My" .Each of these stores have a lot of certificates installed . Till now i have written a program which opens the "My" cert store. In this case, it has only one certificate whose name is stored in pszNameString. In this case, the cert name is "AMS vivek" .I dont have any problem in passing the string back to java code if there is only one certificate involved. Supposing i retireve 2 certs,whose cert names are "AMS Vivek" and "Wipro Vivek" how do i pass them back to the java application. How do i store the names of the certificate in the native code and how do i pass them back to the java code??PLease help!
    import java.awt.*;
    import java.io.*;
    import java.lang.*;
    import java.applet.*;
    public class Testapp extends Applet {
         String ret=null;
    public void init(){
              System.out.println("in init");
              loaddll();
         public void loaddll(){
                        System.out.println("before loading DLL");
                        System.loadLibrary("Msgimpl");
                        System.out.println("After loading DLL");
         private native String crypto(String store);
    public void paint(Graphics g) {
              g.setColor(Color.blue);
              g.setColor(Color.magenta);
              g.drawString("call before native function", 25, 25);
              ret=crypto("My");
         g.drawString(ret, 25, 50);
              g.drawString("Finally", 25, 75);
    #define WIN32WINNT 0x0400
    #include <windows.h>
    #include <jni.h>
    #include <wincrypt.h>
    #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    #include "Testapp.h"
    BOOL APIENTRY DllMain(HANDLE hModule,
    DWORD dwReason, void** lpReserved) {
    return TRUE;
    JNIEXPORT jstring JNICALL
    Java_Testapp_crypto(JNIEnv * jEnv,jobject obj,jstring jstore) {
         HCRYPTPROV               hProv;
              BOOL                    bResult;
              HCERTSTORE hStoreHandle = NULL;
              PCCERT_CONTEXT          pCertContext = NULL;
              char                    pszNameString[256];
              CRYPT_KEY_PROV_INFO *pCryptKeyProvInfo;
              DWORD                    dwPropId=0;
              DWORD                    cbData;
              const char *msg;
              jstring jstr;
              msg = (*jEnv)->GetStringUTFChars(jEnv, jstore,0);
              //printf("Before context\n");
              if (hStoreHandle = CertOpenSystemStore(NULL,msg))
              printf("The %s store has been opened. \n", msg);
              else
              printf("The store was not opened.\n");
              exit(1);
         while(pCertContext= CertEnumCertificatesInStore(hStoreHandle,pCertContext))
                                       // on the first call to the function,
              // this parameter is NULL
              // on all subsequent calls,
              // this parameter is the last pointer
              // returned by the function
              if(CertGetNameString(pCertContext,CERT_NAME_FRIENDLY_DISPLAY_TYPE,0,NULL,pszNameString,1000))
              printf("\nCertificate for %s \n",pszNameString);
                   else
                   printf("\nGetNameFailed\n");
         }//main while
         return (*jEnv)->NewStringUTF(jEnv, pszNameString);
         //(*jEnv)->ReleaseStringUTFChars(jEnv, jstore,msg);
         if (!CertCloseStore(hStoreHandle,0))
         //printf("Failed CertCloseStore\n");
         exit(1);
              //printf("After context\n");

    Testapp.h is the header file that java creates.It conatins the definition of the native methods to be used.u can create a header file using
    javah -jni Testapp(class file...u must forst compile the .java file)
    * DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class Testapp */
    #ifndef IncludedTestapp
    #define IncludedTestapp
    #ifdef __cplusplus
    extern "C" {
    #endif
    /* Inaccessible static: LOCK */
    /* Inaccessible static: dbg */
    /* Inaccessible static: isInc */
    /* Inaccessible static: incRate */
    #undef Testapp_TOP_ALIGNMENT
    #define Testapp_TOP_ALIGNMENT 0.0f
    #undef Testapp_CENTER_ALIGNMENT
    #define Testapp_CENTER_ALIGNMENT 0.5f
    #undef Testapp_BOTTOM_ALIGNMENT
    #define Testapp_BOTTOM_ALIGNMENT 1.0f
    #undef Testapp_LEFT_ALIGNMENT
    #define Testapp_LEFT_ALIGNMENT 0.0f
    #undef Testapp_RIGHT_ALIGNMENT
    #define Testapp_RIGHT_ALIGNMENT 1.0f
    #undef Testapp_serialVersionUID
    #define Testapp_serialVersionUID -7644114512714619750LL
    /* Inaccessible static: metrics */
    /* Inaccessible static: class_00024java_00024awt_00024Component */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024ComponentListener */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024FocusListener */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024HierarchyListener */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024HierarchyBoundsListener */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024KeyListener */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024MouseListener */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024MouseMotionListener */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024InputMethodListener */
    #undef Testapp_serialVersionUID
    #define Testapp_serialVersionUID 4613797578919906343LL
    /* Inaccessible static: dbg */
    /* Inaccessible static: class_00024java_00024awt_00024Container */
    /* Inaccessible static: class_00024java_00024awt_00024event_00024ContainerListener */
    /* Inaccessible static: nameCounter */
    #undef Testapp_serialVersionUID
    #define Testapp_serialVersionUID -2728009084054400034LL
    #undef Testapp_serialVersionUID
    #define Testapp_serialVersionUID -5836846270535785031LL
    * Class: Testapp
    * Method: listCertificate
    * Signature: (Ljava/lang/String;)[Ljava/lang/String;
    JNIEXPORT jobjectArray JNICALL Java_Testapp_listCertificate
    (JNIEnv *, jobject, jstring);
    * Class: Testapp
    * Method: certificateKey
    * Signature: (Ljava/lang/String;[B)V
    JNIEXPORT void JNICALL Java_Testapp_certificateKey
    (JNIEnv *, jobject, jstring, jbyteArray);
    #ifdef __cplusplus
    #endif
    #endif

  • JNI: Multi-dimensional (3-D) Array [][][]

    Hi,
    Am having trouble with passing multi-dimensional arrays from C++ to Java.
    The Java method receives an object but it's contents are null.
    The received (in Java) object's length is correct.
    If I only have a 2d array, I do not encounter a problem.
    // Create the class
    jclass intClass = env->FindClass("[I");
    // Create 1st and 2nd array
    jobjectArray array1 = env-> NewObjectArray(30, intClass, NULL)
    jobjectArray array2 = env-> NewObjectArray(2, intClass, NULL)
    // Create 3rd Array
    jintArray array3 = env->NewIntArray(100);
    // Put some data into array3
    env-> SetIntArrayRegion(array3 , 0, 1, myBuffer);
    // Add array 3 to array 2 and array 2 to array 1
    env->SetObjectArrayElement(array2 , 0, array3);
    env->SetObjectArrayElement(array1 , 0, array2 );
    // Call the Java method
    env->CallVoidMethod(obj, mid, array1 )I have checked before calling the Java method that all 3 arrays are created and have the correct sizes.
    The example in Sheng Liang's book is only for 2d Arrays.
    Any ideas ?
    Many thanks.
    Andy

    Hi,
    I'm not very aware of arrays under JNI but I thought the number of [ were the number of dimension :
    // Create the class
    jclass intClass = env->FindClass("[[[I");--Marc (http://jnative.sf.net)                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • 2 D array of doubles

    I was wondering how to pass a 2D array of doubles through JNI?
    I am doing this so that I can change the 2D array to a Variant that contains a 2D array of SAFEARRAYS of doubles. Then I am going to invoke a method of a 3rd party software through COM.

    It's possible, but I believe that you'll be crazy using such an array in JNI (dereferencing lots of things etc.) and the performance will be very poor.
    You can do the following thing:
    - Convert the 2D array into a 1D array in Java code. It's faster in the Java side than doing it using JNI (basically you'll need to use a lot of System.arraycopy() calls and some multiplications and additions).
    - Transfer the 1D array to the JNI code
    - Convert it back to the Variant or SAFEARRAY(double) 2D array - I believe that if you've done the things right you'll need only to do a straight memcpy in the JNI code.

  • How do I get a byte array from an object passed into the JNI?

    This is what my java code looks like:
    public class streamedData
    protected byte[] m_value = null;
    public byte[] getByteArray ()
    return m_value;
    /* code not pertaining to this question snipped. */
    jclass streamedDataClass = env->GetObjectClass(jstreamedData);
    // Get methodIDs for the various NPKI_Extension methods
    value = env->GetMethodID(streamedDataClass, "getByteArray", "()[B");
    lstreamedData->value = (unsigned char *)malloc (lstreamedData->length);
    if (lstreamedData->value == NULL)
    return INSUFFICIENT_MEMORY;
    memset (lstreamedData->value, 0, lstreamedData->length);
    memcpy (lstreamedData->value, env->CallByteMethodA(streamedDataClass, value, NULL), lstreamedData->length);
    This is not working.
    My question is, how do I get a copy of or read m_value in the JNI layer? Do I have to make the byte array public and access it as a field ID?
    Any help would be appreciated. Why oh why can't there be a CallByteArrayMethod????

    My question is, how do I get a copy of or read m_value in the JNI layer? Do I have to make the byte array public and access it as a field ID?
    You can retrieve a handle to the byte array, through a method call, as you're doing now, or by directly accessing it through GetFieldID.
    In the case of the method call, you'll want to do:jmethodID getByteArrayMethod = env->GetMethodID(streamedDataClass, "getByteArray", "()[B");
    jbyteArray byteArray = static_cast<jbyteArray>( env->CallObjectMethod( jstreamedData, getByteArrayMethod ) );In the case of field access, you can do:jfieldID m_valueFieldID = env->GetFieldID( streamedDataClass, "m_value", "[B" );
    jbyteArray byteArray = static_cast<jbyteArray>( env->GetObjectField( jstreamedData, m_valueFieldID ) );Once you have byteArray, you need to access it using the array operations:lstreamedData->value = env->GetByteArrayElements( byteArray, 0 );
    // Do what you want to do, then release the array
    env->ReleaseByteArrayElements( byteArray, lstreamedData->value, 0 );As always, Jace, http://jace.reyelts.com/jace, makes this easier. For example,void printByteArray( jobject jstreamedData ) {
      streamedData data( jstreamedData );
      JArray<JByte> byteArray = streamedData.m_value();
      for ( int i = 0; i < byteArray.length(); ++i ) {
        cout << byteArray[ i ];
    }God bless,
    -Toby Reyelts

  • JNI and huge Array

    Hi,
    I need to transfer nearly 120k buffer to Native C++ code and the same data back to JAVA.
    I like to know how this array is transfered from Java to C++ and C++ to Java?
    Can I pass the reference from Java to C++?
    Thanks in advance
    Raja

    Do you need to use the data in java? Then you have to do the regular jni array stuff.
    If you don't use it, then just have java keep a pointer - put the pointer into a java long and re-extract when you need it again.

  • [JNI Beginner] GC of Java arrays returned by the native code

    Hello all,
    I am beginning with JNI, to integrate a C library that pilots an industrial equipment, into a java UI. This library enables to exchange various proprietary PDUs (protocol data units), with the equipment, up and down (request/replies). Both requests and replies are arrays of bytes (+char*+).
    "Request" byte arrays are constructed by Java code, which passes them to the JNI code that glues with the lib. "Reply" byte arrays are returned to the Java code, which analyzes them.
    The "return reply" part is very similar to this [tutorial example|http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html] , which returns bytes read from a file. However there's something I don't understand with regard to garbage collection of the returned byte array:
    - in this stock example, the C code creates a Java byte array fills it, and simply returns it (example code stripped to highlight only the parts relevant to my question):
        jByteArray=(*env)->NewByteArray(env, size);
        (*env)->SetByteArrayRegion(env, jByteArray, 0, size, (jbyte *)sourceBytes);
        return (jByteArray);What will happen to this Java array (jByteArray) with regard to garbage collection?
    - if it's no more referenced (the example Java code just systemouts it and forgets it), will it be eligible to GC?
    - if it is referenced by a Java variable (in my case, I plan to keep a reference to several replies as the business logic requires to analyze several of them together), do regular Java language GC rules apply, and prevent eligibility of the array to GC as long as it's referenced?
    That may sound obvious, but what mixes me up is that the same tutorial describes memory issues in subsequent chapters: spécifically, the section on "passing arrays states that:
    [in the example] the array is returned to the calling Java language method, which in turn, garbage collects the reference to the array when it is no longer usedThis seems to answer "yes" to both my questions above :o) But it goes on:
    The array can be explicitly freed with the following call:
    {code} (*env)-> ReleaseByteArrayElements(env, jByteArray, (jbyte *)sourceBytes, 0);{code}Under what circumstances would one need to explicitly free jByteArray when it's about to be returned to the Java calling method? Or does this sentence apply to completely different situations (such as, when the array is +not+ returned as is to a Java method)?
    The tutorial's next section has a much-expected +memory issues+ paragraph, from which I quote:
    By default, JNI uses local references when creating objects inside a native method. This means when the method returns, the references are eligible to be garbage collected.I assume this means, +unless the references are assigned, in the Java code, to a Java variable+, right?
    If you want an object to persist across native method calls, use a global reference instead. A global reference is created from a local reference by calling NewGlobalReference on the the local reference.I assume this enables the C code to maintain a global reference to a java object even if it's not referenced anymore from the Java variables, right?
    I also checked the [JNI specification|http://download-llnw.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp1242] , but this didn't clear the doubt completely:
    *Global and Local References*
    The JNI divides object references used by the native code into two categories: local and global references. Local references are valid for the duration of a native method call, and are automatically freed after the native method returns. Global references remain valid until they are explicitly freed.
    Objects are passed to native methods as local references. All Java objects returned by JNI functions are local references. The JNI allows the programmer to create global references from local references. JNI functions that expect Java objects accept both global and local references. A native method may return a local or global reference to the VM as its resultAgain I assume the intent is that Global references are meant for objects that have to survive across native calls, regardless of whether they are referenced by Java code. But what worries me is that combining both sentences end up in +All Java objects returned by JNI functions are local references (...) and are automatically freed after the native method returns.+.
    Could you clarify how to make sure that my Java byte arrays, be they allocated in C code, behave consistently with a Java array allocated in Java code (I'm familiar already with GC of "regular" Java objects)?
    Thanks in advance, and best regards,
    J.

    jduprez wrote:
    Hello all,
    I am beginning with JNI, to integrate a C library that pilots an industrial equipment, into a java UI. This library enables to exchange various proprietary PDUs (protocol data units), with the equipment, up and down (request/replies). Both requests and replies are arrays of bytes (+char*+).
    "Request" byte arrays are constructed by Java code, which passes them to the JNI code that glues with the lib. "Reply" byte arrays are returned to the Java code, which analyzes them.
    The "return reply" part is very similar to this [tutorial example|http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html] , which returns bytes read from a file. However there's something I don't understand with regard to garbage collection of the returned byte array:
    - in this stock example, the C code creates a Java byte array fills it, and simply returns it (example code stripped to highlight only the parts relevant to my question):
        jByteArray=(*env)->NewByteArray(env, size);
    (*env)->SetByteArrayRegion(env, jByteArray, 0, size, (jbyte *)sourceBytes);
    return (jByteArray);What will happen to this Java array (jByteArray) with regard to garbage collection?It will be collected when it is no longer referenced.
    The fact that you created it in jni doesn't change that.
    The array can be explicitly freed with the following call:
    (*env)-> ReleaseByteArrayElements(env, jByteArray, (jbyte *)sourceBytes, 0);Under what circumstances would one need to explicitly free jByteArray when it's about to be returned to the Java calling method? Or does this sentence apply to completely different situations (such as, when the array is not returned as is to a Java method)?
    Per what the tutorial says it is either poorly worded or just wrong.
    An array which has been properly initialized it a just a java object. Thus it can be freed like any other object.
    Per your original question that does not concern you because you return it.
    In terms of why you need to explicitly free local references.
    [http://download-llnw.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp16785]
    The tutorial's next section has a much-expected memory issues paragraph, from which I quote:
    By default, JNI uses local references when creating objects inside a native method. This means when the method returns, the references are eligible to be garbage collected.I assume this means, unless the references are assigned, in the Java code, to a Java variable, right?As stated it is not precise.
    The created objects are tracked by the VM. When they are eligible to be collected they are.
    If you create a local reference and do NOTHING that creates an active reference elsewhere then when the executing thread returns to the VM then the local references are eligible to be collected.
    >
    If you want an object to persist across native method calls, use a global reference instead. A global reference is created from a local reference by calling NewGlobalReference on the the local reference.That is not precise. The scope is the executing thread. You can pass a local reference to another method without problem.
    I assume this enables the C code to maintain a global reference to a java object even if it's not referenced anymore from the Java variables, right?
    It enables access to it to be insured across multiple threads in terms of execution scope. Normally you should not use them.

  • JNI - Passing an object containing an array field

    I need to pass an object to a native method. The object contains several int fields and a field that is an int array (contains 32 int).
    I have no problem with the int fields, but do not know how to access the int array field in the C code. What approach should be used to get/set values in the int array field?
    Any suggestions are appreciated.

    I have been reading up on the subject, but I guess I'm just an idiot. If all the answers were obvious from reading the specification then there wouldn't be much point to this forum.
    For int fields in the object passed to the native function I do the following to set the value:
    fid = (*env)->GetFieldID(env, cls, "intFieldName", "I");
    (*env)->SetIntField(env, myObj, fid, newValue);
    For a field that is an array of int, it seems that I can get the field ID as follows:
    fid = (*env)->GetFieldID(env, cls, "arrayFieldName", "[I");
    The "Get<Type>Field" and "Set<Type>Field" methods can be used for object, boolean, byte, char, short, int, long, float, double. Nothing specific here for array. Should I use the GetObjectField method, if so can the object field then be handled as an array? This is where I am missing something. I have experimented with using the SetIntArrayRegion method but this causes an exception - obviously missing a necessary step here. I am hoping someone here can provide guidance on what I am missing, what JNI functions I should be using, or refer me to the appropriate page of the specification or other document where it is explained (for idiots like me).

  • FATAL ERROR in native method: Non-array passed to JNI array operations

    After stepping up to JDK 1.4.2 we started getting a hotspot error, I added -Xcheck:jni and it yielded the above error which was not existent in JDK 1.4.1 and for the life of me I cannot find out whats wrong:
    Native method dec:
    private native byte[] cost(final byte[] byte_array,
    final double minCostPerMeter,
    final int costFuncSelection,
    final double maxCostThreshold);
    Method call:
    ByteArrayInputStream
    inputByteStream = new ByteArrayInputStream(
    cost(output_byte_stream.toByteArray(),
    minCostPerMeter,
    costFunctionSelection.length,
    maxCostThreshold));
    An array is being passed I have no idea why it is complaing about the method call.
    Any help would be appreciated.
    -R

    What happens if you remove all the code from the JNI method - so it just calls and then returns?
    If it still occurs then I would expect that you have a memory problem in a piece of code before this one. Such problems can have no impact when run in one environment but cause failures in another becomes some other legitimate piece of data moved.
    If it doesn't then I would expect that the problem is in the method itself and not the call.
    It could be some odd VM problem so trying a different version of 1.4.2 might help (but in of itself would not eliminate the possibility that you have a memory problem.)

  • JNI multidimensional Array and OpenCV

    Hello everybody,
    my first post, so lets go..
    At the moment I am writing my thesis in the filed of automatic image classification. The project is written in Java, but I wanna use the OpenCV library from Intel (http://sourceforge.net/projects/opencvlibrary/) for facedetection.
    So far I managed to call the native method from Java. What I do I parse the path of the image to be analyzed as a string to my C++ programm. The faces are being detected and written into a so called CvSeq (http://www.comp.leeds.ac.uk/vision/opencv/opencvref_cxcore.htm#cxcore_ds_sequences) which holds the coordinates of the rectangles surrounding the found faces. Until now I can only call cvSeq->total which gives me the total number of faces as ints. That integer I return to my java api.
    What I don't know is, how to return a multidimensional array (2 dimensions) where the first dim contains the path as a string to the file and the second dimension 3 integers for x,y coordinates and the lenght of each rectangle.
    Or better, I might know how to return that Array, but not how to create it.
    I know this is somewht OpenCV specific, but maybe someone knows anything. Any little help would be greatly appreciated. Thanks a lot!!!!
    Regards
    Carsten
    attached: JNI source code
    /////////////////////////////////////////// source code ///////////////////////////////////////////////
    #include "cv.h"
    #include "highgui.h"
    #include "cxcore.h"
    #include "cxtypes.h"
    #include "cvaux.h"
    #include "org_kimm_media_image_data_JNIOpenCV.h"
    #include <stdio.h>
    JNIEXPORT jint JNICALL
    Java_org_kimm_media_image_data_JNIOpenCV_getFaces(JNIEnv *env, jobject object, jstring path)
    //declarations
    CvHaarClassifierCascade *pCascade = 0;
    CvMemStorage *pStorage = 0;
    CvSeq *pFaceRectSeq;
    int scale=1;
    jobjectArray recPoints;
    const char *str = env->GetStringUTFChars(path, 0);
    //initializations
    IplImage* pInpImg = cvLoadImage(str, CV_LOAD_IMAGE_COLOR);
    IplImage* small_image = pInpImg;
    pStorage = cvCreateMemStorage(0);
    pCascade = (CvHaarClassifierCascade *)cvLoad
         (("C:/OpenCV/data/haarcascades/haarcascade_frontalface_default.xml"),0, 0, 0 );
    //validaste that everything initilized properly
    if( !pInpImg || !pStorage || !pCascade)
         printf("Initialization failed: %s \n",
              (!pInpImg) ? "didn't load image file" :
              (!pCascade) ? "didn't load Haar Cascade --"
                   "make sure Path is correct" :
              "failed to allocate memory for data storage");
         exit(-1);
    //performance boost through reducing image size by factor 2          
              small_image = cvCreateImage( cvSize(pInpImg->width/2,pInpImg->height/2), IPL_DEPTH_8U, 3 );
    cvPyrDown( pInpImg, small_image, CV_GAUSSIAN_5x5 );
    scale = 2;
    //detect faces in image
    pFaceRectSeq = cvHaarDetectObjects(small_image, pCascade, pStorage,
                                            1.1,                                        //increase search scale by 10% each pass
                                            6,                                        //drop group of fewer than three detections
                                            CV_HAAR_DO_CANNY_PRUNING,          //skip regions unlikely to contain faces
                                                 cvSize(50,50));                         //use XML default for smallest search scale
    //initialize array for location of the faces (HERE IS WHERE I GET INTO TROUBLE!!!!!)
    int x = pFaceRectSeq->total;
    jclass intArrCls = env->FindClass ( "[I" ) ;
    recPoints = env->NewObjectArray ( x, intArrCls, NULL ) ;
    //for(int j = 0; j <= x; j++) {
    //   recPoints[j] = (jintArray)env->NewIntArray(3);
    for(int i=0;i<(pFaceRectSeq ? pFaceRectSeq->total:0); i++)
                                       CvRect* r = (CvRect*)cvGetSeqElem(pFaceRectSeq, i);
                                       CvPoint pt1 = {(r->x)*scale, (r->y)*scale};
                                       CvPoint pt2 = {(r->x + r->width)*scale, (r->y + r->height)*scale};
    //env->SetObjectArrayElement(recPoints,i, pt1.x);
    return pFaceRectSeq->total;
    }

    Any Java array you can consider like one-dimensional array of arrays n-1 dimension. For example, you have a 3 dim. array of objects:
    Object[][][] arr = new Object[1][2][6]; It can be considered as a set of one-dimensional arrays:
    ==========================================
    |  dim   |           Type
    ==========================================
      0          1 element, an array of type �[[Ljava/lang/Object;�
      1          1 x 2 elements , an arrays of type �[Ljava/lang/Object;�
    So you can convert three-dimensional array to one-dimensional array like in C++:
    |�[Ljava/lang/Object;� | �[Ljava/lang/Object;� | �[Ljava/lang/Object;�
         6 objects                 6 objects                 6 objects

  • Array store exception -- JNI

    Hi,
    I am trying to return a string array in the native function to java and i get the follwing error when i run the java class file
    Exception in thread "main" java.lang.ArrayStoreException
    at ArrayHandler.returnArray(Native Method)
    at ArrayHandler.main(ArrayHandler.java:10)
    My java and C code are pasted below
    public class ArrayHandler {
    private static native String[] returnArray();
    static{
    System.loadLibrary("Msgimpl");
    public static void main(String args[]) {
    ArrayHandler ah= new ArrayHandler();
    String[] ar = ah.returnArray();
    for (int i=0; i<5; i++) {
    System.out.println("array element"+i+"=" + ar);
    #define WIN32WINNT 0x0400
    #include <windows.h>
    #include <jni.h>
    #include <wincrypt.h>
    #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    #include "ArrayHandler.h"
    BOOL APIENTRY DllMain(HANDLE hModule,
    DWORD dwReason, void** lpReserved) {
    return TRUE;
    JNIEXPORT jobjectArray JNICALL
    Java_ArrayHandler_returnArray(JNIEnv *env, jobject obj){
    jobjectArray ret;
    int i;
    char *message[5]= {"first",
         "second",
         "third",
         "fourth",
         "fifth"};
         jclass intArrCls = (*env)->FindClass(env, "[Ljava/lang/String;");
         if (intArrCls == NULL) {
         return NULL; /* exception thrown */
    ret=(jobjectArray)(*env)->NewObjectArray(env,5,intArrCls,(*env)->NewStringUTF(env,""));
    if (ret == NULL) {
              return NULL; /* out of memory error thrown */
    for(i=0;i<5;i++) {
    (*env)->SetObjectArrayElement(env,ret,i,(*env)->NewStringUTF(env,message[i]));
    return(ret);

    I found out the mistake
    jclass intArrCls = (*env)->FindClass(env, "[Ljava/lang/String;"); should have been
    jclass intArrCls = (*env)->FindClass(env, "Ljava/lang/String;");
                                                                                                                                                                                                                                                                                                                                                                   

  • Pass an array of integers from C to Java with JNI

    Hello,
    I have a C function that returns a struct me. The fields of this struct are all of type integer. I, with the fields of this structure create an array of integers in C language I would like to pass this array of integers c, in Java using JNI.
    How can I make this?

    I don't see how you compiled that.
    It certainly will not compile for me.
    jintArray position=(jintArray)(*env)->NewIntArray(env,2);That is the invocation idiom for C code.
    jint f[2];You cannot have a variable declaration in the middle of a method (block) in C code. That is only allowed in C++.
    C code and C++ code is not the same.
    The following is C++ code. Note that it does NOT include getBinaryPoint() since that method could be the source of the problem.
    jintArray position = env->NewIntArray(2);
    if(position==NULL)     return NULL;
    jint f[2];
    f[0]=3;
    f[1]=4;
    env->SetIntArrayRegion(position,0,2,f);
    return position;

Maybe you are looking for

  • Requistion and Purchase Order - base unit and order unit

    People, I have a basic doubt in MM: I have a Requisition with a item using the base unit, for instance 20 litres. When I create a Purchase Order in ME21N passing the requisition and item number, I must be converted to the order unit, correct? In this

  • Stablize video with out of frame anchors?

    I have some clips I want to stablize. However, no high-contrast object stays in frame throughout the clip. What do you do in this case? Do you break the clip into two and stablize each one individually, then match them up manually? Or is it possible

  • Documentation to master Query Designer Features

    Hello colleges. I would like to know if anyone has found a comprehensive documentation in the use of the Query Designer, specially in those features who seems to help you calculate an use cumulative, counters, contributions, totals, ranking use, etc.

  • Change process chain...

    Hi Gurus, I have a process chain in dev which I transported to prod. Now I want to make changes to the process chain. Can you please explain the procedure that I should follow? Thanks NewBW

  • I can not use numbers on my iPod touch just letters can someone help me?

    Can someone help me , I can use numbers on my iPod touch after I replaced the digitizer and lcd glass on my iPod 3rd generation every thing else works fine.