使用JNI用C访问Java对象的Java对象 [英] Accessing a Java object in a Java object in C using JNI

查看:204
本文介绍了使用JNI用C访问Java对象的Java对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是比较新的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆