zoukankan      html  css  js  c++  java
  • Android的NDK开发(3)————JNI数据类型的详解

    原文:http://blog.csdn.net/conowen/article/details/7523145


     在Java中有两类数据类型:primitive types,如,int, float, char;另一种为reference types,如,类,实例,数组。


     注意:数组,不管是对象数组还是基本类型数组,都作为reference types存在,有专门的JNI方法取数组中每个元素。



    1、void

    java的void与JNI的void是一致的。


    2、基本数据类型





    3、对象类型



    相比基本类型,对象类型的传递要复杂得多。不能对Jstring进行直接操作。

    1. //如下使用方式是错误的,因为jstring不同于C语言中的char *类型。  
    2. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  
    3. {  
    4. /* ERROR: incorrect use of jstring as a char* pointer */  
    5. printf("%s", str);  
    6. ...  
    7. }  


    注意:

    1. typedef jint jsize;  




    3.1、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中相同。当最高位被设置时,表示多字节编码。


    1. //调用GetStringUTFChars,把一个Unicode字串转成UTF-8格式字串<pre name="code" class="cpp">Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  
    2. {  
    3. char buf[128];  
    4. const jbyte *cbyte;  
    5. cbyte= (*env)->GetStringUTFChars(env, str, NULL);  
    6. if (cbyte== NULL) {  
    7. return NULL;  
    8. }  
    9. printf("%s", cbyte);  
    10. (*env)->ReleaseStringUTFChars(env, str, cbyte);  
    11.   
    12. scanf("%127s", buf);  
    13. return (*env)->NewStringUTF(env, buf);  
    14. </pre>//或者return (*env)->NewStringUTF(env, "hello world");<br>  
    15.  }  
    16. <pre></pre>  
    17. <p></p>  
    18. <pre></pre>  
    19. <p></p>  
    20. <p>         上述函数中,有isCopy参数,当该值为JNI_TRUE,将返回str的一个拷贝;为JNI_FALSE将直接指向str的内容。 注意:当isCopy为JNI_FALSE,不要修改返回值,不然将改变java.lang.String的不可变语义。一般会把isCopy设为NULL,不关心Java VM对返回的指针是否直接指向java.lang.String的内容。</p>  
    21. <p>         注意:在调用GetStringChars之后,一定要调用ReleaseStringChars做释放,(Unicode -> UTF-8转换的原因)。不管在调用GetStringChars时为isCopy赋值JNI_TRUE还是JNI_FALSE,因不同JavaVM实现的原因,ReleaseStringChars可能释放内存,也可能释放一个内存占用标记。</p>  
    22. <p></p>  
    23. <span style="font-size:18px; color:#3333FF"><br>  
    24. <br>  
    25. 3.2、GetStringRegion/GetStringUTFRegion函数简单说明</span>  
    26. <p>因为这两个函数不涉及内存操作,所以较GetStringUTFChars使用要简单。也不用进行释放指针之类的操作,非常方便。(推荐使用)</p>  
    27. <p></p>  
    28. <pre name="code" class="cpp"><pre name="code" class="cpp"><pre name="code" class="cpp">Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  
    29. {  
    30.   
    31. char outputbuf[128], inputbuf[128];  
    32. int len = (*env)->GetStringLength(env, str);  
    33. (*env)->GetStringUTFRegion(env, str, 0, len, outbuf);  
    34. printf("%s", outputbuf);  
    35. scanf("%s", inputbuf);  
    36. return (*env)->NewStringUTF(env, inbuf);  
    37. }</pre>  
    38. <pre></pre>  
    39. <pre></pre>  
    40. <p></p>  
    41. <pre></pre>  
    42. <pre></pre>  
    43. <br>  
    44. GetStringUTFRegion有两个主要的参数,start 和 length, 这两个参数以Unicode编码计算. 该函数会做边界检查,所以可能抛出StringIndexOutOfBoundsException。<br>  
    45. <p></p>  
    46. <p><br>  
    47. </p>  
    48. <p><span style="font-size:18px; color:#3333FF"><br>  
    49. </span></p>  
    50. <p><span style="font-size:18px; color:#3333FF"><br>  
    51. </span></p>  
    52. <p><span style="font-size:18px; color:#3333FF">3.3、GetStringLength/GetStringUTFLength函数简单说明</span></p>  
    53. <p><br>  
    54. 前者是Unicode编码长度,后者返回的是是UTF编码长度。<br>  
    55. <br>  
    56. <br>  
    57. </p>  
    58. <p><span style="font-size:24px; color:#FF0000">4、数组类型</span></p>  
    59. <p><img src="http://my.csdn.net/uploads/201204/30/1335782694_1137.jpg" alt=""></p>  
    60. <p><br>  
    61. </p>  
    62. <p>JNI对每种数据类型的数组都有对应的函数。</p>  
    63. <p><br>  
    64. </p>  
    65. <p><span style="font-size:18px; color:#3333FF; background-color:rgb(255,255,255)">4.1、常见错误操作:</span><br>  
    66. </p>  
    67. <p></p>  
    68. <pre name="code" class="cpp">/* 直接操作数组是错误的 */  
    69. Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  
    70. {  
    71. int i, sum = 0;  
    72. for (i = 0; i < 10; i++) {  
    73. sum += arr[i];  
    74. }  
    75. }</pre>  
    76. <p></p>  
    77. <p><span style="font-size:18px; color:#3333FF">4.2、使用void Get<Type>ArrayRegion(JNIEnv *env,<ArrayType> array, jsize start,jsize len, <NativeType> *buf);进行操作</span></p>  
    78. <p>参数说明:</p>  
    79. <p><span style="color:#CC0000">env:</span> the JNIEnv interface pointer.<br>  
    80. <span style="color:#CC0000">array:</span> a reference to an array whose elements are to be copied.将要被拷贝的目标数组<ArrayType><br>  
    81. <span style="color:#CC0000">start:</span> the starting index of the array elements to be copied.(数组的起始位置)<br>  
    82. <span style="color:#CC0000">len: </span>the number of elements to be copied.(拷贝元素的个数)<br>  
    83. <span style="color:#CC0000">buf: </span>the destination buffer.存放结果的本地数组<NativeType></p>  
    84. <p>返回值:void<br>  
    85. </p>  
    86. <p><img src="http://my.csdn.net/uploads/201204/30/1335783040_8618.jpg" alt=""><br>  
    87. </p>  
    88. <p></p>  
    89. <pre name="code" class="cpp">Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  
    90. {  
    91. jint buf[10];  
    92. jint i, sum = 0;  
    93. (*env)->GetIntArrayRegion(env, arr, 0, 10, buf);  
    94. for (i = 0; i < 10; i++) {  
    95. sum += buf[i];  
    96. }  
    97. return sum;  
    98. }</pre><br>  
    99. <br>  
    100. <p></p>  
    101. <p>JNI中数组的基类为jarray,其他如jintArray都是继承自jarray。</p>  
    102. <p></p>  
    103. <p></p>  
    104. <p><span style="font-size:18px; color:#3333FF">4.3、使用<NativeType> *Get<Type>ArrayElements(JNIEnv *env,<ArrayType> array, jboolean *isCopy);进行数组操作</span></p>  
    105. <p></p>  
    106. <p><img src="http://my.csdn.net/uploads/201204/30/1335783395_8845.jpg" alt=""></p>  
    107. <p>参数说明:</p>  
    108. <p><span style="color:#CC0000">env: </span>the JNIEnv interface pointer.array: a reference to the primitive array whose elements are tobe accessed.(目标数组)</p>  
    109. <p><span style="color:#CC0000">isCopy: </span>a pointer to a jboolean indicating whether a function</p>  
    110. <p><br>  
    111. </p>  
    112. <p>返回值:返回指向Java数组的一个直接的指针</p>  
    113. <p><br>  
    114. </p>  
    115. <p></p>  
    116. <p><span style="font-size:16px; color:#009900">使用实例:</span></p>  
    117. <p></p>  
    118. <pre name="code" class="cpp">Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  
    119. {  
    120. jint *carr;  
    121. jint i, sum = 0;  
    122. carr = (*env)->GetIntArrayElements(env, arr, NULL);  
    123. if (carr == NULL) {  
    124. return 0; /* exception occurred */  
    125. }  
    126. for (i=0; i<10; i++) {  
    127. sum += carr[i];  
    128. }  
    129. (*env)->ReleaseIntArrayElements(env, arr, carr, 0);  
    130. return sum;  
    131. }</pre><br>  
    132. )  
    133. <p></p>  
    134. <p><br>  
    135. </p>  
    136. <p>更多数组操作函数:</p>  
    137. <p><img src="http://my.csdn.net/uploads/201204/30/1335783812_1174.jpg" alt=""></p>  
    138. <p><br>  
    139. </p>  
    140. <p><span style="font-size:24px; color:#CC0000">5、另外一些有用的宏定义(来自jni.h)</span></p>  
    141. <p></p>  
    142. <pre name="code" class="cpp">#define JNI_FALSE   0  
    143. #define JNI_TRUE    1  
    144.   
    145. #define JNI_VERSION_1_1 0x00010001  
    146. #define JNI_VERSION_1_2 0x00010002  
    147. #define JNI_VERSION_1_4 0x00010004  
    148. #define JNI_VERSION_1_6 0x00010006  
    149.   
    150. #define JNI_OK          (0)         /* no error */  
    151. #define JNI_ERR         (-1)        /* generic error */  
    152. #define JNI_EDETACHED   (-2)        /* thread detached from the VM */  
    153. #define JNI_EVERSION    (-3)        /* JNI version error */  
    154.   
    155. #define JNI_COMMIT      1           /* copy content, do not free buffer */  
    156. #define JNI_ABORT       2           /* free buffer w/o copying back */  
    157. </pre><br>  
    158. <br>  
    159. <p></p>  
    160. <p><br>  
    161. </p>  
    162. <p><br>  
    163. </p>  
    164. <pre></pre>  
    165. <pre></pre>  
    166. <pre></pre>  
    167. <pre></pre>  
    168. <pre></pre>  
    169. <pre></pre>  
    170. <pre></pre>  
    171. <pre></pre>  
    172. <pre></pre>  
    173. <pre></pre>  
    174. <pre></pre>  
    175. <pre></pre>  
    176. <pre></pre>  
    177. <pre></pre>  
    178. <pre></pre>  
    179. <pre></pre>  
    180. <pre></pre>  
    181. <pre></pre>  
    182.   
    183. </pre></pre>  

  • 相关阅读:
    Android 7.0 UICC 分析(二)
    Android 7.0 UICC 分析(一)
    痛风有治吗?
    <学习笔记> 数论
    <学习笔记> 高精度 +
    <学习笔记> 线段树
    <学习笔记?> 链表
    <学习笔记> 手打堆模板
    <学习笔记> 倍增 lca
    <学习笔记> 最小生成树 Kruskal
  • 原文地址:https://www.cnblogs.com/java20130722/p/3207327.html
Copyright © 2011-2022 走看看