Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use JNI to Create, Populate and Return a Java Class Instance

I'm trying to use a JNI function to create a Java class and set some properties of that class using the DeviceId.java constructor method. I'm able to get the constructor method using the GetMethodID, but how would I create a new instance of Device.java and then set the properties (setId and setCache). The goal is to return a fully populated instance of Device.java Object to the caller. Any ideas?

JNI Function:

 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);
    }

Java Class:

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;
    }   
}
like image 772
c12 Avatar asked Apr 12 '12 19:04

c12


People also ask

What is Jclass in JNI?

The jclass instance is your object on which a method will be invoked; you'll need to look up the getName method ID on the Class class, then invoke it on the jclass instance using CallObjectMethod to obtain a jstring result. So in short yes, you just call the getName function and look at the jstring result.

What is JNI Jobject?

jobject thiz means the this in java class. Sometimes if you create a static native method like this. void Java_MyClass_method1 (JNIEnv *, jclass); jclass means the class itself. Follow this answer to receive notifications.

What is JNA vs JNI?

Java Native Access (JNA) is a community-developed library that provides Java programs easy access to native shared libraries without using the Java Native Interface (JNI). JNA's design aims to provide native access in a natural way with a minimum of effort. Unlike JNI, no boilerplate or generated glue code is required.


1 Answers

When you called GetMethodID, you provided the signature for the two-arg constructor. Thus, you just need to pass your jstring and a jbytearray when you call NewObject - for example:

return (*env)->NewObject(env, c, cnstrctr, id, cache);

You don't need to call the setId and setCache methods unless you decide to call the 0-arg constructor - and that just complicates your code since you'll have to call GetMethodID for those and call them. Simpler to continue down the route you're on.

like image 172
Edward Thomson Avatar answered Oct 05 '22 23:10

Edward Thomson