JNI - 将表示基本Java对象(布尔值)的jobject转换为本机基本类型(bool)

时间:2011-06-23 09:07:16

标签: performance java-native-interface android-ndk

我认为我设法将大部分问题都纳入了这个问题的标题!

我在我的原生C ++代码中从Java中撤回一个Object:

jobject valueObject = env->CallObjectMethod(hashMapObject, hashMapGetMID, keyObject);

我可以使用以下内容检查返回对象是否是本机类型之一:

jclass boolClass = env->FindClass("java/lang/Boolean");
if(env->IsInstanceOf(valueObject, boolClass) == JNI_TRUE) { }

所以,我现在有一个jobject,我知道它是一个布尔值(注意大写字母B) - 问题是,最有效的方法是什么(考虑到我已经在我的本机代码中有了jobject)将它转换为一个bool。类型转换不起作用。

虽然上面的例子是布尔值,但我也想转换字符 - > char,短 - >短,整数 - > int,Float-> float,Double-> double。

(一旦我实现了它,我将发布一个回答,这个做布尔值。布尔值。)

3 个答案:

答案 0 :(得分:5)

你有两个选择。

选项#1是您在自我回答中编写的内容:使用为每个类定义的公共方法来提取原始值。

选项#2更快但不严格合法:直接访问内部字段。对于Boolean,这将是Boolean.value。对于每个原始框类,您有“value”字段的fieldID,您只需直接读取该字段。 (JNI高兴地忽略了它被宣布为私有的事实。你也可以写入“最终”字段并做其他属于“非常糟糕的想法”类别的东西。)

“value”字段的名称不太可能改变,因为这会破坏序列化。所以不建议正式使用,但在实践中,如果需要,你可以侥幸使用它。

无论哪种方式,你应该缓存jmethodID / jfieldID值,而不是每次都查找它们(查找相对昂贵)。

您也可以使用较便宜的IsSameObject函数而不是IsInstanceof,因为box类是“final”。这需要进行额外的GetObjectClass调用以获取valueObject的类,但在进行各种比较之前,您只需执行一次。

顺便说一句,小心你使用“char”。在上面的示例中,您将CallCharMethod(一个16位UTF-16值)的结果转换为char(一个8位值)。记住,char!= jchar(除非你以某种方式为宽字符配置),long!= jlong​​(除非你用64位长编译)。

答案 1 :(得分:1)

如果我没有更多输入,这是我将要使用的解决方案。希望这不是困难,但知道JNI我认为它可能是:

    if     (env->IsInstanceOf(valueObject, boolClass)           == JNI_TRUE)
    {
        jmethodID booleanValueMID   = env->GetMethodID(boolClass, "booleanValue", "()Z");
        bool booleanValue           = (bool) env->CallBooleanMethod(valueObject, booleanValueMID);
        addBoolean(key, booleanValue);
    }
    else if(env->IsInstanceOf(valueObject, charClass)           == JNI_TRUE)
    {
        jmethodID characterValueMID  = env->GetMethodID(charClass, "charValue", "()C");
        char characterValue          = (char) env->CallCharMethod(valueObject, characterValueMID);
        addChar   (key, characterValue);
    }

答案 2 :(得分:0)

一般来说,我写jni是为了获得更好的性能。 如何获得更好的性能?使用asm,原始类型和几个方法调用。 我建议设计你的方法返回类型可以在c / c ++中使用,比如 jint,jlong​​,jboolean,jbyte和jchar等。

冗余函数调用和转换将导致低效且无法维护的实现。