Reputation: 2307
I can successfully make JNI calls to java. I fetch an array from JNI call. But I cannot access elements inside this array.
Following is my C code:
void jniInvokeMethod(JNIEnv* env, jclass cls, jobject object) {
jstring folderName = (*env)->NewStringUTF(env, "");
jstring token = (*env)->NewStringUTF(env, "Second string");
jmethodID getFolderContents = (*env)->GetMethodID(env, cls, "getFolderContents", "(Ljava/lang/String;Ljava/lang/String;)[Lcom/labsite/rest/model/FolderOrFile;");
if (getFolderContents != 0) {
printf("getFolderContents found\n");
}
jobjectArray folderContents = (*env)->CallObjectMethod(env, object, getFolderContents, folderName, token);
printf("%s\n", folderContents);
jobject* elem = (*env)->GetObjectArrayElement(env, folderContents, 0);
for (int i = 0; i < (*env)->GetArrayLength(env, folderContents); i++) {
jobject folderContentObj = elem[i];
//jclass cls = (*env)->GetObjectClass(env, folderContentObj);
jclass folderOrFileCls = (*env)->FindClass(env, "Lcom/labsite/rest/model/FolderOrFile;");
jmethodID getSizeMethod = (*env)->GetMethodID(env, folderOrFileCls, "getSize", "()J");
(*env)->CallObjectMethod(env, folderContentObj, getSizeMethod);
}
}
Following is the method I call from C:
public class Client {
public FolderOrFile[] getFolderContents(String folderName, String token) {
...
}
}
Visual Studio Debugger stop when (*env)->CallObjectMethod(env, folderContentObj, getSizeMethod)
line is being executed, following error message is provided:
Exception thrown at 0x0000000058A498ED (jvm.dll) in mirror.exe: 0xC0000005: Access violation reading location 0x0000000000000009.
Following is the class being returned:
public class FolderOrFile implements Serializable {
...
private long size;
public long getSize() { return size;}
....
}
I am able to invoke getFolderContents()
methods. But I cannot invoke a getter of an object. What is wrong with getSize()
invocation? (The same thing applies to other methods of FolderOrFile
class.
How should I interpret the error message provided by Visual Studio?
Upvotes: 0
Views: 585
Reputation: 33875
You made a mistake here:
jobject* elem = (*env)->GetObjectArrayElement(env, folderContents, 0);
GetObjectArrayElement
returns a jobject
, not a jobject*
. Since jobject
is a typedef
for a different pointer type the code still compiles though (with a warning, so be sure to turn those on if you haven't!). Then later on, when you try to index this pointer:
jobject folderContentObj = elem[i];
You actually get a more or less random value for the jobject
(whatever happens to be in memory there), so when you try to use that with CallObjectMethod
, you get an access violation.
There is no equivalent to Get<PrimitiveType>ArrayElements
for object arrays (my guess is that this is due do differences in memory layout in the VM internally). So the way to access the elements, is to call GetObjectArrayElement
on every iteration:
jobject folderContentObj = (*env)->GetObjectArrayElement(env, folderContents, i);
Upvotes: 3