简体   繁体   中英

JNI:Using Wrapper Types for primitive data types to simulate passing by pointers in C++

The problem is the famous parameter passing problem in JNI.

I want to wrap a c++ code that passes primitive parameters by pointer and I just want to confirm one thing, to make sure that the Wrapper classes can not be use for my problem.

As you all know the Wrapper types like Byte(for byte) and Interger(for int) do not support setter method so i can't use them to set the value of a passes object using the setter,

But, what about the assignment operator?

Is there any way i can call the assignment operator(=) of Wrapper Type "Byte" using JNI in the C++ code?

a codeed sample of the idea is as follows:

JNIEXPORT void JNICALL 
Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj/*A Byte object*/)
{
    jclass cls = (*env)->GetObjectClass(env, obj);
    jmethodID mid = (*env)->GetMethodID(env, cls, "=(or something else you can tell me)", "(B)V");
    if (mid == NULL) {
        return; /* method not found */
    }
    (*env)->CallVoidMethod(env, obj, mid);
}

Yes, you can look up or set the private "value" field of primitive boxes in native code. However, because the field is private, you're not guaranteed that the field be present in all VM implementations. You're also at the mercy of the interpreter making assumptions about the value being passed in remaining unchanged (similar in concept to changing the contents behind a pointer marked "* const").

You're better off passing in a primitive array of length one, pinning the array and obtaining the corresponding pointer for use as the "address" of your primitive to be changed.

Here is an instructional example showing how to mutate an immutable object. You should think hard and long about this and in the end you should not do this.

native void nativeModifyByte(Byte b);

JNIEXPORT void JNICALL Java_nativeModifyByte(JNIEnv * env, jobject o, jobject b) {
   jclass c = (*env)->GetObjectClass(env, b);
   jfieldID fid = (*env)->GetFieldID(env, c, "value", "B");
   jbyte oldVal = (*env)->GetByteField(env, b, fid);
   (*env)->SetByteField(env, b, fid, 42);
}

Usage:

    byte v = 13;
    Byte b = new Byte(v);
    nativeModifyByte(b);
    System.out.println(b);

Output:

    42

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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