4

I'm using JNI to call c++ methods in my java client. In one of the methods, I'm passing in an ArrayList of integers and want to get out an array of integers in c++. When I pass the ArrayList through the JNI, I get a jObject. How do I convert that object to an integer array?

I have found this post that is similar, but uses an arraylist of strings: JNI - java ArrayList conversion to c++ std::string*

Any ideas on how to modify that do use integers? I tried just changing the std::string refrences to int, but with no luck.

4
  • This might be helpful. Commented Oct 1, 2014 at 17:01
  • The seems to be doing the opposite, pass back an arraylist to java. It's not the JNI that I'm having trouble with, its the conversion from a jObject to an integer array that I'm having trouble with (where the jObject was an arraylist of integers in java) Commented Oct 1, 2014 at 17:14
  • simply walk the arrayList object via its size() and get(int) methods via jni Commented Oct 1, 2014 at 17:19
  • 2
    ... or convert the ArrayList<Integer> back into int[] before passing it back. Commented Oct 1, 2014 at 17:24

1 Answer 1

5

First realize that ArrayList<> is a generic, and JNI doesn't know anything at all about generics. Basically, to JNI, ArrayList<T> is ArrayList<Object>. Second, you are surely talking about ArrayList<Integer>, not ArrayList<int> because the second is not possible (see Why I can't have int in the type of ArrayList?). Let's look at converting this to an int[] in C++. I'm not going to try to write code that compiles here, because JNI is a huge tedious PITA, but this is the right idea, without all of the bloated error-checking you will also need ;-)

FYI, anyone who calls more than 10 JNI methods starts looking for JNI-wrapper-generators for C++. We've written our own in house, but I hear there are respectable open and commercial tools.

jobject arrayObj = ... jclass arrayClass = env->FindClass("java/util/ArrayList"); jmethodID sizeMid = env->GetMethodID(arrayClass, "size", "()I"); jclass integerClass = env->FindClass("java/lang/Integer"); jmethodID intValueMid = env->GetMethodID(integerClass, "intValue", "()I"); jvalue arg; jint size = env->CallIntMethodA(arrayObj, sizeMid, &arg); int* cppArray = new int[size]; jmethodID getMid = env->GetMethodID(arrayClass, "get", "(I)Ljava/lang/Object;"); for (int i = 0; i < size; i++) { arg.i = i; jobject element = env->CallIntMethodA(arrayObj, getMid, &arg); appArray[i] = env->CallIntMethodA(element, intValueMid, &arg); // you can't have an unlimited number of active local references. vm->DeleteLocalRef(element); } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.