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. What are Unix swap (.swp) files?

    原文: http://www.networkworld.com/article/2931534/it-management/what-are-unix-swap-swp-files.html ---- ...

  2. 从一个input点击引起的思考

    一个input或者select标签都是有属于自己的disabled属性的,这个属性很少被使用,但是我们在项目实际开发的过程中也会遇到,比如我选择之后就让他置灰不可以变动了,那么久可利用js动态设置.对 ...

  3. Cocos2d-x教程(26)-Cocos2d-x + Lua脚本实现大地图缩放功能

    欢迎增加 Cocos2d-x 交流群: 193411763 视频教程地址:http://www.tudou.com/programs/view/qRiOfppMghM/ 转载请注明原文出处:http: ...

  4. Java 实现简答的单链表的功能

    作者:林子木  博客网址:http://blog.csdn.net/wolinxuebin 參考网址:http://blog.csdn.net/sunsaigang/article/details/5 ...

  5. Setup Script in SoapUI - 停止项目运行 (abort project)

    TestSuite需要依赖一个先决条件(比如Login) 当Login失败则立即停止Project运行 在Project的Setup Script的代码如下 import com.eviware.so ...

  6. Scikit-learn库中的数据预处理(一)

    数据标准化:当单个特征的样本取值相差甚大或明显不遵从高斯正态分布时,标准化表现的效果较差.实际操作中,经常忽略特征数据的分布形状,移除每个特征均值,划分离散特征的标准差,从而等级化,进而实现数据中心化 ...

  7. 【POJ 1958】 Strange Towers of Hanoi

    [题目链接] http://poj.org/problem?id=1958 [算法] 先考虑三个塔的情况,g[i]表示在三塔情况下的移动步数,则g[i] = g[i-1] * 2 + 1 再考虑四个塔 ...

  8. hadoop-Combiner作用用法

    文章来源http://blog.csdn.net/ipolaris/article/details/8723782 reduce的输入每个key所对应的value将是一大串1,但处理的文本很多时,这一 ...

  9. IBatis异常: Cannot find class: VARCHAR

    今天再项目里添加新功能时,突然爆出 org.springframework.beans.factory.BeanCreationException: Error creating bean with ...

  10. ckeditor详细设置

    CKEditor 3 JavaScript API Documentation : http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.con ...