Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

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

Thread view: 
markryde@gmail.com - 22 Dec 2005 20:05 GMT
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
Gordon Beaton - 22 Dec 2005 21:06 GMT
> Now , in the Java class I want to retrieve the objects of this array.
> I tried:
[quoted text clipped - 14 lines]
>
> 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

Signature

[  do not email me copies of your followups  ]
g o r d o n + n e w s @  b a l d e r 1 3 . s e

markryde@gmail.com - 23 Dec 2005 04:18 GMT
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
Gordon Beaton - 23 Dec 2005 07:46 GMT
> 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

Signature

[  do not email me copies of your followups  ]
g o r d o n + n e w s @  b a l d e r 1 3 . s e



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.