Search code examples
javaandroidc++java-native-interfaceemoji

How to pass a C String Emoji to Java via JNI


I am trying to pass a database value to Java via JNI :

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

prints : c_string >>> 👑👟👓

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

However, this fails without errors.

How can you go about passing special characters (such as emojis) to Java in JNI?

Thank you all in advance.


Solution

  • Cribbing from my answer here, you can use the JNI equivalent of

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

    as follows, where each paragraph roughly implements one step, and the last sets your object field to the result:

    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);