Return multiple values from C++

1,954 views
Skip to first unread message

Scott Marley

unread,
May 3, 2010, 4:38:12 PM5/3/10
to android-ndk
Hi Everyone. I'm struggling a little to get my head around how to
return multiple values from C++. Let's assume I have a struct in C++
that looks something like this:

struct details {
int index;
double distance;
...
};

I would like to return this from C++ to Java so that the members of my
struct are accessible. However, I don't need it to work the other way
(to put values from Java into my native struct). I have been reading
various articles regarding JNI but I have yet to find any really
simple examples of how this is done. I realise that I have to create a
Java class as a wrapper for my native struct but I'm still confused.
What would be extremely helpful is a simple code example including the
Java and Native code needed to achieve this. I know that once I've got
the principle it should be simple to extend.

Thank you everyone for your patience with a JNI novice.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.

fulanito

unread,
May 4, 2010, 6:23:56 AM5/4/10
to android-ndk
You need to bundle all the output values as one class in the Java side
(as a public class), and then init it from the C++
code using JNI methods.
You need to explicitly call the constructor from the C++ code, even if
it is only a default constructor.

For example:
jclass javaCls = env->FindClass("com/myApp/JavaClass");
jmethodID cid = env->GetMethodID(javaCls,"<init>","()V");
jobject out = env->NewObject(javaCls, cid);
Here I assume the class name is JavaCls and the constructor is the
default constructor.

Then you can set the fields, again using JNI methods:
jfieldID fid = env->GetFieldID(javaCls , "res", "Z");
env->SetBooleanField( out, fid, TRUE);
Here I set a boolean field called "res".

Always check that the jclass, jmethodID and so on returned from JNI
methods are not null.

For more info, look at JNI documentation.
Fulanito.

Scott Marley

unread,
May 4, 2010, 4:19:14 PM5/4/10
to android-ndk
Fantastic, that's the first clear description I've seen! For anyone
else who needs this explaining at the basic level that I have, my code
is as follows:

####### Java class declaration: #######

public class JavaCls {
public boolean res;
}

####### Java native declaration: #######

public native JavaCls trueFalse();

############### C++: ###############

extern "C"{

jobject
Java_astroexplorer_scott_uk_AstroExplorer_trueFalse( JNIEnv* env,
jobject thiz)
{
jclass javaCls = env->FindClass("astroexplorer/scott/uk/JavaCls");
jmethodID cid = env->GetMethodID(javaCls,"<init>","()V");
jobject out = env->NewObject(javaCls, cid);

jfieldID fid = env->GetFieldID(javaCls , "res", "Z");
env->SetBooleanField( out, fid, true);

return out;
}
}

###### To get the native results: ######

JavaCls result = trueFalse();

Now I just need to add the code to check for null values being
returned which would inevitably cause the program to hang. Thank you,
thank you, thank you!
Reply all
Reply to author
Forward
0 new messages