【问题标题】:Convert JNI types to Native types将 JNI 类型转换为 Native 类型
【发布时间】:2011-09-12 14:53:16
【问题描述】:

虽然有关于将 jstring 转换为本机字符串 (string nativeString = env->GetStringUTFChars(jStringVariable, NULL);) 的文档,但我找不到将 jboolean 转换为 bool 或将 jint 转换为 @987654326 的示例@。

谁能建议这是如何实现的?

【问题讨论】:

    标签: java-native-interface android-ndk


    【解决方案1】:

    您只需要使用 C 样式转换将 jint 转换为 intjbooleanbool(如果您使用 C99 bool 类型)或 uint8_t(如果您使用 std int 类型)或 unsigned char 相同。

    打开$NDK_ROOT/platforms/android-8/arch-arm/usr/include/jni.h,你会看到jintjboolean等只是typedefs。

    【讨论】:

    • 你的意思是 int intValue = (int) jIntValue; ?
    • 没错,C 风格的演员可以完成这项工作
    • 我不知道,你问的是如何将jint 转换为int,答案是jint 只是typedefint 或@987654337 @ 取决于平台
    • 你是对的。我会问一个单独的问题来解决由此产生的问题。
    • int 到 jint 和 bool 到 jboolean 也一样吗?
    【解决方案2】:

    要将jboolean(可能仅包含值JNI_FALSEJNI_TRUE)转换为原生bool,我会使用这样的东西:

    (bool)(jboolean == JNI_TRUE)
    

    如果 jboolean 可能不是来自 JVM,那么测试 jboolean != JNI_FALSE 可能会被认为更安全。

    【讨论】:

    • 这有点限制。我认为 (bool)(java_rtn != JNI_FALSE) 更好,因为某些库可能会返回 true,因为某些整数不等于 1(并且 JNI_TRUE == 1)。
    • @greg7gkb 嗯,什么?!你在说什么“图书馆”? JVM 应该保证从 Java 传递给 C 的 boolean 将正好是 0 或 1。
    • @Alnitak 如果出现错误,Windows API 的大多数函数都返回 0,如果函数成功,则返回 0 以外的任何值。所以,一个函数可以成功并返回一个值,例如,28,使用这个答案的代码,它将被转换为 false。
    • @BloodShura 问题是关于将 Java 的 jboolean 转换为原生的,而不是反过来,所以 Windows API 在这里可能做什么是无关紧要的。
    • @Alnitak 问题在于,jboolean 并不总是直接来自 JVM。您可以将 bool 类型(可以来自任何其他来源,例如 Windows API)转换为 jboolean,然后,此 jboolean 可能具有比 0 和 1 更多的值。那么,为了安全起见,最好检查该值是否不为零,而不是检查是否等于一。
    【解决方案3】:

    同样的问题 - 已修复。就我而言,我使用的是 openFrameworks,所以我不知道这是否适用于非 openFrameworks 项目(尚未测试)。但是,外部函数中的前两个参数似乎始终是“env”和“thiz”,并且需要为每个新的外部函数显式定义这些参数。

    extern "C"{
    
    // casts the variable properly
    void Java_com_package_JavaClass_someFunction( JNIEnv*  env, jobject  thiz, jboolean yourBool ){
        myTestApp->someFunction( (bool) yourBool );
    }
    
    // "yourBool" will always be "1" because its taking the spot of "thiz" which is not null
    void Java_com_package_JavaClass_someFunction( JNIEnv*  env, jboolean yourBool ){
        myTestApp->someFunction( (bool) yourBool );
    }
    
    // "yourBool" will always be "1" because its taking the spot of "env" which is not null
    void Java_com_package_JavaClass_someFunction( jboolean yourBool ){
        myTestApp->someFunction( (bool) yourBool );
    }
    
    
    }
    

    【讨论】:

      【解决方案4】:

      奇怪的是jchar。它被定义为unsigned short,根据您的编译设置,它可能等同于也可能不等同于wchar_t。根据您的底层平台,使用 UTF8 字符串可能会更好。至少对于 ASCII 字符子集,这些按位等效于 ASCII。

      然而,在 Windows 和 Mac OS/Cocoa 上,本机宽字符串表示正好是 unsigned short。 Java 字符串自然适合这种情况。

      【讨论】:

        【解决方案5】:

        如果您只想在 if(..) 语句中使用它,这对我有用,无需转换:

        if (jboolean == true) {
          return true;
        } else {
          return false;
        }
        

        【讨论】:

          【解决方案6】:

          这对我有用:

          bool isValue = bool(jbooleanValue);
          

          【讨论】:

          • 添加一些评论为什么这会回答 OP 的问题将有助于未来的人们试图找到类似问题的答案。
          猜你喜欢
          • 1970-01-01
          • 2011-11-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-18
          • 2022-08-18
          • 2014-02-20
          • 2014-09-02
          相关资源
          最近更新 更多