Как передать C String Emoji в Java через JNI - PullRequest
0 голосов
/ 31 января 2020

Я пытаюсь передать значение базы данных в Java через JNI:

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

печатает: c_string >>> ???

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

Однако это происходит без ошибок.

Как вы можете go передать специальные символы (например, смайлики) до Java в JNI?

Спасибо всем заранее.

Ответы [ 2 ]

2 голосов
/ 31 января 2020

Ссылаясь на мой ответ здесь, вы можете использовать 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);  
1 голос
/ 31 января 2020

Во-первых, вы теряете память, выделенную на strdup(). Вам нужно передать указатель char* от strdup() до free(), когда вы закончите использовать его. Однако в этой ситуации вообще нет необходимости вызывать strdup(), вы можете передать cStringValue непосредственно в NewStringUTF() функцию JNI.

При этом * JNI NewStringUTF() Функция требует, чтобы входная строка C была в «модифицированном» формате UTF-8 , о котором стандарт C ++ ничего не знает. Хотя можно создать строку C в этом формате, вам придется сделать это вручную. Поскольку строки Java используют интерфейс UTF-16, а в стандартном C ++ есть средства для работы со строками UTF-16, я настоятельно рекомендую вместо этого использовать функцию NewString() JNI.

Если код вашей базы данных позволяет вам извлекать строки в формате UTF-16, тогда все готово. Если нет, вам придется преобразовать строки в UTF-16, прежде чем передавать их в NewString() (так же, как вам нужно будет преобразовать их в «модифицированный» UTF-8, если вы продолжите использовать NewStringUTF()).

...