• 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进行直接操作。

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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. }  



    注意:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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('')做结束符, 当UTF-8包含非ASCII码字符时,以''做结束符的规则不变。7-bit ASCII字符的取值范围在1-127之间,这些字符的值域与UTF-8中相同。当最高位被设置时,表示多字节编码。

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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.2、GetStringRegion/GetStringUTFRegion函数简单说明

     因为这两个函数不涉及内存操作,所以较GetStringUTFChars使用要简单。也不用进行释放指针之类的操作,非常方便。(推荐使用)

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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.3、GetStringLength/GetStringUTFLength函数简单说明

    前者是Unicode编码长度,后者返回的是是UTF编码长度。

    4、数组类型

    JNI对每种数据类型的数组都有对应的函数。

    4.1、常见错误操作:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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.2、使用

    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在CODE上查看代码片派生到我的代码片
     
    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.3、使用<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在CODE上查看代码片派生到我的代码片
     
    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. )  

    更多数组操作函数:

    5、另外一些有用的宏定义(来自jni.h)



    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
      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 */  
     
  • 相关阅读:
    安装 kubenetes-dashboard
    使用kubeadm在Centos7上部署kubernetes1.21.1
    批量重命名
    is_valid重写。返回数据格式统一
    django-序列化参数为空报错问题
    单文件日志测试
    文本、目录 空间清理问题
    数仓数据
    滑动验证码(无原图片处理)
    鸟哥私房菜基础篇
  • 原文地址:https://www.cnblogs.com/huozhong/p/4902827.html
Copyright © 2020-2023  润新知