http://blog.csdn.net/luhuajcdd/article/details/7750158
在Java中有两类数据类型:primitive types,如,int, float, char;另一种为reference types,如,类,实例,数组。
注意:数组,不管是对象数组还是基本类型数组,都作为reference types存在,有专门的JNI方法取数组中每个元素。
1、void
java的void与JNI的void是一致的。
2、基本数据类型
3、对象类型
相比基本类型,对象类型的传递要复杂得多。不能对Jstring进行直接操作。
- //如下使用方式是错误的,因为jstring不同于C语言中的char *类型。
- Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)
- {
- /* ERROR: incorrect use of jstring as a char* pointer */
- printf("%s", str);
- ...
- }
注意:
- 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中相同。当最高位被设置时,表示多字节编码。
- //调用GetStringUTFChars,把一个Unicode字串转成UTF-8格式字串<pre name="code" class="cpp">Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)
- {
- char buf[128];
- const jbyte *cbyte;
- cbyte= (*env)->GetStringUTFChars(env, str, NULL);
- if (cbyte== NULL) {
- return NULL;
- }
- printf("%s", cbyte);
- (*env)->ReleaseStringUTFChars(env, str, cbyte);
- scanf("%127s", buf);
- return (*env)->NewStringUTF(env, buf);
- </pre>//或者return (*env)->NewStringUTF(env, "hello world");<br>
- }
- <pre></pre>
- <p></p>
- <pre></pre>
- <p></p>
- <p> 上述函数中,有isCopy参数,当该值为JNI_TRUE,将返回str的一个拷贝;为JNI_FALSE将直接指向str的内容。 注意:当isCopy为JNI_FALSE,不要修改返回值,不然将改变java.lang.String的不可变语义。一般会把isCopy设为NULL,不关心Java VM对返回的指针是否直接指向java.lang.String的内容。</p>
- <p> 注意:在调用GetStringChars之后,一定要调用ReleaseStringChars做释放,(Unicode -> UTF-8转换的原因)。不管在调用GetStringChars时为isCopy赋值JNI_TRUE还是JNI_FALSE,因不同JavaVM实现的原因,ReleaseStringChars可能释放内存,也可能释放一个内存占用标记。</p>
- <p></p>
- <span style="font-size:18px; color:#3333FF"><br>
- <br>
- 3.2、GetStringRegion/GetStringUTFRegion函数简单说明</span>
- <p>因为这两个函数不涉及内存操作,所以较GetStringUTFChars使用要简单。也不用进行释放指针之类的操作,非常方便。(推荐使用)</p>
- <p></p>
- <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)
- {
- char outputbuf[128], inputbuf[128];
- int len = (*env)->GetStringLength(env, str);
- (*env)->GetStringUTFRegion(env, str, 0, len, outbuf);
- printf("%s", outputbuf);
- scanf("%s", inputbuf);
- return (*env)->NewStringUTF(env, inbuf);
- }</pre>
- <pre></pre>
- <pre></pre>
- <p></p>
- <pre></pre>
- <pre></pre>
- <br>
- GetStringUTFRegion有两个主要的参数,start 和 length, 这两个参数以Unicode编码计算. 该函数会做边界检查,所以可能抛出StringIndexOutOfBoundsException。<br>
- <p></p>
- <p><br>
- </p>
- <p><span style="font-size:18px; color:#3333FF"><br>
- </span></p>
- <p><span style="font-size:18px; color:#3333FF"><br>
- </span></p>
- <p><span style="font-size:18px; color:#3333FF">3.3、GetStringLength/GetStringUTFLength函数简单说明</span></p>
- <p><br>
- 前者是Unicode编码长度,后者返回的是是UTF编码长度。<br>
- <br>
- <br>
- </p>
- <p><span style="font-size:24px; color:#FF0000">4、数组类型</span></p>
- <p><img src="https://img-my.csdn.net/uploads/201204/30/1335782694_1137.jpg" alt=""></p>
- <p><br>
- </p>
- <p>JNI对每种数据类型的数组都有对应的函数。</p>
- <p><br>
- </p>
- <p><span style="font-size:18px; color:#3333FF; background-color:rgb(255,255,255)">4.1、常见错误操作:</span><br>
- </p>
- <p></p>
- <pre name="code" class="cpp">/* 直接操作数组是错误的 */
- Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
- {
- int i, sum = 0;
- for (i = 0; i < 10; i++) {
- sum += arr[i];
- }
- }</pre>
- <p></p>
- <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>
- <p>参数说明:</p>
- <p><span style="color:#CC0000">env:</span> the JNIEnv interface pointer.<br>
- <span style="color:#CC0000">array:</span> a reference to an array whose elements are to be copied.将要被拷贝的目标数组<ArrayType><br>
- <span style="color:#CC0000">start:</span> the starting index of the array elements to be copied.(数组的起始位置)<br>
- <span style="color:#CC0000">len: </span>the number of elements to be copied.(拷贝元素的个数)<br>
- <span style="color:#CC0000">buf: </span>the destination buffer.存放结果的本地数组<NativeType></p>
- <p>返回值:void<br>
- </p>
- <p><img src="https://img-my.csdn.net/uploads/201204/30/1335783040_8618.jpg" alt=""><br>
- </p>
- <p></p>
- <pre name="code" class="cpp">Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
- {
- jint buf[10];
- jint i, sum = 0;
- (*env)->GetIntArrayRegion(env, arr, 0, 10, buf);
- for (i = 0; i < 10; i++) {
- sum += buf[i];
- }
- return sum;
- }</pre><br>
- <br>
- <p></p>
- <p>JNI中数组的基类为jarray,其他如jintArray都是继承自jarray。</p>
- <p></p>
- <p></p>
- <p><span style="font-size:18px; color:#3333FF">4.3、使用<NativeType> *Get<Type>ArrayElements(JNIEnv *env,<ArrayType> array, jboolean *isCopy);进行数组操作</span></p>
- <p></p>
- <p><img src="https://img-my.csdn.net/uploads/201204/30/1335783395_8845.jpg" alt=""></p>
- <p>参数说明:</p>
- <p><span style="color:#CC0000">env: </span>the JNIEnv interface pointer.array: a reference to the primitive array whose elements are tobe accessed.(目标数组)</p>
- <p><span style="color:#CC0000">isCopy: </span>a pointer to a jboolean indicating whether a function</p>
- <p><br>
- </p>
- <p>返回值:返回指向Java数组的一个直接的指针</p>
- <p><br>
- </p>
- <p></p>
- <p><span style="font-size:16px; color:#009900">使用实例:</span></p>
- <p></p>
- <pre name="code" class="cpp">Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
- {
- jint *carr;
- jint i, sum = 0;
- carr = (*env)->GetIntArrayElements(env, arr, NULL);
- if (carr == NULL) {
- return 0; /* exception occurred */
- }
- for (i=0; i<10; i++) {
- sum += carr[i];
- }
- (*env)->ReleaseIntArrayElements(env, arr, carr, 0);
- return sum;
- }</pre><br>
- )
- <p></p>
- <p><br>
- </p>
- <p>更多数组操作函数:</p>
- <p><img src="https://img-my.csdn.net/uploads/201204/30/1335783812_1174.jpg" alt=""></p>
- <p><br>
- </p>
- <p><span style="font-size:24px; color:#CC0000">5、另外一些有用的宏定义(来自jni.h)</span></p>
- <p></p>
- <pre name="code" class="cpp">#define JNI_FALSE 0
- #define JNI_TRUE 1
- #define JNI_VERSION_1_1 0x00010001
- #define JNI_VERSION_1_2 0x00010002
- #define JNI_VERSION_1_4 0x00010004
- #define JNI_VERSION_1_6 0x00010006
- #define JNI_OK (0) /* no error */
- #define JNI_ERR (-1) /* generic error */
- #define JNI_EDETACHED (-2) /* thread detached from the VM */
- #define JNI_EVERSION (-3) /* JNI version error */
- #define JNI_COMMIT 1 /* copy content, do not free buffer */
- #define JNI_ABORT 2 /* free buffer w/o copying back */
- </pre><br>
- <br>
- <p></p>
- <p><br>
- </p>
- <p><br>
- </p>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- </pre></pre>