java - 使用JNI访问C中Java对象中的Java对象

标签 java c++ c java-native-interface

我是 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/

相关文章:

java - 使用 Yosemite Mac osX(Webstorm、intellij)使 Jetbrains 崩溃

java - JToolBar 等价于frame.setJMenuBar(ie.createMenuBar()); 的是什么?

c++ - 通过 SQL 查询/C++ 插入 'image' 数据类型值

c++ - GCC和Clang中模板类如何继承子类

java - 获取未报告的异常尝试调用函数播放 .WAV 时出现异常

C++, boost : how to emulate matrix container memory structure?

c - 是否可以在 C 中模拟对象方法?

char数组到C中的LPCTSTR转换

c++ - C代码仍然被认为是C++吗?

java - 当我从一个 fragment 滑动到另一个 fragment 时如何做一个事件