我们定义一个native方法用来获取c/c++返回的字符串
package com.aruba.jniapplication;
public class JniDemo3 {
static {
System.load("C:\\Users\\tyqhc\\source\\repos\\JniApplication\\x64\\Debug\\JniApplication.dll");
}
public native String getChinese();
public static void main(String[] args) {
JniDemo3 jniDemo3 = new JniDemo3();
System.out.print(jniDemo3.getChinese());
}
}
c++代码:
JNIEXPORT jstring JNICALL Java_com_aruba_jniapplication_JniDemo3_getChinese
(JNIEnv* env, jobject jobj) {
string chinese = "张三";
return env->NewStringUTF(chinese.c_str());
}
结果如下:
中文乱码了,这是因为Java的编码使用的是UTF-16,中英文每个占2字节(16bit),JNI使用的编码是UTF-8,英文占1个字节,中文占3个字节,C/C++英文编码为ASCII,中文为GB2312,中文占2个字节
字符编码切换.png
解决方法:在c++中使用Java的String的这个构造方法:String(byte bytes[], String charsetName)
JNIEXPORT jstring JNICALL Java_com_aruba_jniapplication_JniDemo3_getChinese
(JNIEnv* env, jobject jobj) {
string chinese = "张三";
//获取String的class
jclass string_clz = env->FindClass("java/lang/String");
//获取构造方法 public String(byte bytes[], String charsetName)
jmethodID jmid = env->GetMethodID(string_clz,"<init>","([BLjava/lang/String;)V");
//创建byte数组并赋值
int size = strlen(chinese.c_str());
jbyteArray bytes = env->NewByteArray(size);
env->SetByteArrayRegion(bytes,0, size, (jbyte *)chinese.c_str());
//charsetName
jstring charsetName = env->NewStringUTF("GB2312");
jstring java_str = (jstring)env->NewObject(string_clz,jmid,bytes, charsetName);
return java_str;
}
网友评论