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

标签 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。为什么?

最佳答案

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

GetStringUTFChars [...] Returns a pointer to an array of bytes representing the string in modified UTF-8 encoding

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

In Modified UTF-8 (MUTF-8),[29] the null character (U+0000) uses the two-byte overlong encoding 11000000 10000000 (hexadecimal C0 80), instead of 00000000 (hexadecimal 00). Modified UTF-8 strings never contain any actual null bytes but can contain all Unicode code points including U+0000,[30] which allows such strings (with a null byte appended) to be processed by traditional null-terminated string functions.

关于java - jni无法正确接收包含 '\0'的jstring,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51979832/

相关文章:

java - 在Java中查找直到第n个单词的字符数?

java - ZMQ : Assertion Failed with JZMQ

java - 改造同步调用异步调用

android - 拦截菜单点击

android - 是否可以缩短自定义 View 名称?

java - 如何取回 jobjectArray 的原始元素?

java - ConcurrentSkipListSet内部工作原理,与TreeSet的区别

java - 错误 : Element value must be a constant expression

java - Android & JNI 如何将 Byte[] 数据数组传递给 JNI 并取回 Byte[]

java - JNI : converting unsigned int to jint