Ответ 1
После много времени, чтобы найти решение. я нашел способ:
В Java utf16
Unicode будет кодироваться с использованием 2 байтов (utf16
). поэтому jstring
будет содержать символы utf16
. std::string
в c++ по сути представляет собой строку байтов, а не символов, поэтому, если мы хотим передать jstring
из JNI
в c++
, мы преобразовали utf16
в байты.
в функциях JNI документа у нас есть 2 функции для получения строки из jstring:
// Returns a pointer to the array of Unicode characters of the string.
// This pointer is valid until ReleaseStringchars() is called.
const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy);
// Returns a pointer to an array of bytes representing the string
// in modified UTF-8 encoding. This array is valid until it is released
// by ReleaseStringUTFChars().
const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy);
GetStringUTFChars
, он вернет измененный utf8.
GetStringChars
вернет jbyte *, мы будем читать код символа из jbytes и конвертировать его в символ в c++
это мое решение (хорошо работало с символами ascii
и utf8
):
std::string jstring2string(JNIEnv *env, jstring jStr) {
if (!jStr)
return "";
const jclass stringClass = env->GetObjectClass(jStr);
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
size_t length = (size_t) env->GetArrayLength(stringJbytes);
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
std::string ret = std::string((char *)pBytes, length);
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
env->DeleteLocalRef(stringJbytes);
env->DeleteLocalRef(stringClass);
return ret;
}