Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNI : create an jobjectArray without knowing the size in advance

I would like to return an array of strings from C to Java using JNI. I saw that I could use NewObjectArray() this way:

JNIEXPORT jobjectArray JNICALL Java_Array_initStringArray(JNIEnv *env, jclass cls, jint size)
{
 jclass stringCls = (*env)->FindClass(env, "Ljava/lang/String;");
 if (stringCls == NULL) return NULL;

 jstringArray result = (*env)->NewObjectArray(env, size, StringCls, NULL);
 if (result == NULL) return NULL; 
 ...
}

But here, I don't know the int size parameter: I don't know the number of strings I'll use to populate my array. So is there a way to create an jobjectArray without knowing in advance the size of the array?

Something like creating an empty array and then adding jobject one by one to that array?


EDIT : solution using an ArrayList as Edwin suggested

jclass arrayClass = (*jenv)->FindClass(jenv, "java/util/ArrayList");
  if (arrayClass == NULL)   return NULL;

jmethodID mid_init =  (*jenv)->GetMethodID(jenv, arrayClass, "<init>", "()V");
  if (mid_init == NULL) return NULL;

jobject objArr = (*jenv)->NewObject(jenv, arrayClass, mid_init));
  if (objArr == NULL) return NULL;

mid_add = (*jenv)->GetMethodID(jenv, arrayClass, "add", "(Ljava/lang/Object;)Z");
  if (mid_add == NULL) return NULL;

Then in a loop I create an jobject obj for each new object I need to add to the arrayList:

jboolean jbool = (*jenv)->CallBooleanMethod(jenv, objArr, mid_add, obj);
  if (jbool == NULL) return NULL;
like image 225
leochab Avatar asked Apr 29 '11 13:04

leochab


1 Answers

If you want to have the backing store (the array) grow as you add to it, use a java.util.ArrayList. It might mean a few more JNI calls (to set up the object), but in your case it sounds like it's worth the effort.

like image 184
Edwin Buck Avatar answered Oct 16 '22 01:10

Edwin Buck