如何通过 JNI 将 C 字符串表情符号传递给 Java

How to pass a C String Emoji to Java via JNI

本文关键字:符号 Java JNI 何通过 字符串      更新时间:2023-10-16

我正在尝试通过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 中将特殊字符(例如表情符号(传递给 Java?

提前谢谢大家。

从我的回答来看,您可以使用 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);  

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

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

如果您的数据库代码允许您检索 UTF-16 格式的字符串,那么您就一切就绪了。 如果没有,您必须在将它们传递给NewString()之前将它们转换为 UTF-16(就像如果您继续使用NewStringUTF()必须将它们转换为"修改后的"UTF-8 一样(。