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

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

作者: 禅座 | 来源:发表于2019-06-14 13:49 被阅读0次

    要求:

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

    问题:

    会出现乱码;

    产生原因:

    • Java 采用Utf-16编码 字符占2字节 16bit
    • JNI采用Utf-8编码 因为占用1字节 中文3字节
    • C/C++采用Ascii编码 中文采用GB2312编码,中文2个字节

    解决方案一

    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);
    }
    

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/ogzlxctx.html