我对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");
}
我做错了什么吗?
在尝试代码时,您可以轻松地html" target="_blank">添加一些断言,例如:
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
问题内容: 我有一个JNI方法来访问返回一个Integer对象的java方法。我不想返回原始的int类型,因为将修改此代码以处理通用对象。以下是我所拥有的。我无法获得所传递的Integer的值。C ++端的输出类似于 如何获取在C ++端传递的Integer对象的实际值? 请帮忙。 谢谢, -H GenericPeer.cpp GenericPeer.java 资料库 Test.java(主类)
问题内容: 看一下这个例子: 如何从子对象中访问随机对象? 问题答案: 让类将自己的实例传递给该类。 经典Occam剃刀。
我有一组在工作中需要用C/C++运行的java类。 而且,由于我对java还很陌生,所以我要一步一步地走。我已经能够用string、int double等调用java,但最终的结果是返回一个字节数组(一个pdf文档),所以我尝试返回一个简单的两个元素的字节数组。 下面是Java:
问题内容: 我正在浏览一个文档,遇到了一个称为的术语。我发现它是一个数据访问对象。有人可以解释一下这实际上是什么吗? 我知道这是一种用于从不同类型的源访问数据的接口,在我的这项小小的研究中,我碰到了一个称为数据源或数据源对象的概念,事情变得一团糟。 我真的很想知道a 的编程含义。如何使用?任何从最基本的东西解释这个概念的页面的链接也将受到赞赏。 问题答案: 数据访问对象基本上是一个对象或接口,可提
我在浏览一个文档时遇到了一个叫做的术语。我发现它是一个数据访问对象。有人能解释一下这到底是什么吗?
问题内容: 我已经搜索了很多,但找不到特定的解决方案。关于stackoverflow也有一些问题,但我无法找到满意的答案,所以我再次询问。 我在java中有一个如下类。 我知道如何在Java中使用线程。 现在我想同时执行这两个操作。为此,我创建了两个线程类,一个在运行中执行addString()逻辑,另一个在执行deleteString()逻辑中。我在每个线程的构造函数中传递mylist,但是在对