JNI中字符串的转换

1、String在C端的转换方式一

1)从 Java 到 JNI 到 C/C++,编码的转换过程

  • Java内部使用的是utf-16 16bit 的编码方式
  • JNI里面使用的是utf-8  unicode编码方式,英文是1个字节,中文3个字节
  • C/C++使用的是ascii编码,中文的编码方式 GB2312编码,2个字节

2)声明Java本地方法

public native String chineseChars(String str);

3)C端代码实现

#include <Windows.h>
    
    JNIEXPORT jobject JNICALL Java_com.hubin.jin_Test_chineseChars
    (JNIEnv *env, jobject jobj, jstring in){
    
        jboolean iscp;
        char * c_str = (*env)->GetStringChars(env, in, &iscp);
        if (iscp == JNI_TRUE){
            printf("is copy: JNI_TRUE\n");
        }
        else if (iscp == JNI_FALSE){
            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
        char * rtn = (char *)malloc(sizeof(char)* 2 * length + 3);
        memset(rtn, 0, sizeof(char)* 2 * length + 3);
        int size = 0;
        size = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, length, rtn, sizeof(char)* 2 * length + 3, NULL, NULL);
        /*if (size <= 0)
        {
        printf("size: 0 \n", rtn);
        return NULL;
        }*/
        if (rtn != NULL) {
            free(rtn);
            rtn = NULL;
        }
        (*env)->ReleaseStringChars(env, in, c_str);// JVM 使用。通知JVM c_str 所指的空间可以释放了
        printf("string: %s\n", rtn);
    
        return NULL;
    }

2、String在C端的转换方式二(使用String的构造方法在C端转换java字符串)

1)Java中String有一个构造函数如下

public String(byte bytes[], String charsetName){
    this(bytes, 0, bytes.length, charsetName);
}

2)C端调用此构造函数生成字符串

JNIEXPORT jobject JNICALL Java_com.hubin.jin_Test_chineseChars
    (JNIEnv *env ,jobject jobj,jstring in){
        char *c_str = "马Rong与宝宝"//获取jclass
        jclass str_cls = (*env)->FindClass(env, "java/lang/String");
        //获取String构造的jmethodID
        //([BLjava/lang/String;)V :签名
        jmethodID jmid = (*env)->GetMethodID(env, str_cls, "<init>", "([BLjava/lang/String;)V");
    
        //将jstring转换成jbyteArray
        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);
    }

 

参考自:

https://blog.csdn.net/qq_45649553/article/details/141329790

https://www.jianshu.com/p/0098a8002a9f

 

posted @ 2025-01-13 17:43  Plus301  阅读(142)  评论(0)    收藏  举报