I have a method in JNI C/C++ which takes jstring and returns back jstring some thing like as below,
NATIVE_CALL(jstring, method)(JNIEnv * env, jobject obj
The cause of this problem is directly related to a known UTF-8 bug in the NDK/JNI GetStringUTFChars() function (and probably related functions like NewStringUTF). These NDK functions do not convert supplementary Unicode characters (i.e., Unicode characters with a value of U+10000 and above) correctly. This leads to incorrect UTF-8 and subsequent crashes.
I encountered the crash when handling user input text that contained emoticon characters (see the corresponding Unicode chart). Emoticon characters lie in the Supplementary Unicode character range.
Analysis of the Problem
There is a known NDK bug whereby GetStringUTFChars() incorrectly converts supplementary Unicode characters, producing an incorrect and invalid UTF-8 sequence.
In my case, the resulting string was a JSON buffer. When the buffer was passed to the JSON parser, the parser promptly failed because one of the UTF-8 characters of the extracted UTF-8 had an invalid UTF-8 prefix byte.
Possible Workaround
The solution I've used can be summarized as follows:
In this way we circumvent the problem of extracting supplementary Unicode characters from the Java string. Instead, we convert the data to Base-64 ASCII before calling GetStringUTFChars(), extract the Base-64 ASCII characters using GetStringUTFChars(), and convert the Base-64 data back to wide characters.
I resolved this issue by returning byte array instead of String. On the Java side i am now converting the Byte array to Strings .Works fine! Stay away from using NewStringUTF() for Android 4.0 and above as there is already a bug reported on Google Android NDK.
I had this problem when I change the file Application.mk
From this line:
APP_STL := stlport_static
To:
APP_STL := gnustl_static
Once I changed it back again it fixed the issue.
Strings that you pass to NewStringUTF() need to be valid Modified UTF-8. It looks like the string returned by your start_Inauthroot() function is in some other encoding, or is just returning an invalid string. You need to convert the string to UTF-8 before passing it to JNI functions. Or you could use one of the charset-aware String constructors to build the String object instead.
c
android ndk is working as follows
JNIEXPORT jstring JNICALL
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz,jstring str )
{
jboolean isCopy;
const char* szHTML = (*env)->GetStringUTFChars(env, str, &isCopy);
return (*env)->NewStringUTF(env, szHTML);
}
In my opinion, its not a bug.
NewStringUTF Constructs a new java.lang.String object from an array of characters in modified UTF-8 encoding.
Modified UTF-8 is not standard UTF-8. See Modified UTF-8
In most cases, UTF-8 encoded string is valid Modified UTF-8. Because Modified UTF-8 and UTF-8 are quite similar. However when it comes to Unicode string beyond Basic Multilingual Plane, they are not compatible.
Solution: pass UTF-8 bytes to Java layer and new String(bytes, "UTF-8") then pass jstring to JNI.