JNI筆記-字符串拼接

參考博客:https://blog.csdn.net/cloverjf/article/details/78851988

記錄一下在JNI中,由java傳遞到JNI,然後拼接返回新字符串的實現方式:

1、簡單粗暴型

extern "C"
JNIEXPORT jstring JNICALL
Java_com_wyl_ndkdemo_JniTest_contactString2(JNIEnv *env, jobject thiz, jstring str1, jstring str2) {
    //1、直接使用GetStringUTFChars方法將傳遞過來的jstring轉爲char*
    char *c1 = (char *) (env->GetStringUTFChars(str1, JNI_FALSE));
    char *c2 = (char *) (env->GetStringUTFChars(str2, JNI_FALSE));
    //2、再使用本地函數strcat 拼接兩個char*對象,然後NewStringUTF轉爲jstring返回去
    char *res = strcat(c1, c2);
    return env->NewStringUTF(res);
}

2、活學活用型
在學習JNI的過程中,慢慢的我們知道在JNI中,是可以訪問使用java裏面的方法的,在JNI中沒有提供直接拼接字符串的方法,但是java中的這類方法可數不勝數的呢,所以:

extern "C"
JNIEXPORT jstring JNICALL
Java_com_wyl_ndkdemo_JniTest_concatString(JNIEnv *env, jobject thiz, jstring str1, jstring str2) {
    //找到String類
    jclass js = env->FindClass("java/lang/String");
    //再找到它裏面的拼接函數的 jmethodID,注意在java中   String concat(String str)
    jmethodID mid = env->GetMethodID(js, "concat", "(Ljava/lang/String;)Ljava/lang/String;");
    //然後調用CallObjectMethod方法,相當於執行了java語句   str1.concat(str2);
    jstring res = (jstring) env->CallObjectMethod(str1, mid, str2);
    return res;
}

3、天馬行空型
這種方法即使用了java方法,也用了JNI函數,混合使用=.=!

extern "C"
JNIEXPORT jstring JNICALL
Java_com_wyl_ndkdemo_JniTest_concatString3(JNIEnv *env, jobject thiz, jstring str1, jstring str2) {
    //調用自定義方法 將jstring 轉爲char*
    char *res1 = Jstring2char(env, str1);
    char *res2 = Jstring2char(env, str2);
    //再使用strcat拼接 
    char *result = strcat(res1, res2);
    return  env->NewStringUTF(result);

}
//注意該方法要先聲明在調用者前面
char *Jstring2char(JNIEnv *env, jstring dst) {
    //1、利用java函數getBytes獲取到jbyteArray對象  
    //注意了  getBytes重載方法有幾個,需要根據參數列表來做相應變化
    jclass js = env->FindClass("java/lang/String");
    jmethodID mid = env->GetMethodID(js, "getBytes", "(Ljava/lang/String;)[B");//signture 
    jstring jcode = env->NewStringUTF("GB2312");
    jbyteArray jba = (jbyteArray) env->CallObjectMethod(dst, mid, jcode);//參數列表
    //2、利用JNI提供的函數來jbyteArray轉爲char*對象
    jsize size = env->GetArrayLength(jba);
    jbyte *jb = env->GetByteArrayElements(jba, JNI_FALSE);
    char *result = NULL;
    if (size > 0) {
        result = static_cast<char *>(malloc(size + 1));//創建對象
        memcpy(result, jb, size);//複製
        result[size] = 0;
    }
    env->ReleaseByteArrayElements(jba, jb, 0);//釋放
    return result;
}

至於優劣性,等到後續更深入學習時在討論。暫時覺得,前兩種可能只適合純粹的拼接場景,第三種的話,更適合需要對內容操作的情況,比如增刪改某個char。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章