使用JNI用C访问Java对象的Java对象 [英] Accessing a Java object in a Java object in C using JNI
问题描述
我是比较新的JNI和已经得到了下来整数和数组中的Java对象使用JNI搞乱的基本知识。一个Java对象中现在我试图修改/访问Java对象。
I'm relatively new to JNI and have gotten down the basics of messing with integers and arrays in Java objects using JNI. Now I'm trying to modify/access a Java object within a Java object.
我一直在互联网上搜索和堆栈溢出和还没有找到如何做到这一点。
I've been searching on the internet and on Stack Overflow and have yet to find out how to do this.
下面的例子。
在Java的:
public class ObjectOne
{
private byte[] buff;
...
...
}
public class ObjectTwo
{
private ObjectOne obj;
...
...
}
在JNI,我怎么通过ObjectTwo访问迷,从ObjectOne?我想这样的事情...
In JNI, how do I access "buff" from ObjectOne through ObjectTwo? I tried something like this...
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");
}
这是我做错了任何帮助吗?
Any help on what I'm doing wrong?
推荐答案
当您试图code,你可以轻松地添加一些断言是这样的:
When trying your code you could easily add some assertions like this:
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 /包
)
Doing so you will first see that the first fid
will be NULL. That is because the ObjectTwo
class does not have any fields of type java.lang.Object
. You should change the line to look like this (but add the correct packages instead of com/package
):
fid = (*env)->GetFieldID(env, clazz, "obj", "Lcom/package/ObjectOne;");
如果您再次运行,你会发现,FID不再为空,并断言会通过。
If you run again you will find that the fid is no longer null and the assertion will pass.
正如其他人建议我相信 javascsicommand
应 objectTwo
。
As others have suggested I believe that the javascsicommand
should be objectTwo
.
现在的下一个地方,断言失败是 bufferJObject
。这是因为该领域存在,但对象是NULL,如果你检查你的Java code,你会发现, OBJ
字段从不实例是无效
。
Now the next place where the assertion will fail is on bufferJObject
. That is because the field exists but the object is NULL and if you check your java code you will notice that the obj
field is never instantiated and is null
.
修改Java code到这样的事情:
Change your java code to something like this:
public class ObjectTwo
{
private ObjectOne obj = new ObjectOne();
...
...
}
您现在将通过断言,甚至通过所有其他的断言。
You will now pass the assertion and even pass all other assertions.
要总结一下你访问一个空
对象,并尝试调用就可以了反思:
To summarize you were accessing a null
object and trying to invoke reflection on it:
bufferClazz = (*env)->GetObjectClass(env, bufferJObject); <-- The bufferJObject was NULL
这篇关于使用JNI用C访问Java对象的Java对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!