Java中数组分为两种:

1.基本类型数组

2.对象类型(Object[])的数组(数组中存放的是指向Java对象中的引用)

一个能通用于两种不同类型数组的函数:

GetArrayLength(jarray array);

首先来看一下怎么处理基本类型的数组:

(1) GetArrayElements(Array arr , jboolean* isCopide);

这类函数可以把Java基本类型的数组转换到C/C++中的数组,有两种处理方式,一种是拷贝一份传回本地代码,另一个是把指向Java数组的指针直接传回到本地代码中,处理完本地化的数组后,通过ReleaseArrayElements来释放数组

(2) ReleaseArrayElements(Array arr , * array , jint mode)

用这个函数可以选择将如何处理Java跟C++的数组,是提交,还是撤销等,内存释放还是不释放等

mode可以取下面的值:

0 :对Java的数组进行更新并释放C/C++的数组

JNI_COMMIT :对Java的数组进行更新但是不释放C/C++的数组

JNI_ABORT:对Java的数组不进行更新,释放C/C++的数组

(3) GetPrimittiveArrayCritical(jarray arr , jboolean* isCopied);

(4) ReleasePrimitiveArrayCritical(jarray arr , void* array , jint mode);

也是JDK1.2出来的,为了增加直接传回指向Java数组的指针而加入的函数,同样的也会有同GetStringCritical的死锁的问题

(5) GetArrayRegion(Array arr , jsize start , jsize len , * buffer);

在C/C++预先开辟一段内存,然后把Java基本类型的数组拷贝到这段内存中,这个方法和之前拷贝字符串的GetStringRegion方法的原理是类似的

(6) SetArrayRegion(Array arr , jsize start , jsize len , const * buffer);

把Java基本类型的数组中的指定范围的元素用C/C++的数组中的元素来赋值

(7) Array NewArray(jsize sz)

指定一个长度然后返回相应的Java基本类型的数组

在来看一下怎么处理对象型数组

JNI没有提供直接把Java的对象类型数组(Object[])直接转到C++中的Object[]数组的函数,而是直接通过Get/SetObjectArrayElement这样的函数来对Java的Object[]数组进行操作由于去的对象数组没有进行拷贝,所以不需要释放任何资源

NewObjectArray可以通过指定长度跟初始值来创建某个类的数组

下面来看一下例子:操作两种类型的数组

Java中的代码:

[java] view plaincopy

    1. package com.jni.demo;
    2. public class JNIDemo {
    3. //定义一个int型数组
    4. int[] arrays = {4,3,12,56,1,23,45,67};
    5. //定义Father对象数组
    6. Father[] objArrays = {new Father(),new Father(),new Father()};
    7. //定义一个本地方法
    8. public native void callCppFunction();
    9. public static void main(String[] args)throws Exception{
    10. //调用动态链接库
    11. System.loadLibrary("JNIDemo");
    12. JNIDemo jniDemo = new JNIDemo();
    13. jniDemo.callCppFunction();
    14. }
    15. }
    16. C++中的代码:

      [cpp] view plaincopy

      1. #include
      2. #include"com_jni_demo_JNIDemo.h"
      3. #include
      4. using namespace std;
      5. JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_callCppFunction (JNIEnv * env, jobject obj)
      6. {
      7. //获取Java中数组属性arrays的id
      8. jfieldID fid_arrays = env->GetFieldID(env->GetObjectClass(obj),"arrays","[I");
      9. //获取Java中数组属性arrays的对象
      10. jintArray jint_arr = (jintArray)env->GetObjectField(obj,fid_arrays);
      11. //获取arrays对象的指针
      12. jint* int_arr = env->GetIntArrayElements(jint_arr,NULL);
      13. //获取数组的长度
      14. jsize len = env->GetArrayLength(jint_arr);
      15. //打印数组中的值
      16. cout<<"数组的值为:";
      17. for(int s =0;s<len;s++){ <li="" class="alt"> cout<<int_arr[s]<<','; <li=""> }
      18. cout<<endl; <li="">
      19. //新建一个jintArray对象
      20. jintArray jint_arr_temp = env->NewIntArray(len);
      21. //获取jint_arr_temp对象的指针
      22. jint* int_arr_temp = env->GetIntArrayElements(jint_arr_temp,NULL);
      23. //计数
      24. jint count = 0;
      25. //偶数位存入到int_arr_temp内存中
      26. for(jsize j=0;j<len;j++){ <li="" class="alt"> if(j%2==0){
      27. int_arr_temp[count++] = int_arr[j];
      28. }
      29. }
      30. //打印int_arr_temp内存中的数组
      31. cout<<"数组中位置是偶数的值为:";
      32. for(jsize k=0;k<count;k++){ <li=""> cout<<int_arr_temp[k]<<','; <li="" class="alt"> }
      33. cout<<endl; <li="" class="alt">
      34. //将数组中一段(0-2)数据拷贝到内存中,并且打印出来
      35. jint* buffer = new jint[len];
      36. //获取数组中从0开始长度为3的一段数据值
      37. env->GetIntArrayRegion(jint_arr,0,3,buffer);
      38. cout<<"打印数组中0-3一段值:";
      39. for(int l=0;l<3;l++){
      40. cout<<buffer[l]<<','; <li="" class="alt"> }
      41. cout<<endl; <li="" class="alt">
      42. //将数组中的一段(3-7)设置成一定的值,并且打印出来
      43. jint* buffers = new jint[4];
      44. for(int n=0;n<4;n++){
      45. buffers[n] = n+1;
      46. }
      47. //将buffers这个数组中值设置到数组从3开始长度是4的值中
      48. env->SetIntArrayRegion(jint_arr,3,4,buffers);
      49. //从新获取数组指针
      50. int_arr = env->GetIntArrayElements(jint_arr,NULL);
      51. cout<<"数组中3-7这段的值变成了:";
      52. for(int m=0;m<len;m++){ <li="" class="alt"> cout<<int_arr[m]<<','; <li=""> }
      53. cout<<endl; <li="">
      54. //调用C++标准库中的排序方法sort(...),传递一个数组的开始指针和结束指针
      55. std::sort(int_arr,int_arr+len);
      56. //迭代打印数组中的元素
      57. cout<<"数组排序后的结果:";
      58. for(jsize i=0;i<len;i++){ <li=""> cout<<int_arr[i]<<','; <li="" class="alt"> }
      59. cout<<endl; <li="" class="alt"> //释放数组指针
      60. env->ReleaseIntArrayElements(jint_arr,int_arr,JNI_ABORT);
      61. //获取Java中对象Father数组属性的id
      62. jfieldID fid_obj_arrays = env->GetFieldID(env->GetObjectClass(obj),"objArrays","[Lcom/jni/demo/Father;");
      63. //获取Java中对象数组Father属性objArrays的对象
      64. jobjectArray jobj_arr = (jobjectArray)env->GetObjectField(obj,fid_obj_arrays);
      65. //从对象数组中获取索引值为1的对象Father
      66. jobject jobj = env->GetObjectArrayElement(jobj_arr,1);
      67. //获取Father对象的class对象
      68. jclass clazz_father = env->GetObjectClass(jobj);
      69. //获取Father对象中的function方法的id
      70. jmethodID id_father_function = env->GetMethodID(clazz_father,"function","()V");
      71. //调用Father对象中的function方法
      72. env->CallVoidMethod(jobj,id_father_function);
      73. //在本地创建一个大小为10的对象数组,对象的初始化都是jobj,也就是方法的第三个参数
      74. jobjectArray jobj_arr_temp = env->NewObjectArray(10,env->GetObjectClass(jobj),jobj);
      75. //获取本地对象数组中第4个对象
      76. jobject jobj_temp = env->GetObjectArrayElement(jobj_arr_temp,3);
      77. //调用Father对象中的function方法
      78. env->CallVoidMethod(jobj_temp,id_father_function);
      79. }
      80. 在Eclipse编译运行结果如下:

        不要以为这就结束了,后面还有很多内容呀!

JNI数组操作的更多相关文章

  1. Android JNI 数组操作

    JNI 中有两种数组操作,基础数据类型数组和对象数组,JNI 对待基础数据类型数组和对象数组是不一样的. 基本数据类型数组 对于基本数据类型数组,JNI 都有和 Java 相对应的结构,在使用起来和基 ...

  2. NDK开发之数组操作

    JNI把Java数组当作引用类型来处理,JNI提供了必要的函数来访问和处理Java数组. 下面一个一个来看. 1.创建数组 我们可以使用NewArray函数在原生代码中创建数组实例,其中可以是Int. ...

  3. Javascript数组操作

    使用JS也算有段时日,然对于数组的使用,总局限于很初级水平,且每每使用总要查下API,或者写个小Demo测试下才算放心,一来二去,浪费不少时间:思虑下,堪能如此继续之?当狠心深学下方是正道. 原文链接 ...

  4. JavaScript jQuery 中定义数组与操作及jquery数组操作

    首先给大家介绍javascript jquery中定义数组与操作的相关知识,具体内容如下所示: 1.认识数组 数组就是某类数据的集合,数据类型可以是整型.字符串.甚至是对象Javascript不支持多 ...

  5. php数组操作集锦- 掌握了数组操作, 也就掌握了php

    参考下面的文章, 是很好的: http://www.cnblogs.com/staven/p/5142515.html http://pcwanli.blog.163.com/blog/static/ ...

  6. JavaScript 数组操作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. JavaScript中数组操作常用方法

    JavaScript中数组操作常用方法 1.检测数组 1)检测对象是否为数组,使用instanceof 操作符 if(value instanceof Array) { //对数组执行某些操作 } 2 ...

  8. php 常用数组操作

    php常用的数组操作函数,包括数组的赋值.拆分.合并.计算.添加.删除.查询.判断.排序等 array_combine 功能:用一个数组的值作为新数组的键名,另一个数组的值作为新数组的值 <?p ...

  9. 005-Scala数组操作实战详解

    005-Scala数组操作实战详解 Worksheet的使用 交互式命令执行平台 记得每次要保存才会出相应的结果 数组的基本操作 数组的下标是从0开始和Tuple不同 缓冲数组ArrayBuffer( ...

随机推荐

  1. memory management in oracle 11G R2

    When we talking about memory management in Oracle, we are refering to SGA and PGA. The management me ...

  2. linux下nginx+svn

    http://fengqi.me/unix/23.html 因为没有什么可以定制的, 所以svn直接使用系统自带的包管理软件安装, 以centos系列为例, 命令如下: yum install sub ...

  3. 传智播客JDBC视频教程

    视频介绍: 一些视频教程通过浅显案例来让刚開始学习的人感到轻松,可是课程中编写的代码不能直接应用于项目中:而本套视频教程正好相反,视频解说者李勇老师以技术见长.性格朴实无华.不善于幽默搞笑.李勇老师编 ...

  4. Java 实现抽象工厂模式

    抽象工厂模式 里面有几个概念:抽象工厂.实体工厂.抽象产品.实体产品 抽象工厂:定义创建产品的抽象方法 实体工厂:详细的创建哪种产品 抽象产品:一个接口或基类 实体产品:实现详细功能,或派生 类图 ...

  5. 【Unity 3D】学习笔记三十六:物理引擎——刚体

    物理引擎就是游戏中模拟真是的物理效果.如两个物体发生碰撞,物体自由落体等.在unity中使用的是NVIDIA的physX,它渲染的游戏画面很逼真. 刚体 刚体是一个很很中要的组件. 默认情况下,新创的 ...

  6. mysql的启动和停止

    1.检查数据库服务器是否开启:任务管理器-->后台进程-->查看mysqld是否存在.存在说明开启了,反之没开启 2.管理员运行cmd,输入重启指令:net start **(**数据库名 ...

  7. E20170924-hm

    literal   adj. 照字面的; 原义的; 逐字的; 平实的,避免夸张;   n. [印] 错排,文字上的错误; parameter   n. [数] 参数; <物><数&g ...

  8. php 时间戳和时间的转换

    PHP的时间戳与具体时间转化 三个内置函数: time() //获取UNIX系统时间戳 mktime(hour,minute,second,month,day,year) //将指定时间转化为时间戳 ...

  9. 阿拉伯数字1与英语字母l造成的代码bug

    <img src="./images/demo3/1a.png" /> <img src="./images/demo3/la.png" /& ...

  10. poi 和jxl导出excel(2)

    controller: /** * 导出报表 * @return */ @RequestMapping(value = "/export") @ResponseBody publi ...