【问题标题】:How to pass a C String Emoji to Java via JNI如何通过 JNI 将 C 字符串表情符号传递给 Java
【发布时间】:2020-05-16 19:32:18
【问题描述】:

我正在尝试通过 JNI 将数据库值传递给 Java:

__android_log_print(ANDROID_LOG_ERROR, "MyApp", "c_string >>> %s", cStringValue);

打印: c_string >>> ????????????

env->SetObjectField(jPosRec, myJniPosRec->_myJavaStringValue, env->NewStringUTF(strdup(cStringValue)));  

但是,这会失败且没有错误。

如何在 JNI 中将特殊字符 (例如 emojis) 传递给 Java?

提前谢谢大家。

【问题讨论】:

    标签: java android c++ java-native-interface emoji


    【解决方案1】:

    my answer这里抄袭,你可以使用JNI等效的

    Charset.forName("UTF-8").decode(bb).toString()
    

    如下,其中每一段大致实现一个步骤,最后将你的对象字段设置为结果:

    jobject bb = env->NewDirectByteBuffer((void *) cStringValue, strlen(cStringValue));
    
    jclass cls_Charset = env->FindClass("java/nio/charset/Charset");
    jmethodID mid_Charset_forName = env->GetStaticMethodID(cls_Charset, "forName", "(Ljava/lang/String;)Ljava/nio/charset/Charset;");
    jobject charset = env->CallStaticObjectMethod(cls_Charset, mid_Charset_forName, env->NewStringUTF("UTF-8"));
    
    jmethodID mid_Charset_decode = env->GetMethodID(cls_Charset, "decode", "(Ljava/nio/ByteBuffer;)Ljava/nio/CharBuffer;");
    jobject cb = env->CallObjectMethod(charset, mid_Charset_decode, bb);
    
    jclass cls_CharBuffer = env->FindClass("java/nio/CharBuffer");
    jmethodID mid_CharBuffer_toString = env->GetMethodID(cls_CharBuffer, "toString", "()Ljava/lang/String;");
    jstring str = env->CallObjectMethod(cb, mid_CharBuffer_toString);
    
    env->SetObjectField(jPosRec, myJniPosRec->_myJavaStringValue, str);  
    

    【讨论】:

    • 谢谢。完美运行。
    【解决方案2】:

    首先,您正在泄漏strdup() 分配的内存。完成使用后,您需要将 char* 指针从 strdup() 传递到 free()。不过这种情况下完全不需要调用strdup(),可以直接将cStringValue传递给JNI的NewStringUTF()函数。

    也就是说,JNI 的 NewStringUTF() 函数要求输入 C 字符串为 "modified" UTF-8 格式,而标准 C++ 对此一无所知。虽然可以创建该格式的 C 字符串,但您必须手动创建。由于 Java 字符串使用 UTF-16 接口,而标准 C++ 具有处理 UTF-16 字符串的功能,我强烈建议您改用 JNI 的 NewString() 函数。

    如果您的数据库代码允许您检索 UTF-16 格式的字符串,那么您就大功告成了。如果不是,则必须先将字符串转换为 UTF-16,然后再将它们传递给 NewString()(就像如果继续使用 NewStringUTF(),则必须将它们转换为“修改过的”UTF-8)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-26
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 2011-09-16
      • 2010-11-05
      相关资源
      最近更新 更多