使用JNI创建,填充和返回Java类实例

c12*_*c12 11 java java-native-interface

我正在尝试使用JNI函数创建Java类,并使用DeviceId.java构造函数方法设置该类的一些属性.我能够使用GetMethodID获取构造函数方法,但是如何创建Device.java的新实例然后设置属性(setId和setCache).目标是将完全填充的Device.java对象实例返回给调用者.有任何想法吗?

JNI功能:

 JNIEXPORT jobject JNICALL Java_com_test_getID(JNIEnv *env, jclass cls) 
    {
        jmethodID cnstrctr;
        jclass c = (*env)->FindClass(env, "com/test/DeviceId");
        if (c == 0) {
            printf("Find Class Failed.\n");
         }else{
            printf("Found class.\n");
         }

        cnstrctr = (*env)->GetMethodID(env, c, "<init>", "(Ljava/lang/String;[B)V");
        if (cnstrctr == 0) {
            printf("Find method Failed.\n");
        }else {
            printf("Found method.\n");
        }

        return (*env)->NewObject(env, c, cnstrctr);
    }
Run Code Online (Sandbox Code Playgroud)

Java类:

package com.test;

public class DeviceId {
    private String id;
    private byte[] cache;

        public DeviceId(){}
    public DeviceId(String id, byte[] cache){
        this.id=id;
        this.cache=cache;
    }

    public byte[] getCache() {
        return cache;
    }

    public void setCache(byte[] cache) {
        this.cache = cache;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }   
}
Run Code Online (Sandbox Code Playgroud)

Edw*_*son 9

当你打电话时GetMethodID,你提供了两个arg构造函数的签名.因此,你只需要在你打电话时传递你的jstring和- 例如:jbytearrayNewObject

return (*env)->NewObject(env, c, cnstrctr, id, cache);
Run Code Online (Sandbox Code Playgroud)

除非您决定调用0-arg构造函数,否则不需要调用setIdsetCache方法 - 这只会使代码复杂化,因为您必须GetMethodID调用它们并调用它们.更容易继续沿着您所在的路线行进.

  • 应该有一个NewGlobalRef,因为当我们返回时它会超出范围. (2认同)