java - 使用 jobjectarray 中的参数调用 NewObject 方法 jni

标签 java c++ java-native-interface

我在使用 C++ 的 JNI 中工作,我创建了一个方法,其中一系列参数作为 jobjectarray 传递到我的 native 方法。我想使用这些参数在 JNI 中调用构造函数。但是,NewObject 方法不接受 jobject 数组,而是使用省略号。我将如何完成这项任务?我不知道在调用方法之前构造函数将采用多少个参数,签名字符串也从 java 传递。我正在调用的构造函数不将数组作为参数,而是可以将同一类的不同版本传递给 c++ 函数,每个版本都包含不同的方法签名。我需要我的 c++ 方法通常能够使用其传递的参数创建任何对象。我使用 visual studio 作为我的 IDE。我知道我可能需要一个 jvalues 数组,但我不明白如何从 jobjectarray 中获取它。

最佳答案

这有点棘手,因为您已经传递了一个 jobjectArray。这意味着原始类型已被装箱(例如 int 是数组中的 java.lang.Integer 实例),并且您必须在将它们传递给构造函数之前取消装箱.

您要做的是解析方法签名字符串(它并没有您想象的那么糟糕),遍历数组中的每个 jobject 并将其转换为相应的类型(必要时使用拆箱转换)。

遗憾的是,JNI 中没有执行拆箱的内置方法,因此您将不得不通过调用装箱值的适当方法(例如 Integer.intValue)手动完成获取 int)。

基本思路:

jobject createObject(JNIEnv *env, jclass clazz, jmethodID constructor, const char *argstr, jobjectArray *args) {
    int n = env->GetArrayLength(args);
    jvalue *values = new jvalue[n];
    const char *argptr = argstr;
    for(int i=0; i<n; i++) {
        jobject arg = env->GetObjectArrayElement(args, i);
        if(*argptr == 'B') { /* byte */
            values[i].b = object_to_byte(arg);
        }
        /* cases for all of the other primitive types...*/
        else if(*argptr == '[') { /* array */
            while(*argptr == '[') argptr++;
            if(*argptr == 'L')
                while(*argptr != ';') argptr++;
            values[i].l = arg;
        } else if(*argptr == 'L') { /* object */
            while(*argptr != ';') argptr++;
            values[i].l = arg;
        }
        argptr++;
        env->DeleteLocalRef(arg);
    }
    return env->NewObjectA(clazz, methodID, values);
}

object_to_byte 和其他转换函数将被定义为对相关类型进行拆箱的函数(例如 object_to_byte 将使用 JNI 调用 java.lang.Byte。 byteValue 在给定对象上)。

关于java - 使用 jobjectarray 中的参数调用 NewObject 方法 jni,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30900507/

相关文章:

java - View 的行为是固定大小的,而不是使用 ConstraintLayout 基于屏幕的动态大小

java - 如何在线程内更改 View

java - 如何检查服务是否已经在android中运行?

c++ - 从 C++ 中的 exec 命令获取字符串输出

java - 在 JNI 中构建数组时在 SetObjectArrayElement 之后使用 DeleteLocalRef

java - C++ JNI 在执行任何 IO/Streams 时崩溃/挂起

java - 巴比伦方法递归异常: stackOverFlow

c++ - 如何在 C++ 中将十六进制转换为 IEEE 754 32 位 float

c++ - code::blocks 出现奇怪的编译器错误

Android - 调用 System.loadLibrary() 导致进程终止