【问题标题】:jstring(JNI) to std::string(c++) with utf8 characters带有 utf8 字符的 jstring(JNI) 到 std::string(c++)
【发布时间】:2017-06-08 18:30:07
【问题描述】:

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

这是我的代码。它适用于非 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;
}

【问题讨论】:

  • 请将您的解决方案移至答案部分
  • 无论如何,对我来说,您的代码并非异常中立
  • StackOverflow 不是共享站点。如果您有值得分享的内容,请以合适的 QA 格式发布 - 发布问题,然后共享代码会回答。

标签: android c++ c++11 java-native-interface share


【解决方案1】:

经过很长时间才找到解决方案。我找到了一条路:

在 java 中,unicode char 将使用 2 个字节 (utf16) 进行编码。所以jstring 将包含字符utf16。 c++ 中的std::string 本质上是一个字节串,而不是字符,所以如果我们想将jstring 从JNI 传递到c++,我们需要将utf16 转换为字节。

在文档JNI functions中,我们有两个函数可以从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,它会返回一个modified utf8。

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

这是我的解决方案(适用于 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;
}

【讨论】:

  • 对不起,“if (!jStr)”是什么意思?
  • 意思是“如果 (jStr == nullptr)”
【解决方案2】:
jboolean isCopy;
const char *convertedValue = (env)->GetStringUTFChars(yourJStringParam, &isCopy);
std::string string = std::string(convertedValue, length)

这很好用。试试看吧。

【讨论】:

【解决方案3】:

解释在这里:

http://www.club.cc.cmu.edu/~cmccabe/blog_jni_flaws.html https://developer.android.com/training/articles/perf-jni(区域呼叫)

jsize
string_j2c(JNIEnv *env, jstring p, char *buffer) {

    if (buffer != NULL) {
        // Returns the length (the count of Unicode characters) of a
        // Java string.
        const jsize len = (*env).GetStringLength(p);

        // Translates 'len' number of Unicode characters into modified
        // UTF-8 encoding and place the result in the given buffer.
        (*env).GetStringUTFRegion(p, 0, len, buffer);

        // Returns JNI_TRUE when there is a pending exception;
        // otherwise, returns JNI_FALSE.
        const jboolean is_error = (*env).ExceptionCheck();

        if (is_error == JNI_TRUE) {
            return -1;
        }
    }

    // Returns the length in bytes of the modified UTF-8
    // representation of a string.
    const jsize len = (*env).GetStringUTFLength(p);
    return len;
}

const jsize len = string_j2c(env, p, NULL);
char buffer[len];
const jsize ret = string_j2c(env, p, buffer);

if (ret == -1) { // error
}
else {
    __android_log_print(ANDROID_LOG_DEBUG, "Native", "%s", buffer);
}

【讨论】:

    【解决方案4】:

    我将@Nikhil Tambe 的答案调整为如下所示:

    jboolean isCopy;
    const char *convertedValue = (env)->GetStringUTFChars(yourJStringParam, &isCopy);
    std::string str = convertedValue;
    

    这很有效!因为在标准 C++ 中,字符串文字的类型是 const char *,因此您可以将 const char *convertedValue 分配给 std::string 类型的变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      相关资源
      最近更新 更多