use*_*243 5 c c++ java java-native-interface
我对JNI比较陌生,并且已经解决了使用JNI在Java对象中弄乱整数和数组的基础知识.现在我正在尝试修改/访问Java对象中的Java对象.
我一直在互联网和Stack Overflow上搜索,还没有找到如何做到这一点.
这是一个例子.
在Java中:
public class ObjectOne
{
private byte[] buff;
...
...
}
public class ObjectTwo
{
private ObjectOne obj;
...
...
}
Run Code Online (Sandbox Code Playgroud)
在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");
}
Run Code Online (Sandbox Code Playgroud)
对我做错的任何帮助?
mab*_*aba 15
在尝试代码时,您可以轻松添加一些这样的断言:
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);
}
Run Code Online (Sandbox Code Playgroud)
这样做,您将首先看到第一个fid将为NULL.那是因为ObjectTwo该类没有任何类型的字段java.lang.Object.您应该将行更改为这样(但添加正确的包而不是com/package):
fid = (*env)->GetFieldID(env, clazz, "obj", "Lcom/package/ObjectOne;");
Run Code Online (Sandbox Code Playgroud)
如果再次运行,您会发现fid不再为null,并且断言将通过.
正如其他人所说,我相信javascsicommand应该是objectTwo.
现在断言失败的下一个地方正在启用bufferJObject.这是因为该字段存在,但该对象为NULL,如果您检查您的Java代码,您将注意到该obj字段从未实例化,并且是null.
将您的Java代码更改为以下内容:
public class ObjectTwo
{
private ObjectOne obj = new ObjectOne();
...
...
}
Run Code Online (Sandbox Code Playgroud)
您现在将传递断言,甚至传递所有其他断言.
总结一下,您正在访问一个null对象并尝试在其上调用反射:
bufferClazz = (*env)->GetObjectClass(env, bufferJObject); <-- The bufferJObject was NULL
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10699 次 |
| 最近记录: |