解决在JNI中打印中文字符产生的乱码问题

2019-06-14  本文已影响0人  禅座

要求:

在java当中传入一个字符串,在JNI当中实现打印;

问题:

会出现乱码;

产生原因:

解决方案一

JNIEXPORT jobject JNICALL Java_com_zzqqiang_1Test_chineseChars
(JNIEnv * env, jobject jobj, jstring in) {
    //用于判断当前字符是重新分配内存copy过来的还是直接指向原来的内存
    boolean scp;
    char *c_str = (*env)->GetStringChars(env, in,&iscp);
    if (iscp == JNI_TRUE) {
        printf("is copy:JNI_TRUE\n");
    } else if{
        printf("is copy:JNI_FALSE\n");
    }
    int length = (*env)->GetStringLength(env,in);
    const jchar *jcstr = (*env)->GetStringChars(env,in,NULL);
    if (jcstr == NULL) {
        return NULL;
    }
    //将jchar 转为char,+1是为了放置结束符,*2是为了分配足够的空间
    char *rtn = (char *)malloc(sizeof(char)*length*2+1);
    //初始化内存
    memset(rtn,0,sizeof(char)*length*2+1);
    int size = 0;
    size = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, length, rtn, sizeof(char) * 2*length + 1, NULL, NULL);
    pringf("输出的中文字符为:%s",rtn);
    return NULL;
}


//java
public class JniMain {
    public native void chineseChars(String str);
    
    public static void main(String[] args) {
        JniMain jniMain = new JniMain();
        jniMain.chineseChars("美图秀秀天下第一");
    }
}

解决方案二

利用Java String字符串本身的特性,在构造的时候传入相应编码即可

public String(byte[] bytes, String charsetName) throws UnsupportedEncodingException {
    throw new RuntimeException("Stub!");
}
JNIEXPORT jobject JNICALL Java_com_zzqqiang_1Test_chineseChars
(JNIEnv * env, jobject jobj, jstring in) {
    char * c_str = "美图秀秀天下第一";
    jclass str_cls = (*env)->FindClass(env,"java/lang/String");
    //关于String构造函数的签名可以自己查阅,
    jMethodID jmid = (*env)->GetMethodID(env,str_cls,"<init>","([BLjava/lang/String;)V");
    jbyteArray bytes = (*env)->NewByteArray(env,strlen(c_str));
    // 将Char * 赋值到 bytes
    (*env)->SetByteArrayRegion(env, bytes, 0, strlen(c_str), c_str);
    jstring charsetName = (*env)->NewStringUTF(env,"GB2312");
    return (*env)->NewObject(env,str_cls,jmid,bytes,charsetName);
}
上一篇下一篇

猜你喜欢

热点阅读