jni數據類型

       在Java中有兩類數據類型:primitive types,如,int, float, char;另外一種爲reference types,如,類,實例,數組。java


 注意:數組,無論是對象數組仍是基本類型數組,都做爲reference types存在,有專門的JNI方法取數組中每一個元素。
數組



一、void函數

java的void與JNI的void是一致的。
編碼


二、基本數據類型spa





三、對象類型.net



相比基本類型,對象類型的傳遞要複雜得多。不能對Jstring進行直接操做。
指針

[java] view plaincopycode

  1. //以下使用方式是錯誤的,由於jstring不一樣於C語言中的char *類型。  對象

  2. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  blog

  3. {  

  4. /* ERROR: incorrect use of jstring as a char* pointer */  

  5. printf("%s", str);  

  6. ...  

  7. }  




注意:

[java] view plaincopy

  1. typedef jint jsize;  





3.一、GetStringUTFChars與ReleaseStringUTFChars函數簡單說明(跳到3.2有更方便的函數)

        JNI支持Unicode/UTF-8字符編碼互轉。Unicode以16-bits值編碼;UTF-8是一種以字節爲單位變長格式的字符編碼,並與7- bitsASCII碼兼容。UTF-8字串與C字串同樣,以NULL('\0')作結束符, 當UTF-8包含非ASCII碼字符時,以'\0'作結束符的規則不變。7-bit ASCII字符的取值範圍在1-127之間,這些字符的值域與UTF-8中相同。當最高位被設置時,表示多字節編碼。


[java] view plaincopy

  1. //調用GetStringUTFChars,把一個Unicode字串轉成UTF-8格式字串  

  2.   

  3. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  

  4. {  

  5. char buf[128];  

  6. const jbyte *cbyte;  

  7. cbyte= (*env)->GetStringUTFChars(env, str, NULL);  

  8. if (cbyte== NULL) {  

  9. return NULL;  

  10. }  

  11. printf("%s", cbyte);  

  12. (*env)->ReleaseStringUTFChars(env, str, cbyte);  

  13.   

  14. scanf("%127s", buf);  

  15. return (*env)->NewStringUTF(env, buf);  

  16.   

  17. //或者return (*env)->NewStringUTF(env, "hello world");  

  18.  }  

         上述函數中,有isCopy參數,當該值爲JNI_TRUE,將返回str的一個拷貝;爲JNI_FALSE將直接指向str的內容。 注意:當isCopy爲JNI_FALSE,不要修改返回值,否則將改變java.lang.String的不可變語義。通常會把isCopy設爲 NULL,不關心Java VM對返回的指針是否直接指向java.lang.String的內容。

         注意:在調用GetStringChars以後,必定要調用ReleaseStringChars作釋放,(Unicode -> UTF-8轉換的緣由)。無論在調用GetStringChars時爲isCopy賦值JNI_TRUE仍是JNI_FALSE,因不一樣JavaVM實現 的緣由,ReleaseStringChars可能釋放內存,也可能釋放一個內存佔用標記。

 

 3.二、GetStringRegion/GetStringUTFRegion函數簡單說明

 

 由於這兩個函數不涉及內存操做,因此較GetStringUTFChars使用要簡單。也不用進行釋放指針之類的操做,很是方便。(推薦使用)


[java] view plaincopy

  1. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  

  2. {  

  3.   

  4. char outputbuf[128], inputbuf[128];  

  5. int len = (*env)->GetStringLength(env, str);  

  6. (*env)->GetStringUTFRegion(env, str, 0, len, outbuf);  

  7. printf("%s", outputbuf);  

  8. scanf("%s", inputbuf);  

  9. return (*env)->NewStringUTF(env, inbuf);  

  10. }  


GetStringUTFRegion有兩個主要的參數,start 和 length, 這兩個參數以Unicode編碼計算. 該函數會作邊界檢查,因此可能拋出StringIndexOutOfBoundsException。 


3.三、GetStringLength/GetStringUTFLength函數簡單說明


前者是Unicode編碼長度,後者返回的是是UTF編碼長度。


四、數組類型





JNI對每種數據類型的數組都有對應的函數。


4.一、常見錯誤操做:

[java] view plaincopy

  1. /* 直接操做數組是錯誤的 */  

  2. Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  

  3. {  

  4. int i, sum = 0;  

  5. for (i = 0; i < 10; i++) {  

  6. sum += arr[i];  

  7. }  

  8. }  


4.二、使用

void Get<Type>ArrayRegion(JNIEnv *env,<ArrayType> array, jsize start,jsize len, <NativeType> *buf);

進行操做

參數說明:

env: the JNIEnv interface pointer.

array: a reference to an array whose elements are to be copied.將要被拷貝的目標數組<ArrayType>

start: the starting index of the array elements to be copied.(數組的起始位置)

len: the number of elements to be copied.(拷貝元素的個數)buf:the destination buffer.存放結果的本地數組<NativeType>

返回值:void



[java] view plaincopy

  1. Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  

  2. {  

  3. jint buf[10];  

  4. jint i, sum = 0;  

  5. (*env)->GetIntArrayRegion(env, arr, 0, 10, buf);  

  6. for (i = 0; i < 10; i++) {  

  7. sum += buf[i];  

  8. }  

  9. return sum;  

  10. }  

  11.   

  12. JNI中數組的基類爲jarray,其餘如jintArray都是繼承自jarray。  



4.三、使用<NativeType> *Get<Type>ArrayElements(JNIEnv *env,<ArrayType> array, jboolean *isCopy);進行數組操做



參數說明:

env: the JNIEnv interface pointer.array: a reference to the primitive array whose elements are tobe accessed.(目標數組)

isCopy: a pointer to a jboolean indicating whether a function

返回值:返回指向Java數組的一個直接的指針


[java] view plaincopy

  1. 使用實例:  

  2.   

  3. Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  

  4. {  

  5. jint *carr;  

  6. jint i, sum = 0;  

  7. carr = (*env)->GetIntArrayElements(env, arr, NULL);  

  8. if (carr == NULL) {  

  9. return 0; /* exception occurred */  

  10. }  

  11. for (i=0; i<10; i++) {  

  12. sum += carr[i];  

  13. }  

  14. (*env)->ReleaseIntArrayElements(env, arr, carr, 0);  

  15. return sum;  

  16. }  

  17.   

  18.   

  19. )  


更多數組操做函數:

五、另一些有用的宏定義(來自jni.h)



[java] view plaincopy

  1. #define JNI_FALSE   0  

  2. #define JNI_TRUE    1  

  3.   

  4. #define JNI_VERSION_1_1 0x00010001  

  5. #define JNI_VERSION_1_2 0x00010002  

  6. #define JNI_VERSION_1_4 0x00010004  

  7. #define JNI_VERSION_1_6 0x00010006  

  8.   

  9. #define JNI_OK          (0)         /* no error */  

  10. #define JNI_ERR         (-1)        /* generic error */  

  11. #define JNI_EDETACHED   (-2)        /* thread detached from the VM */  

  12. #define JNI_EVERSION    (-3)        /* JNI version error */  

  13.   

  14. #define JNI_COMMIT      1           /* copy content, do not free buffer */  

  15. #define JNI_ABORT       2           /* free buffer w/o copying back */ 

相關文章
相關標籤/搜索