JNI数组操作
在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
- package com.jni.demo;
- public class JNIDemo {
- //定义一个int型数组
- int[] arrays = {4,3,12,56,1,23,45,67};
- //定义Father对象数组
- Father[] objArrays = {new Father(),new Father(),new Father()};
- //定义一个本地方法
- public native void callCppFunction();
- public static void main(String[] args)throws Exception{
- //调用动态链接库
- System.loadLibrary("JNIDemo");
- JNIDemo jniDemo = new JNIDemo();
- jniDemo.callCppFunction();
- }
- }
- C++中的代码:
[cpp] view plaincopy
- #include
- #include"com_jni_demo_JNIDemo.h"
- #include
- using namespace std;
- JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_callCppFunction (JNIEnv * env, jobject obj)
- {
- //获取Java中数组属性arrays的id
- jfieldID fid_arrays = env->GetFieldID(env->GetObjectClass(obj),"arrays","[I");
- //获取Java中数组属性arrays的对象
- jintArray jint_arr = (jintArray)env->GetObjectField(obj,fid_arrays);
- //获取arrays对象的指针
- jint* int_arr = env->GetIntArrayElements(jint_arr,NULL);
- //获取数组的长度
- jsize len = env->GetArrayLength(jint_arr);
- //打印数组中的值
- cout<<"数组的值为:";
- for(int s =0;s<len;s++){ <li="" class="alt"> cout<<int_arr[s]<<','; <li=""> }
- cout<<endl; <li="">
- //新建一个jintArray对象
- jintArray jint_arr_temp = env->NewIntArray(len);
- //获取jint_arr_temp对象的指针
- jint* int_arr_temp = env->GetIntArrayElements(jint_arr_temp,NULL);
- //计数
- jint count = 0;
- //偶数位存入到int_arr_temp内存中
- for(jsize j=0;j<len;j++){ <li="" class="alt"> if(j%2==0){
- int_arr_temp[count++] = int_arr[j];
- }
- }
- //打印int_arr_temp内存中的数组
- cout<<"数组中位置是偶数的值为:";
- for(jsize k=0;k<count;k++){ <li=""> cout<<int_arr_temp[k]<<','; <li="" class="alt"> }
- cout<<endl; <li="" class="alt">
- //将数组中一段(0-2)数据拷贝到内存中,并且打印出来
- jint* buffer = new jint[len];
- //获取数组中从0开始长度为3的一段数据值
- env->GetIntArrayRegion(jint_arr,0,3,buffer);
- cout<<"打印数组中0-3一段值:";
- for(int l=0;l<3;l++){
- cout<<buffer[l]<<','; <li="" class="alt"> }
- cout<<endl; <li="" class="alt">
- //将数组中的一段(3-7)设置成一定的值,并且打印出来
- jint* buffers = new jint[4];
- for(int n=0;n<4;n++){
- buffers[n] = n+1;
- }
- //将buffers这个数组中值设置到数组从3开始长度是4的值中
- env->SetIntArrayRegion(jint_arr,3,4,buffers);
- //从新获取数组指针
- int_arr = env->GetIntArrayElements(jint_arr,NULL);
- cout<<"数组中3-7这段的值变成了:";
- for(int m=0;m<len;m++){ <li="" class="alt"> cout<<int_arr[m]<<','; <li=""> }
- cout<<endl; <li="">
- //调用C++标准库中的排序方法sort(...),传递一个数组的开始指针和结束指针
- std::sort(int_arr,int_arr+len);
- //迭代打印数组中的元素
- cout<<"数组排序后的结果:";
- for(jsize i=0;i<len;i++){ <li=""> cout<<int_arr[i]<<','; <li="" class="alt"> }
- cout<<endl; <li="" class="alt"> //释放数组指针
- env->ReleaseIntArrayElements(jint_arr,int_arr,JNI_ABORT);
- //获取Java中对象Father数组属性的id
- jfieldID fid_obj_arrays = env->GetFieldID(env->GetObjectClass(obj),"objArrays","[Lcom/jni/demo/Father;");
- //获取Java中对象数组Father属性objArrays的对象
- jobjectArray jobj_arr = (jobjectArray)env->GetObjectField(obj,fid_obj_arrays);
- //从对象数组中获取索引值为1的对象Father
- jobject jobj = env->GetObjectArrayElement(jobj_arr,1);
- //获取Father对象的class对象
- jclass clazz_father = env->GetObjectClass(jobj);
- //获取Father对象中的function方法的id
- jmethodID id_father_function = env->GetMethodID(clazz_father,"function","()V");
- //调用Father对象中的function方法
- env->CallVoidMethod(jobj,id_father_function);
- //在本地创建一个大小为10的对象数组,对象的初始化都是jobj,也就是方法的第三个参数
- jobjectArray jobj_arr_temp = env->NewObjectArray(10,env->GetObjectClass(jobj),jobj);
- //获取本地对象数组中第4个对象
- jobject jobj_temp = env->GetObjectArrayElement(jobj_arr_temp,3);
- //调用Father对象中的function方法
- env->CallVoidMethod(jobj_temp,id_father_function);
- }
- 在Eclipse编译运行结果如下:
不要以为这就结束了,后面还有很多内容呀!
JNI数组操作的更多相关文章
- Android JNI 数组操作
JNI 中有两种数组操作,基础数据类型数组和对象数组,JNI 对待基础数据类型数组和对象数组是不一样的. 基本数据类型数组 对于基本数据类型数组,JNI 都有和 Java 相对应的结构,在使用起来和基 ...
- NDK开发之数组操作
JNI把Java数组当作引用类型来处理,JNI提供了必要的函数来访问和处理Java数组. 下面一个一个来看. 1.创建数组 我们可以使用NewArray函数在原生代码中创建数组实例,其中可以是Int. ...
- Javascript数组操作
使用JS也算有段时日,然对于数组的使用,总局限于很初级水平,且每每使用总要查下API,或者写个小Demo测试下才算放心,一来二去,浪费不少时间:思虑下,堪能如此继续之?当狠心深学下方是正道. 原文链接 ...
- JavaScript jQuery 中定义数组与操作及jquery数组操作
首先给大家介绍javascript jquery中定义数组与操作的相关知识,具体内容如下所示: 1.认识数组 数组就是某类数据的集合,数据类型可以是整型.字符串.甚至是对象Javascript不支持多 ...
- php数组操作集锦- 掌握了数组操作, 也就掌握了php
参考下面的文章, 是很好的: http://www.cnblogs.com/staven/p/5142515.html http://pcwanli.blog.163.com/blog/static/ ...
- JavaScript 数组操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JavaScript中数组操作常用方法
JavaScript中数组操作常用方法 1.检测数组 1)检测对象是否为数组,使用instanceof 操作符 if(value instanceof Array) { //对数组执行某些操作 } 2 ...
- php 常用数组操作
php常用的数组操作函数,包括数组的赋值.拆分.合并.计算.添加.删除.查询.判断.排序等 array_combine 功能:用一个数组的值作为新数组的键名,另一个数组的值作为新数组的值 <?p ...
- 005-Scala数组操作实战详解
005-Scala数组操作实战详解 Worksheet的使用 交互式命令执行平台 记得每次要保存才会出相应的结果 数组的基本操作 数组的下标是从0开始和Tuple不同 缓冲数组ArrayBuffer( ...
随机推荐
- bbed改动undo段状态(ORA-01578)
ZBDBA@orcl11g>select * from zbdba; select * from zbdba * ERROR at line 1: ORA-01578: ORACLE data ...
- Linux下使用Vi是方向键变乱码 退格键不能使用的解决方法
在Linux下编辑一些文件.这就涉及到了vi这个编辑器了.在Linux下,初始使用vi的时候有点问题.就是在编辑模式下使用方向键的时候,并不会使光标移动,而是在命令行中出现[A [B [C [D之类的 ...
- starUML 2.5.1 for mac
http://www.macupdate.com/app/mac/55571/staruml/download 一直在windows下使用 star UML,占用资源少,简洁易用. Mac下也能够用了 ...
- 【源代码剖析】tornado-memcached-sessions —— Tornado session 支持的实现(二)
客官您最终回头了! 让我们本着探(zuo)索(si)精神把 session.py 看完吧... 首先看看须要的库: pickle 一个用于序列化反序列化的库(听不懂?你直接看成和 json 一样作用即 ...
- 我所不知的 javascript Object 的一些现象
1.我们都知道对象访问属性有两种方法,一种是使用 . 操作符,使用它添加的属性名必须满足标识符的命名规范:另一种是使用 [] 键访问的方法,可以接受任意UTF-8/Unicode字符串作为属性名,在E ...
- 专訪印度电商Snapdeal CEO:学阿里还是京东
[摘要]印度的互联网正成资本关注下一个投资焦点,也可能成中国互联网企业走向海外的桥头堡.为此.腾讯科技最近将推出走近印度"硅谷"系列文章,帮助大家了解印度互联网. 腾讯科技与Sna ...
- .net连接MySQL数据库的方案与实例演示
以下的文章主要是向大家描述的是.net连接MySQL数据库的实际操作方法与其实例的演示.net连接MySQL数据库的实际操作方案我们主要是将其分成三部分,以下的文章就有其详细内容的描述. http:/ ...
- 自然常数 e 的理解与应用
某彩票中奖率是百万分之一,则一个人买一百万张彩票仍不中奖的概率是: (1−1106)106≈1e e 往往出现在: 许多微小事件带来的总体变化 随机性和无穷多:
- luogu 3796 【模板】AC自动机(加强版)
我太菜了 棒神%%% #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib ...
- 【转载】HashMap实现原理浅析
HashMap和Hashtable的区别 两者最主要的区别在于Hashtable是线程安全,而HashMap则非线程安全Hashtable的实现方法里面都添加了synchronized关键字来确保线程 ...