Search code examples
javaandroidc++java-native-interface

Updating jint variable in JNI


When below JNI function is called dataByteArray (of jbyteArray type) is correctly received by the Application (Android/java) calling the function. But sizeDataByteArray (of jint type) is not received by the application. Please let me know what is wrong in below code.

JNIEXPORT jboolean JNICALL Java_com_example_helloworld_Tester_getData
(JNIEnv* env, jclass clasz, jbyteArray dataByteArray, jint sizeDataByteArray) {

    // Some code 
    l_data = “01:02:03:AB:CD:EF”;
    l_data_size = strlen(l_data);
    env->SetByteArrayRegion(dataByteArray, 0, strlen(l_data), (jbyte *) l_data);
    sizeDataByteArray = l_data_size;

    // Some code
    return true; 
}

Solution

  • You can create class for return multiple values from native code:

    public class ReturnValue {
        public final boolean success;
        public final byte[] result;
    
        public ReturnValue(boolean success, byte[] result) {
            this.success = success;
            this.result = result;
        }
    }
    

    return this object from jni you can implement this way:

    JNIEXPORT jobject JNICALL Java_com_example_helloworld_Tester_getData
              (JNIEnv* env, jclass clasz, jbyteArray dataByteArray, jint sizeDataByteArray) {
        const char* cls_name = "com/example/helloworld/ReturnValue";
        // try to obtain ReturnValue class
        jclass cls = env->FindClass(cls_name);
        // if exception occurred return control to java 
        if (env->ExceptionOccurred())
            return NULL;
    
        const char* constructor_signature = "(Z[B)V";
        // try to obtain ReturnValue constructor
        jmethodID constructorId = env->GetMethodID(cls, "<init>", constructor_signature);
        // if exception occurred return control to java 
        if (env->ExceptionOccurred())
                return NULL;
    
        jboolean success = true;
        jbyteArray data = env->NewByteArray(0);
    
        // fill data array...
    
        // create ReturnValue object. If exception occurred, 
        // control will be returned java automatically in this case
        return env->NewObject(cls, constructorId, success, data);
    }
    

    Read additional information about jni method calling and method's signatures in this article.