Search code examples
javac++java-native-interface

Complex data from Java to C++


Good night,

This is my first post here.

I'm working on a integration and I'm having some problem.

I'm trying to pass some structured data to/from Java<->C++ using JNI, but I'm having a situation.

Imagine something like this(despite the ugly format)

Class Detail {
    public int v1;
    public long v2;
}

Class Info {
    public int Number;
    pubinc int Size;
    public Detail InfoExtra[] = new Detail[ 3 ];
    Info(){
        InfoExtra[0] = new Detail();
        InfoExtra[1] = new Detail();
        InfoExtra[2] = new Detail();
        InfoExtra[3] = new Detail();
    }
}

I'm Ok accessing "Number" and "Size" using GetFieldID()/GetIntField().

My problem is when I try to access "InfoExtra" member and yours attributes.

I can find "InfoExtra" using:

lfieldID = (env*)->GetFieldID( localClass, "InfoExtra", "[LInfoExtra;" )

But, I don't know how to retrieve this. How can I do that?

Best regards Paulo


Solution

  • First thing to do is to change

    public Detail InfoExtra[] = new Detail[ 3 ];
    

    to

    public Detail InfoExtra[] = new Detail[ 4 ];
    

    in order to avoid the nasty ArrayIndexOfOutBounds exception.

    Now, you got the field signature wrong. A fast way to generate signatures is the following command:

    javap -s p <ClassName>
    

    For InfoExtra the right signature is [LDetail;.

    To access the array you would do something like this:

    jclass clazz = (*env)->GetObjectClass(env,obj);
    jfieldID infoExtra = (*env)->GetFieldID(env, clazz, "InfoExtra", "[LDetail;");
    jobjectArray extras = (*env)->GetObjectField(env, clazz,infoExtra);
    
    for (int i=0; i< ((*env)->GetArrayLength(env,extras)); i++) {
        jobject element = (*env)->GetObjectArrayElement(env,extras,i);
        //Do something with it, then release it
        (*env)->DeleteLocalRef(env,element);
    }
    
    //Don't forget to release the array as well
    (*env)->DeleteLocalRef(env,extras);
    

    Hope this helps!