參考博客: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。