jni无法正确接收jstring包含'\ 0'

时间:2018-08-23 06:47:20

标签: java android java-native-interface

在jni中:

jstring JNICALL native_encrypt(JNIEnv* env, jstring plainstr) {
    if(plainstr == NULL) {
        return NULL;
    }
    const char* plain_str = (*env)->GetStringUTFChars(env, plainstr, NULL);
    LOG_ERROR("plain_str:%s", plain_str);
    int i=0;
    int n = strlen(plain_str);
    //android_log
    LOG_ERROR("plain_str len=%d", n);
    for (i=0;i<n;i++){
        LOG_ERROR("%d", plain_str[i]);
    }
    jstring encryptedstr = encrypt(env, plain_str);
    (*env)->ReleaseStringUTFChars(env, plainstr, plain_str);

    return encryptedstr;
}

在Java(android)

String js = "abc\0def\0a0123456789";
System.out.println("jstring=" + js + ", LEN=" + js.length() + ", " + Arrays.toString(js.getBytes(Charset.forName("utf-8"))));
System.out.println("encrypt jstring=" + native_encrypt(js));

java的输出是

  

jstring =abc��def��a0123456789,LEN = 19,[97,98,99,0,100,101,102,0,97,48,49,50,51,52,53,54, 55,56,57]

jni的输出是

  

plain_str:abc��def��a0123456789       plain_str len = 21       97       98       99       192       128       100       101       102       192       128       97       48       49       50       51       52       53       54       55       56       57

“ \ 0”更改为两个字符:192,128。为什么?

1 个答案:

答案 0 :(得分:2)

请参阅:https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFChars

  

GetStringUTFChars [...]返回一个指针,该指针指向以修改的UTF-8编码表示字符串的字节数组

并且:https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8

  

在修改的UTF-8(MUTF-8)中,[29]空字符(U + 0000)使用两字节超长编码11000000 10000000(十六进制C0 80),而不是00000000(十六进制00)。修改后的UTF-8字符串从不包含任何实际的空字节,但可以包含所有Unicode代码点,包括U + 0000 [30],该点允许此类字符串(附加了空字节)由传统的以空终止的字符串函数进行处理。 >