简体   繁体   中英

2D Arrays in JNI

I'm trying to take a 2D character array as an argument from java code, copy it to an array in C and use the array in my C code as shown:

JNIEXPORT void JNICALL Java_Map_fillMap(JNIEnv *env, jobject thisObj, jcharArray mapFromJava) {
    jsize len = (*env)->GetArrayLength(env, mapFromJava);
    jchar *mapArray = (*env)->GetCharArrayElements(env, mapFromJava, 0);
    int size = sizeof(char) * 19 * 9;
    memcpy(map, mapArray, size);

} When I try to print the 2d array out I get essentially gibberish that appears to be from the .dll library file.

EDIT1 Currently only stores the first value to each of the second dimension arrays. Im unsure of how to get the second for loop to iterate across this dimension and copy each element using memcpy.

JNIEXPORT void JNICALL Java_CGameLogic_fillMap(JNIEnv *env, jobject thisObj, jobjectArray mapFromJava) {
int i;
for(i=0; i<len1; i++) {
     jcharArray array = (*env)->GetObjectArrayElement(env,mapFromJava, i);
     int len2 =(*env)->GetArrayLength(env, array);
     jchar *mapArray = (*env)->GetCharArrayElements(env, array, 0);
     int j;
     for (j=0;j< len2; j++) {
         memcpy(map[i], mapArray, sizeof(char));
     }
  }
}

There are at least two problems that I can see:

  1. You assume that mapFromJava is a jcharArray , but it is not. If the Java type is char[][] then the corresponding JNI type would be jobjectArray , and each element in that jobjectArray is a jcharArray .

  2. You appear to assume that char and jchar have the same size, but they probably don't. jchar is an unsigned 16-bit integer type. A char is usually an 8-bit type (though it might vary depending on the platform).

I've no idea where those magic numbers 19 and 9 come from. You should use the length as returned by GetArrayLength .

If the parameter mapFromJava is a 2D character array, it should be a jobjectArray . Then each of its elements is a char[] . So you need to loop over the elements of mapFromJava , access the 1D array and append their elements to your memory.

jsize len = (*env)->GetArrayLength(env, mapFromJava);
for(int i=0; i<len1; i++) {
     jcharArray array = (jcharArray)env->GetObjectArrayElement(mapFromJava, i);
     // extract the chars from array
}

Problem solved, I forgot that mapArray will hold all the elements for that given array so sizeof(char) needed to be large enough for all characters in the array. eg (sizeof(char)*len2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM