JNI系列文章:
JNI系列之入門Hello JNI C(一)
JNI系列之入門Hello JNI C(二)
JNI系列入門之C語言與Java的雙向通信(一)
JNI系列入門之C語言與Java的雙向通信(二)
JNI系列入門之C語言中文字符串亂碼問題
解決方案
思路:
我們在寫java代碼的時候,可以通過new String(byte[], String chasetname)來指定字符集加載唧喉,避免亂碼問題践樱。同樣我們可以利用JNI的特性将硝,在C層使用java的String構造方法拓瞪,實例化一個jstring對象返回給Java使用窿给,這樣C層的中文字符串就不會亂碼了絮供。
實現(xiàn):
// 解決C返回給java的字符串中文亂碼問題
JNIEXPORT jstring JNICALL Java_com_jerry_jnitest_JniTest_resolveMessyCode
(JNIEnv *env, jobject jobj, jstring jstr_in) {
char *c_str = "我是來自于C語言的中文字符串硫戈,我亂碼的毛病被治好了,當然有些生僻字可能還是會亂碼罚随,那就需要換成其它的字符集玉工。";
// 通過調用java的String的構造方法String(byte bytes[], String charsetName)
// 給charsetName設置為GB2312就沒問題了
// 要執(zhí)行new String(xxx)構造方法
// 1. 先獲取String的jclass
jclass cls_string = (*env)->FindClass(env, "java/lang/String");
// 2. 獲取構造函數(shù)的jmethodID
jmethodID mid_constructor = (*env)->GetMethodID(env, cls_string, "<init>",
"([BLjava/lang/String;)V");
// 3. new一個String對象
// 創(chuàng)建一個jbyteArray變量
// 字節(jié)數(shù)組里是一個個的字節(jié)byte即jbyte,
// jbyte又是signed char的別名淘菩,說明jbyte其實就是char字符
// 那么char* 字符串就是char字符的集合遵班,即jbyte的集合,就是jbyteArray
jbyteArray bytes = (*env)->NewByteArray(env, strlen(c_str));
(*env)->SetByteArrayRegion(env, bytes, 0, strlen(c_str), c_str);
jstring jstr_charset = (*env)->NewStringUTF(env, "GB2312");
return (*env)->NewObject(env, cls_string, mid_constructor,
bytes, jstr_charset);
}