1. 程式人生 > >NDK基本資料型別及操作

NDK基本資料型別及操作

1.資料型別

2.引用型別

3.資料和物件型別的基本操作

(1)string型別,在native中並不提供修改string型別函式,因為java中也是步伐修改存在的string的型別即string型別在java中不變型別的

jstring javaString;
javaString = (*env)->NewStringUTF(env, "Hello World!");


逆過程

const jbyte* str;
jboolean isCopy;
str = (*env)->GetStringUTFChars(env, javaString, &isCopy);


即讓是物件(引用型別),我們就要去釋放他的引用,這個細節是java程式設計師比較容易忘記的

(*env)->ReleaseStringUTFChars(env, javaString, str);


(2)資料型別

通過New<Type>Array類建立

type範圍:Int, Char, Boolean, etc

jintArray javaArray;
javaArray = (*env)->NewIntArray(env, 10);
if (0 != javaArray) {
/* You can now use the array. */
}

接著就是操作資料中的元素

從java中拷貝

jint nativeArray[10];
(*env)->GetIntArrayRegion(env, javaArray, 0, 10, nativeArray);


逆過程

(*env)->SetIntArrayRegion(env, javaArray, 0, 10, nativeArray);


或者直接全部拷貝

<span style="font-family:TheSansMonoConNormal;color:#000000;FONT-VARIANT: normal; FONT-STYLE: normal; FONT-SIZE: 9pt">jint* nativeDirectArray;
<span style="font-family:TheSansMonoConNormal;color:#000000;FONT-VARIANT: normal; FONT-STYLE: normal; FONT-SIZE: 9pt">jboolean isCopy;</span>
</span>
nativeDirectArray = (*env)->GetIntArrayElements(env, javaArray, &isCopy);


別忘記釋放

Release<Type>ArrayElemens


例如

(*env)->ReleaseIntArrayElements(env, javaArray, nativeDirectArray, 0);

記得資料的內容可能被我們已經修改了,所以追後的一個引數告訴系統如何處理


(3).位元組型別

 位元組型別是比較重要而且是需要注意的,因為位元組沒有大小,他需要你指定大小,在java中之所以string為不變型別就是這個原因吧,因為string儲存必須指定記憶體大小

所以我們動態申請

unsigned char* buffer = (unsigned char*) malloc(1024);
...
jobject directBuffer;
directBuffer = (*env)->NewDirectByteBuffer(env, buffer, 1024);


我們直接申請了1024個位元組來的buffer來構建jobject

接著我們也可以獲取

unsigned char* buffer;
buffer = (unsigned char*) (*env)->GetDirectBufferAddress(env,
directBuffer);


記得free申請的記憶體

4.獲取java class的屬性

(1)獲取class

jclass clazz;
clazz = (*env)->GetObjectClass(env, instance);


instance對應java的型別

(2)獲取欄位

jfieldID instanceFieldId;
instanceFieldId = (*env)->GetFieldID(env, clazz,"instanceField", "Ljava/lang/String;");


特殊的---靜態型別

jfieldID staticFieldId;
staticFieldId = (*env)->GetStaticFieldID(env, clazz,"staticField", "Ljava/lang/String;");


對於物件GetStatic<Type>Field

jstring staticField;
staticField = (*env)->GetStaticObjectField(env, clazz, staticFieldId);


5.呼叫方法

呼叫方法有兩種

思路 找到方法的ID,再call方法

(1)呼叫例項方法

instanceMethodId = (*env)->GetMethodID(env, clazz,"instanceMethod", "()Ljava/lang/String;");

(2)呼叫靜態方法

staticMethodId = (*env)->GetStaticMethodID(env, clazz,"staticMethod", "()Ljava/lang/String;");


接著呼叫方法,方法會有返回型別,所以使用

(1)呼叫例項方法

Call<Type>Method 

如:

jstring instanceMethodResult;
instanceMethodResult = (*env)->CallStringMethod(env,instance, instanceMethodId);

(2)呼叫靜態方法

CallStatic<Type>Field 

6.屬性或型別的簽名

如上我們

jstring staticField;
staticField = (*env)->GetStaticObjectField(env, clazz, staticFieldId);

其中staticFieldId是指定java中的型別的,這樣系統才知道我們從java中拿了什麼樣的資料

就像

staticMethodId = (*env)->GetStaticMethodID(env, clazz,"staticMethod", "()Ljava/lang/String;");

告訴系統返回String

其實說了這麼多,你只要明白,對於屬性型別,他就要有個可以形容這個是什麼型別屬性的描述,而方法就用簽名描述,我們可以使用javap

看看我們java物件的屬性和方法的簽名