我是 JNI 的新手,已经掌握了使用 JNI 处理 Java 对象中的整数和数组的基础知识。现在我正在尝试修改/访问 Java 对象中的 Java 对象。
我一直在互联网和 Stack Overflow 上搜索,但还没有找到如何执行此操作。
这是例子。
在 Java 中:
public class ObjectOne
{
private byte[] buff;
...
...
}
public class ObjectTwo
{
private ObjectOne obj;
...
...
}
在 JNI 中,如何通过 ObjectTwo 从 ObjectOne 访问“buff”?我试过这样的东西......
JNIEXPORT void JNICALL Java_accessBuffThroughObjectTwo(JNIEnv *env, jobject obj, jobject objectTwo)
{
jclass clazz;
jclass bufferClazz;
jobject bufferJObject;
clazz = (*env)->GetObjectClass(env, objectTwo);
fid = (*env)->GetFieldID(env, clazz, "obj", "Ljava/lang/Object;");
bufferJObject = (*env)->GetObjectField(env, javascsicommand, fid);
bufferClazz = (*env)->GetObjectClass(env, bufferJObject); <-- Fails here for Access Violation
fid = (*env)->GetFieldID(env, bufferClazz, "buff", "[B");
}
对我做错了什么有帮助吗?
最佳答案
在尝试您的代码时,您可以轻松地添加一些断言,如下所示:
JNIEXPORT void JNICALL Java_accessBuffThroughObjectTwo(JNIEnv *env, jobject obj, jobject objectTwo) {
jclass clazz;
jclass bufferClazz;
jobject bufferJObject;
jfieldID fid;
clazz = (*env)->GetObjectClass(env, objectTwo);
assert(clazz != NULL);
fid = (*env)->GetFieldID(env, clazz, "obj", "Ljava/lang/Object;");
assert(fid != NULL);
bufferJObject = (*env)->GetObjectField(env, javascsicommand, fid);
assert(bufferJObject != NULL);
bufferClazz = (*env)->GetObjectClass(env, bufferJObject);
assert(bufferClazz != NULL);
fid = (*env)->GetFieldID(env, bufferClazz, "buff", "[B");
assert(fid != NULL);
}
这样做,您首先会看到第一个 fid
将为 NULL。这是因为 ObjectTwo
类没有任何 java.lang.Object
类型的字段。您应该将行更改为如下所示(但添加正确的包而不是 com/package
):
fid = (*env)->GetFieldID(env, clazz, "obj", "Lcom/package/ObjectOne;");
再次运行会发现fid不再为null,断言通过。
正如其他人所建议的那样,我认为 javascsicommand
应该是 objectTwo
。
现在下一个断言失败的地方是 bufferJObject
。这是因为该字段存在但对象为 NULL,如果您检查 Java 代码,您会注意到 obj
字段从未实例化并且为 null
。
将您的 java 代码更改为如下内容:
public class ObjectTwo
{
private ObjectOne obj = new ObjectOne();
...
...
}
您现在将通过断言,甚至通过所有其他断言。
总而言之,您正在访问一个 null
对象并尝试对其调用反射:
bufferClazz = (*env)->GetObjectClass(env, bufferJObject); <-- The bufferJObject was NULL
关于java - 使用JNI访问C中Java对象中的Java对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11803927/