简体   繁体   English

在Java中的JNI中使用非静态对象

[英]Using non-static objects in jni in java

I am trying to learn jni, and i was wondering how i would make it so that a java object could have some values associated with it in the jni c++ layer. 我正在尝试学习jni,我想知道如何实现它,以便java对象在jni c ++层中可以具有与其相关的一些值。 Currently i have this java code. 目前,我有此Java代码。

public class Test 
{
    static
    {
        Runtime.getRuntime().loadLibrary("JNITests");
    }

    public native void setValue(int value);
    public native int getValue();

    public static void main(String[] args) 
    {
        Test test1 = new Test();
        test1.setValue(34);
        Test test2 = new Test();
        test2.setValue(23);
        System.out.println(test1.getValue());
    }
}

So what i am trying to do is enable each Test object to store a value in the jni using setValue and get getValue, using this c++ code. 所以我想做的就是使用此c ++代码使每个Test对象使用setValue和getgetValue在jni中存储一个值。

#include <jni.h>
#include "Test.h"
int value;

JNIEXPORT void JNICALL Java_Test_setValue(JNIEnv *, jobject, jint newValue)
{
value = newValue;
}

JNIEXPORT jint JNICALL Java_Test_getValue(JNIEnv *, jobject)
{
return value;
}

However, the problem is that when i use setValue on test2 and then i print test1's value it has changesd to what i set test2 to. 但是,问题是,当我在test2上使用setValue时,然后我打印test1的值时,它已更改为我将test2设置为的值。 How do i fix this. 我该如何解决。 I tried mapping each jobject to an int value but that did not work either. 我尝试将每个jobject映射到一个int值,但这也不起作用。

A possible solution may be the use of a dynamically allocated structure in the native code. 可能的解决方案可能是在本机代码中使用动态分配的结构。 For that to work, you have to allocate (for example, in the constructor) some memory that holds the structure. 为此,您必须分配(例如,在构造函数中)一些保存该结构的内存。 The address of that structure is passed back to the Java part and stored in the Java object. 该结构的地址被传递回Java部件并存储在Java对象中。 Then, for getValue and setValue , a parameter is added that holds the memory address of the allocated structure, you can then use for storing the value. 然后,对于getValuesetValue ,将添加一个参数,该参数保存分配的结构的内存地址,然后可用于存储该值。 When destroying the object, you have to free the memory manually. 销毁对象时,必须手动释放内存。


Using your code, the native part may look like: 使用您的代码,本机部分可能看起来像:

#include <cstdlib>
#include <jni.h>
#include "Test.h"

struct data {
    int value;
};

JNIEXPORT void JNICALL Java_Test_setValue0(JNIEnv *, jobject, jlong address, jint newValue)
{
    struct data *ptr = (struct data *)address;
    ptr->value = newValue;
}

JNIEXPORT jint JNICALL Java_Test_getValue0(JNIEnv *, jobject, jlong address)
{
    struct data *ptr = (struct data *)address;
    return ptr->value;
}

JNIEXPORT jlong JNICALL Java_Test_construct0(JNIEnv *, jobject) {
    struct data *ptr = (struct data *)malloc(sizeof(*ptr));
    return (jlong)ptr;
}

JNIEXPORT void JNICALL Java_Test_destruct0(JNIEnv *, jobject, jlong address) {
    struct data *ptr = (struct data *)address;
    free(ptr);
}

And the Java part would then look like: 然后,Java部分将如下所示:

public class Test 
{
    static
    {
        Runtime.getRuntime().loadLibrary("JNITests");
    }

    private long address;

    private native long construct0();
    private native void destruct0(long address);
    private native void setValue0(long address, int value);
    private native int getValue0(long address);

    public Test() {
        this.address = this.construct0();
    }

    @Override
    public void finalize() {
        this.destruct0(this.address);
        super.finalize();
    }

    public void setValue(int value) {
        this.setValue0(this.address, value);
    }

    public int getValue() {
        return this.getValue0(this.address);
    }

    public static void main(String[] args) 
    {
        Test test1 = new Test();
        test1.setValue(34);
        Test test2 = new Test();
        test2.setValue(23);
        System.out.println(test1.getValue());
    }
}

I renamed the native methods to introduce the address parameter without API change. 我重命名了本机方法,以在不更改API的情况下引入address参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM