如何通过 JNI 将 C 字符串表情符号传递给 Java
How to pass a C String Emoji to Java via JNI
我正在尝试通过 JNI 将数据库值传递给 Java:
__android_log_print(ANDROID_LOG_ERROR, "MyApp", "c_string >>> %s", cStringValue);
prints : c_string >>>
env->SetObjectField(jPosRec, myJniPosRec->_myJavaStringValue, env->NewStringUTF(strdup(cStringValue)));
但是,这没有错误地失败了。
如何在 JNI 中将特殊字符 (例如表情符号) 传递给 Java?
提前谢谢大家。
首先,您正在泄漏 strdup()
分配的内存。使用完后,您需要将 char*
指针从 strdup()
传递到 free()
。但是,这种情况下根本不需要调用strdup()
,可以直接将cStringValue
传给JNI的NewStringUTF()
函数。
也就是说,JNI 的 NewStringUTF()
function requires the input C string to be in "modified" UTF-8 format, which standard C++ knows nothing about. While it is possible to create a C string in that format, you will have to do so manually. Since Java strings use a UTF-16 interface, and standard C++ has facilities to work with UTF-16 strings, I strongly suggest you use JNI's NewString()
函数。
如果您的数据库代码允许您检索 UTF-16 格式的字符串,那么您已经准备就绪。如果不是,则必须先将字符串转换为 UTF-16,然后再将它们传递给 NewString()
(就像如果继续使用 NewStringUTF()
,则必须将它们转换为 "modified" UTF-8 一样) ).
抄袭自 此处,您可以使用
的 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);
我正在尝试通过 JNI 将数据库值传递给 Java:
__android_log_print(ANDROID_LOG_ERROR, "MyApp", "c_string >>> %s", cStringValue);
prints : c_string >>>
env->SetObjectField(jPosRec, myJniPosRec->_myJavaStringValue, env->NewStringUTF(strdup(cStringValue)));
但是,这没有错误地失败了。
如何在 JNI 中将特殊字符 (例如表情符号) 传递给 Java?
提前谢谢大家。
首先,您正在泄漏 strdup()
分配的内存。使用完后,您需要将 char*
指针从 strdup()
传递到 free()
。但是,这种情况下根本不需要调用strdup()
,可以直接将cStringValue
传给JNI的NewStringUTF()
函数。
也就是说,JNI 的 NewStringUTF()
function requires the input C string to be in "modified" UTF-8 format, which standard C++ knows nothing about. While it is possible to create a C string in that format, you will have to do so manually. Since Java strings use a UTF-16 interface, and standard C++ has facilities to work with UTF-16 strings, I strongly suggest you use JNI's NewString()
函数。
如果您的数据库代码允许您检索 UTF-16 格式的字符串,那么您已经准备就绪。如果不是,则必须先将字符串转换为 UTF-16,然后再将它们传递给 NewString()
(就像如果继续使用 NewStringUTF()
,则必须将它们转换为 "modified" UTF-8 一样) ).
抄袭自
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);