Rerieving array of Java Objects which are created in a JNI method

M

markryde

Hello,

I have a simple java class named MyClass, which has only 2 members and
a ctor:

public class MyClass
{
public int i;
public int j;
public MyClass(int i,int j)
{
this.i=i;
this.j=j;
}
}

Now, in a JNI method I want to create an array of objects of this class
and return it to a java method which calls this JNI method.

I tried this :
in the JNI native:

JNIEXPORT jobjectArray JNICALL Java_Test_getMyArray (JNIEnv* env,
jobject obj)
{
jobjectArray joaMyArray;
jobject newObject;
jclass myClass = (*env)->FindClass(env,"MyClass");
if (myClass==NULL)
{
return NULL;
}
jmethodID midCtor = (*env)->GetMethodID(env,myClass, "<init>",
"(II)V");

if (midCtor==NULL)
return NULL;

joaMyArray = (*env)->NewObjectArray(env,2, myClass, NULL);
newObject = (*env)->NewObject(env,myClass, midCtor,1,2);
newObject = (*env)->NewObject(env,myClass, midCtor,3,4);

(*env)->SetObjectArrayElement(env,joaMyArray, 0, newObject);
(*env)->SetObjectArrayElement(env,joaMyArray, 1, newObject);

return ret;
}


Now , in the Java class I want to retrieve the objects of this array.
I tried:
public static void main(String[] args)
{
Test test = new Test();
Object[] myClass = test.getMyArray();

(when I tried :
MyClass[] myClass = test.getMyArray();
it gave compilation error,saying that it expects Object[].)

I want to iterate over the elements of the array of MyClass
isntances, which is returned from getMyArray, and print the i,j
values of the elements of this array. (which are instances of MyClass)

How can I do it ?

Regards,
-- MR
 
G

Gordon Beaton

Now , in the Java class I want to retrieve the objects of this array.
I tried:
public static void main(String[] args)
{
Test test = new Test();
Object[] myClass = test.getMyArray();

(when I tried :
MyClass[] myClass = test.getMyArray();
it gave compilation error,saying that it expects
Object[].)

I want to iterate over the elements of the array of MyClass
isntances, which is returned from getMyArray, and print the i,j
values of the elements of this array. (which are instances of
MyClass)

How can I do it ?

Declare the native method correctly (in the java source) and you can
use the correct return type:

public native MyClass[] getMyArray();

then:

MyClass[] myClass = test.getMyArray();

You can safely ignore the fact that the declaration in C uses
jobjectArray.

BTW the following sequence of statements will likely not do what you
seem to hope, if this is really the order they appear in your code:
newObject = (*env)->NewObject(env,myClass, midCtor,1,2);
newObject = (*env)->NewObject(env,myClass, midCtor,3,4);

(*env)->SetObjectArrayElement(env,joaMyArray, 0, newObject);
(*env)->SetObjectArrayElement(env,joaMyArray, 1, newObject);

The first element is lost, and the second one is assigned to both
positions.

/gordon
 
M

markryde

Hello Gordon,
Thnks !

You were very helpful indeed.

Indeed , when I chnaged it to:
public native MyClass[] getMyArray();
and
MyClass[] myClass = test.getMyArray();
It did compiled OK.
BTW the following sequence of statements will likely not do what you
seem to hope, if this is really the order they appear in your code:

I ran the program and indeed the value of the first element was lost,
and the second one was assigned to both
positions.

I found out that if I use different instances of jobject it works as
expected.

I assume that this is the proper way to do it .




Regards,
MR
 
G

Gordon Beaton

I found out that if I use different instances of jobject it works as
expected.

That's one way.
I assume that this is the proper way to do it .

Well it's ok for two objects, but simply reorder the statements and
you only need one variable regardless of the array size:

newObject = (*env)->NewObject(env,myClass, midCtor,1,2);
(*env)->SetObjectArrayElement(env,joaMyArray, 0, newObject);

newObject = (*env)->NewObject(env,myClass, midCtor,3,4);
(*env)->SetObjectArrayElement(env,joaMyArray, 0, newObject);

This has the advantage that you can put it inside a loop and handle
any number of elements:

for (i=0,j=1; i<n; i++,j+=2) {
newObject = (*env)->NewObject(env,myClass, midCtor,j,j+1);
(*env)->SetObjectArrayElement(env,joaMyArray, 0, newObject);

// hint for GC when n is large
(*env)->DeleteLocalRef(env,newObject);
}

/gordon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top