jni 无法正确接收包含 '\0' 的 jstring
jni cannot receive jstring contains '\0' correctly
在 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[=11=]def[=11=]a0123456789";
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.
在 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[=11=]def[=11=]a0123456789";
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.