5 Replies Latest reply: May 16, 2011 5:20 PM by jschellSomeoneStoleMyAlias RSS

    Retrieving arrays of java class inside C++ code

    860480
      Hi everyone,

      Currently i am using JNI for native access. But i am getting some error while retrieving arrays of a java class inside my c++ code. I mean, if my java code is:
      package GUI;
      public class myClass {
          
          public native test1 classcl();       ///return type is object of class 'test1' (defined below)
          
              public static void main(String[] args)
          {
              System.load("D:\\dot_net\\TestGUI\\debug\\TestGUI.dll");
              myClass obj = new myClass();
              obj.classcl();
              
          }
      
      }
      
      class test1 {
          public int var = 90;
          public byte[] raw = new byte[5];
          
          public byte[] GetByte(){
              return raw;  
      }}
      then my corresponding implementation in C++ would be:
       JNIEXPORT jobject JNICALL Java_GUI_myClass_classcl
        (JNIEnv *env, jobject obj)
      {
           jclass testC;
           jobject objC;
           jint var1;
           jfieldID fid1;
      
           testC = env->FindClass("GUI/test1");
           fid1 = env->GetFieldID(testC,"var","I");
              objC = env->AllocObject(testC);
              env->SetIntField(objC,fid1,74);             ///// by this the integer field 'var' is accessed and it's value is changed
              return objC;
      } 
      /*****************DOUBT******************\
      You all must have noticed that there is also a byte array named raw inside class test1.
      So, my doubt is like I accessed the integer field var of class test1, if i also have to access the byte array(raw) and change it's value, then what would be my code?

      I have tried very hard, but somehow not able to achieve this.

      Thanking in advance,

      Satya Prakash.

      Edited by: 857477 on May 14, 2011 3:29 AM
        • 1. Re: Retrieving arrays of java class inside C++ code
          802316
          Personally, I would create the Object in Java, as you have done and update that object rather than create another object to return.

          When you create an object in JNI, you just get the object, without a constructor being called. This means you have to find and invoke the constructor method, or atleast duplicate what the constructor does and create the array. i.e. `raw` will be null unless you do. Obviously attempting to access it without creating an array will cause a Segmentation fault.
          • 2. Re: Retrieving arrays of java class inside C++ code
            860480
            Ok, but i couldn't get you properly.
            I have no constructor inside my 'test1' class. So, why would i require to invoke the default constructor? I mean, when i am creating the object, the default constructor is invoked automatically, right?

            Anyway my actual problem is that i want the equivalent syntax of the following code:

            /**************this is for accessing an integer variable inside my native C++ code*****************\

            testC = env->FindClass("GUI/test1");
            fid1 = env->GetFieldID(testC,"var","I");
            objC = env->AllocObject(testC);
            env->SetIntField(objC,fid1,74); ///// by this the integer field 'var' is accessed and it's value is changed

            So here, if instead of an integer variable it would have been an integer array, then what would have been the equivalent code?
            • 3. Re: Retrieving arrays of java class inside C++ code
              jschellSomeoneStoleMyAlias
              857477 wrote:
              the default constructor is invoked automatically, right?
              Java does that.

              You are not doing Java. You are doing JNI. And you must call the constructor.
              So here, if instead of an integer variable it would have been an integer array, then what would have been the equivalent code?
              Easiest way to do this is to write Java code that is a pseudo representation of what your JNI code needs to do.

              Then your JNI code must do the same thing.
              • 4. Re: Retrieving arrays of java class inside C++ code
                860480
                jschell wrote:
                >

                Easiest way to do this is to write Java code that is a pseudo representation of what your JNI code needs to do.
                Then your JNI code must do the same thing.
                Actually, I am completely new to both Java and Jni. So, can you just give me a small example of what you said:
                " a pseudo representation of what your JNI code needs to do". This would be really helpful.

                Thing is, I am having the following Java class:
                /*********************myClass.java*********************\
                public class myClass{

                public native test ret(); //test is another class defined below
                public static void main(String[] args)
                {
                myClass obj = new myClass();
                test obj1 = obj.ret();
                }
                }

                class test{
                public byte[] raw = new byte[5];
                public string str;
                }

                Now, i create myClass.h by using javac and javah in command prompt.
                now my cpp code using jni:
                /*********************myClass.cpp*********************\

                #include "myClass.h"

                JNIEXPORT jobject JNICALL Java_GUI_myClass_classcl
                (JNIEnv *env, jobject obj)
                {
                jclass testC = env->FindClass("test");
                jfieldID fid = env->GetFieldID(testC,"raw","[B");
                jfieldID fid2 = env->GetFieldID(testC,"str","Ljava/lang/String;");
                jmethodID mid = (env)->GetMethodID(testC, "<init>", "()V");
                jobject newObjC = env->NewObject(testC,mid); //as you said, invoking the constructor first

                So, now what to do? How to operate on the variables "raw" and "str" here. That's where I am confused.

                Waiting to hear from you,
                Sattu
                • 5. Re: Retrieving arrays of java class inside C++ code
                  jschellSomeoneStoleMyAlias
                  public native test ret();
                  That is your JNI method.
                  So, now what to do?
                  Step 1: Write Java code, not JNI, which is a pseudo (simulation) of what you want to do with Java, only java, in that JNI method.
                  Step 2: Use that code as a model to create your actual JNI code.

                  Note that step 1 does NOT involve writing C/C++ code. You write Java code. Only.