從java程序中傳過去的String對象在本地方法中對應的是jstring類型,jstring類型和c中的char*不同,所以如果你直接當做char*使用的話,就會出錯。因此在使用之前需要將jstring轉換成為c/c++中的char*,這里使用JNIEnv的方法轉換.
下面是訪問String的一些方法:
GetStringUTFChars將jstring轉換成為UTF-8格式的char*
GetStringChars將jstring轉換成為Unicode格式的char*
ReleaseStringUTFChars釋放指向UTF-8格式的char*的指針
ReleaseStringChars釋放指向Unicode格式的char*的指針
NewStringUTF創建一個UTF-8格式的String對象
NewString創建一個Unicode格式的String對象
GetStringUTFLengt獲取 UTF-8格式的char*的長度
GetStringLength獲取Unicode格式的char*的長 度
JNI 支持字符串在 Unicode 和 UTF-8 兩種編碼之間轉換。
JNIEXPORT jstring JNICALL Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt) { char buf[128]; const jbyte *str; str = (*env)->GetStringUTFChars(env, prompt, NULL); if (str == NULL) { //不要忘記檢測,否則分配內存失敗會拋出異常 return NULL; /* OutOfMemoryError already thrown */ } printf("%s", str); (*env)->ReleaseStringUTFChars(env, prompt, str); /* We assume here that the user does not type more than * 127 characters */ scanf("%s", buf); return (*env)->NewStringUTF(env, inbuf); }
(1)GetStringUTFChars可以把一個 jstring指針(指向JVM內部的Unicode字符序列)轉化成一個UTF-8格式的C 字符串。
(2)從GetStringUTFChars 中獲取的UTF-8字符串在本地代碼中使用完畢后,要使用ReleaseStringUTFChars 告訴 JVM 這個 UTF-8 字符串不會被使用了,因為這個UTF-8字符串占用的內存會被回收。
(3)JNI 函數 NewStringUTF 在本地方法中創建一個新的java.lang.String字符串對象.這個新創建的字符串對象擁有一個與給定的
UTF-8編碼的C類型字符串內容相同的 Unicode 編碼字符串
UTF-8 字符串以’\0’結尾,而 Unicode 字符串不是。
如果一個jstring指向一個 UTF-8編碼的字符串,為了得到這個字符串的字節長度,可以調用標准 C 函數 strlen,當然也可以用GetStringUTFLength
GetStringChars 和 GetStringUTFChars 函數中的第三個參數需要更進一步的解釋:
const jchar * GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy);
當從 JNI 函數 GetStringChars 中返回得到字符串B時,如果B是原始字符串java.lang.String 的拷貝,則isCopy被賦值為 JNI_TRUE。
如果B和原始字符串指向的是JVM中的同一份數據,則 isCopy被賦值為 JNI_FALSE。
當 isCopy值為JNI_FALSE時,本地代碼決不能修改字符串的內容,否則JVM中的原始字符串也會被修改,這會打破 JAVA語言中字符串不可變的規則。
通常,因為你不必關心 JVM 是否會返回原始字符串的拷貝,你只需要為 isCopy傳遞NULL作為參數。