带有utf8字符的jstring(JNI)到std :: string(c ++)

Mr *_*rry 15 c++ java-native-interface android share c++11

如何将jstring(JNI)转换为std::string(c ++)utf8字符?

这是我的代码.它适用于非utf8字符,但utf8字符有问题.

std::string jstring2string(JNIEnv *env, jstring jStr){
    const char *cstr = env->GetStringUTFChars(jStr, NULL);
    std::string str = std::string(cstr);
    env->ReleaseStringUTFChars(jStr, str);
    return str;
}
Run Code Online (Sandbox Code Playgroud)

Mr *_*rry 19

经过很长时间才找到解决方案.我找到了一种方式:

在java中,unicode char将使用4个字节(utf16)进行编码.jstring容器字符也是如此utf16.std::string在C++本质上是字节,而不是一串字符,所以如果我们想通过jstringJNIc++,我们必须转换utf16为字节.

在文档JNI函数中,我们有两个函数从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);
Run Code Online (Sandbox Code Playgroud)

GetStringUTFChars,它将返回修改后的utf8.

GetStringChars 将返回jbyte*,我们将从jbytes读取char代码并将其转换为c ++中的char

这是我的解决方案(适用于asciiutf8字符):

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;
}
Run Code Online (Sandbox Code Playgroud)


Nik*_*mbe 5

jboolean isCopy;
const char *convertedValue = (env)->GetStringUTFChars(yourJStringParam, &isCopy);
std::string string = std::string(convertedValue, length)
Run Code Online (Sandbox Code Playgroud)

这样很好。试试看。

  • 不要忘记调用 ReleaseStringUTFChars!std::string 复制 const char* 中的字符,因此在创建字符串后不再需要 conversionValue 。 (6认同)