I have the following Java native method declaration:
static native Object nativeCallObjectMethod
(Object object, Method method, Object... params);
This produces the following C function declaration (note that Object... params is mapped to jobjectArray params):
JNIEXPORT jobject JNICALL Java_pkg_Cls_nativeCallObjectMethod
(JNIEnv *env, jclass ignored, jobject obj, jobject method,
jobjectArray params) { }
I want to call method with params as arguments:
jmethodID methodID = (*env)->FromReflectedMethod(env, method);
return (*env)->CallObjectMethod(env, obj, methodID, params);
However, params is of type jobjectArray, whereas the JNI methods callObjectMethod* can only take one of the following three forms:
CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
There is no form of this method that takes jobjectArray in the last argument position. I assume that method 2 is the one I want to call, and I realize jobjectArray elements may need unboxing to produce an array of jvalue values. I found this suggestion of how to implement this: https://stackoverflow.com/a/30961708/3950982
However, I can't believe there is no standard way to unbox a jobjectArray into a jvalue array using the JNI API. Surely there must be a built-in way to achieve this, since Java does this internally when using reflection?
How can I solve this, preferably without reinventing the wheel?
I wrote a method for unboxing a
jobjectArrayinto ajvalue[]array:For speed, global refs to classes like
Integer.classandint.classare obtained as follows on initialization:Call the unboxing method like this:
The above code does not handle varargs. The full version that handles varargs can be seen in the Narcissus library (I am the author).