转载: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格式字串
  2. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)
  3. {
  4. char buf[128];
  5. const jbyte *cbyte;
  6. cbyte= (*env)->GetStringUTFChars(env, str, NULL);
  7. if (cbyte== NULL) {
  8. return NULL;
  9. }
  10. printf("%s", cbyte);
  11. (*env)->ReleaseStringUTFChars(env, str, cbyte);
  12. scanf("%127s", buf);
  13. return (*env)->NewStringUTF(env, buf);
  14. //或者return (*env)->NewStringUTF(env, "hello world");
  15. }

上述函数中,有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使用要简单。也不用进行释放指针之类的操作,非常方便。(推荐使用)

  1. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)
  2. {
  3. char outputbuf[128], inputbuf[128];
  4. int len = (*env)->GetStringLength(env, str);
  5. (*env)->GetStringUTFRegion(env, str, 0, len, outbuf);
  6. printf("%s", outputbuf);
  7. scanf("%s", inputbuf);
  8. return (*env)->NewStringUTF(env, inbuf);
  9. }

GetStringUTFRegion有两个主要的参数,start 和 length, 这两个参数以Unicode编码计算. 该函数会做边界检查,所以可能抛出StringIndexOutOfBoundsException。

3.3、GetStringLength/GetStringUTFLength函数简单说明

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

4、数组类型

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

4.1、常见错误操作:

  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

  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. 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数组的一个直接的指针

  1. 使用实例:
  2. Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
  3. {
  4. jint *carr;
  5. jint i, sum = 0;
  6. carr = (*env)->GetIntArrayElements(env, arr, NULL);
  7. if (carr == NULL) {
  8. return 0; /* exception occurred */
  9. }
  10. for (i=0; i<10; i++) {
  11. sum += carr[i];
  12. }
  13. (*env)->ReleaseIntArrayElements(env, arr, carr, 0);
  14. return sum;
  15. }

更多数组操作函数:

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

    1. #define JNI_FALSE   0
    2. #define JNI_TRUE    1
    3. #define JNI_VERSION_1_1 0x00010001
    4. #define JNI_VERSION_1_2 0x00010002
    5. #define JNI_VERSION_1_4 0x00010004
    6. #define JNI_VERSION_1_6 0x00010006
    7. #define JNI_OK          (0)         /* no error */
    8. #define JNI_ERR         (-1)        /* generic error */
    9. #define JNI_EDETACHED   (-2)        /* thread detached from the VM */
    10. #define JNI_EVERSION    (-3)        /* JNI version error */
    11. #define JNI_COMMIT      1           /* copy content, do not free buffer */
    12. #define JNI_ABORT       2           /* free buffer w/o copying back */
 

JNI-数据类型的更多相关文章

  1. JNI数据类型(转)

    本文原创,转载请注明出处:http://blog.csdn.net/qinjuning 在Java存在两种数据类型: 基本类型 和 引用类型 ,大家都懂的 . 在JNI的世界里也存在类似的数据类型,与 ...

  2. [转]jni数据类型映射、域描述符说明

    在Java存在两种数据类型: 基本类型 和 引用类型 ,大家都懂的 . 在JNI的世界里也存在类似的数据类型,与Java比较起来,其范围更具严格性,如下: 1.primitive types ---- ...

  3. 006android初级篇之jni数据类型映射

    JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++) 使用JNI的副作用 一旦使用JNI,JAVA程序就丧失了JAV ...

  4. JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系

    转载请注明出处:http://blog.csdn.net/xyang81/article/details/42047899 当我们在调用一个Java native方法的时候.方法中的參数是怎样传递给C ...

  5. NDK学习笔记-JNI数据类型和属性方法的访问

    JNI实现了C/C++与Java的相互访问,那么这篇文章就从C/C++访问Java开始说起 native函数说明 每个native函数,都至少有两个参数(JNIEnv *和jclass或jobject ...

  6. JNI实战(三):JNI 数据类型映射

    在JNI实战(二):Java 调用 C 我们了解了JNI的静态注册和动态注册.也知道我们应该使用动态注册来进行JNI函数与Java方法之间的映射. 示例的映射表的数组为如下: static JNINa ...

  7. Android JNI 学习(三):JNI 数据类型和数据结构

    本文我们来讨论一下JNI如何将Java类型映射到本机C类型. 一.基本数据类型 如下图表整理了Java基本类型和native对应的关系: Java类型 Native类型 描述 boolean jboo ...

  8. Android的NDK开发(3)————JNI数据类型的详解

    在Java中有两类数据类型:primitive types,如,int, float, char:另一种为reference types,如,类,实例,数组. 注意:数组,不管是对象数组还是基本类型数 ...

  9. 基于 Android NDK 的学习之旅-----JNI 数据类型

    经典老套流程,学编程语言东西,先学它最基础的数据类型,JNI也是如此.JNI 定义了一系列基本数据类型和引用数据类型与java想对应. 1.基本数据类型 下面一张表是描述了 Java 基本数据类型和J ...

  10. Android有关JNI 学习(两)为JNI方法名称,数据类型和方法签名的一些知识

    我们知道,使用javah产生c/c++当在头文件,将java定义 native 功能,以产生相应jni层功能,如下面: /* * Class: com_lms_jni_JniTest * Method ...

随机推荐

  1. Dreamweaver CS6破解教程[序列号+破解补丁]

    Dreamweaver CS6破解教程[序列号+破解补丁]   Adobe Dreamweaver CS6中文简体版下载地址:Dreamweaver CS6中文简体版下载[带破解] 破解之前的准备 1 ...

  2. [HIS] HIT行业常用名词及缩写定义

    [HIS] HIT行业常用名词及缩写定义 1.   EHR 居民个人电子健康记录 2.   MPI 居民个人主索引 3.   HIS 医院管理信息系统 4.   CIS 医院临床信息系统 5.   P ...

  3. Android开发之实用小知识点汇总-1

    1.去掉android屏幕中的actionbar: this.requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏 //这个是全屏幕显示的代码 ...

  4. 大四实习准备1_java构造器_android ListView

    2015-4-23 Java构造器 与类名同名;无返回值(void也不行);被不同的修饰符修饰是有区别的;当构造函数被private修饰时,只有本类可访问.其他类可以通过该类的get函数得到对象.如单 ...

  5. [C#] 我的log4net使用手册

    1. log4net简介 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.Java平台下,它还 ...

  6. sencha touch2 动画问题

    最近在review一个项目的代码, 发现返回操作比较乱,很多"从哪里来,到哪里去的操作"被写的一塌糊涂; 按照ios系统的进场出场动画(人家的体验还是很好的,必须借鉴)为标准,使用 ...

  7. 018如何建立自动化框架 how to bulid the framwork

    本讲包括: 一. objective 二. How to bulid 三. Keyview of frawork (关键视图) 四. conclusion automation framwork:自动 ...

  8. Android_1_渐变背景色

    首先创建一个渐变背景色文件drawable-mdpi/bg_color.xml <?xml version="1.0" encoding="utf-8"? ...

  9. SSH权威指南(转载)

    本书是一本介绍通信安全的书籍,如果你想保障你的通信安全,本书能给你一个很好的解决方案.本书从ssh协议介绍起,到具体的开源实现和商业实现.但本书同时介绍开源实现和商业实现,给人感觉比较乱.注意:由于o ...

  10. php获取post中的json数据的实现方法

    最近用到腾讯微博与PHP交互,腾讯把json数据post给PHP(腾讯推送数据时,每条数据是一个json格式的数据包,作为post的数据体(请注意post数据体没有参数,不是key=value形式,整 ...