`
hm4123660
  • 浏览: 278067 次
  • 性别: Icon_minigender_1
  • 来自: 广州
博客专栏
Dea4ce76-f328-3ab2-b24a-fb268e1eeb75
数据结构
浏览量:69002
社区版块
存档分类
最新评论

jni处理java数组

    博客分类:
  • JNI
阅读更多

              使用jni来操作java中的数组对象。java数组分为基本类型数组和对象数组。在jni中可以使用GetArrayLength(jarray array)来获取这两组数组的长度。

 

 

1.基本类型数组

jni提供两个重要函数来处理java数组

(1) Get<Type>ArrayElements(<Type>Array arr , jboolean* isCopide);

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

 

(2) Release<Type>ArrayElements(<Type>Array arr , <Type>* array , jint mode)

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

mode可以取下面的值:

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

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

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

 

在java中定义整数数组,要求在本地方法实现数组的排序,java代码为:

package com.example;


public class jni_test {

	//在本地方法sayHello里对数组进行排序
	public native void sayHello();
	
	int []my_arr={3,7,9,1,5,2,10,6};
	

	static{
		System.loadLibrary("NativeCode");
	}
	
    public static void main(String[] args) {
    	
    	jni_test temp=new jni_test();
    	
    	temp.sayHello();
    	
    	for(int i=0;i<temp.my_arr.length;i++)
    	{
    		System.out.println(temp.my_arr[i]);
    	}
    }
    	
}

 

c++实现本地方法代码:

#include"com_example_jni_test.h"
#include<iostream>
using namespace std;

JNIEXPORT void JNICALL Java_com_example_jni_1test_sayHello(JNIEnv * evn, jobject obj)
{
	//获取java的Class
	jclass my_class=evn->GetObjectClass(obj);
	//获取数组属性id
	jfieldID arr_id=evn->GetFieldID(my_class,"my_arr","[I");
	//得到数组对象
	jintArray array=(jintArray)evn->GetObjectField(obj,arr_id);
	//把java数组转到c++数组
	jint * my_array=evn->GetIntArrayElements(array,NULL);
	//获取数组长度
	jsize size=evn->GetArrayLength(array);

	//利用冒泡排序进行排序
	bool change;int temp;
	for(int i=0;i<size-1;i++)
	{
		change=false;
		for(int j=size-1;j>i;j--)
		{
			if(my_array[j]<my_array[j-1])
			{
				temp=my_array[j];
				my_array[j]=my_array[j-1];
				my_array[j-1]=temp;
				change=true;
			}
		}
		if(!change)
			break;
	}
	//输出结果
	/*for(int i=0;i<size;i++)
		cout<<my_array[i]<<endl;*/
	//释放c++数组并更新java数组
	evn->ReleaseIntArrayElements(array,my_array,0);
		
}

 

运行结果:



 

2.操作自定义对象数组

自定义Person类

package com.example;

public class Person {
	
	public String name;
	
	public int age;
	
	public Person()
	{
		
	}
	public Person(String name,int age)
	{
		this.name=name;
		this.age=age;
	}
	

	public void Desc()
	{
		System.out.println("姓名: "+this.name+"    年龄:"+this.age);
	}
	

}

 

在本地方法实现Person数组按年龄排序,java代码为

package com.example;


public class jni_test {

	//在本地方法sayHello里对数组进行排序
	public native void sayHello();
	
	Person []my_arr={new Person("小白",20),new Person("小黑",19),
			new Person("小红",21),new Person("小绿",18),new Person("小粉",48)};
	

	static{
		System.loadLibrary("NativeCode");
	}
	
    public static void main(String[] args) {
    	
    	jni_test temp=new jni_test();
    	
    	temp.sayHello();
    	
    }
    	
}

 

本地方法实现Person数组排序代码

#include"com_example_jni_test.h"
#include<iostream>
using namespace std;

JNIEXPORT void JNICALL Java_com_example_jni_1test_sayHello(JNIEnv * evn, jobject obj)
{
	//获取java的Class
	jclass my_class=evn->GetObjectClass(obj);
	//获取数组属性id
	jfieldID arr_id=evn->GetFieldID(my_class,"my_arr","[Lcom/example/Person;");
	//得到数组对象
	jobjectArray array=(jobjectArray)evn->GetObjectField(obj,arr_id);

	//获取数组长度
	jsize size=evn->GetArrayLength(array);

	//cout<<size<<endl;
	  
	//获取Person的数组下标为0的对象
	jobject person1=evn->GetObjectArrayElement(array,0);

	//获取Person的class
	jclass person_class=evn->GetObjectClass(person1);
	jfieldID name_id=evn->GetFieldID(person_class,"name","Ljava/lang/String;");
	jfieldID age_id=evn->GetFieldID(person_class,"age","I");
	jmethodID desc_id=evn->GetMethodID(person_class,"Desc","()V");
    //在本地创建一个大小和java大小一样,对象的初始化都是person1
    jobjectArray jobj_arr = evn->NewObjectArray(size,person_class,person1);
	//把java数组的值赋给此数组
	for(int i=0;i<size;i++)
		evn->SetObjectArrayElement(jobj_arr,i,evn->GetObjectArrayElement(array,i));
   
	//冒泡排序--根据年龄排序
	bool change=false;jobject temp;
	for(int i=0;i<size-1;i++)
	{
		for(int j=size-1;j>i;j--)
		{
			if(evn->GetIntField(evn->GetObjectArrayElement(jobj_arr,j),age_id)<evn->GetIntField(evn->GetObjectArrayElement(jobj_arr,j-1),age_id))
			{
				temp=evn->GetObjectArrayElement(jobj_arr,j);
				evn->SetObjectArrayElement(jobj_arr,j,evn->GetObjectArrayElement(jobj_arr,j-1));
				evn->SetObjectArrayElement(jobj_arr,j-1,temp);
				change=true;
			}
		}
		if(!change)
			break;
		
	}
	
	//调用desc函数输出结果
	for(int i=0;i<size;i++)
		evn->CallVoidMethod(evn->GetObjectArrayElement(jobj_arr,i),desc_id);
}

 

运行结果:



 

 

  • 大小: 7.8 KB
3
0
分享到:
评论

相关推荐

    jni返回对象数组例子

    在java中调用jni中返回的对象或对象数组,即相当于helloword

    java jni 传递结构体

    文档里描述了如何通过jni方法在java与c++代码之间传递非基本类型数据

    JNI学习三-简单类型数组访问

    jni学习——对简单类型数组的访问,本示例通过2中方法介绍java与c之间的通信。

    jni 调用对象以及数组

    本文比较详细 使用jni技术,java里的对象传到c/c++文件里,并且在c/c++里修改后,传到java,以及怎样使用java的listerner,怎么传输数组到c/c++里

    Android中的JNI数组操作教程

    在 Android JNI 基础知识篇提到了 Java 数组类型对应的 JNI 数组类型。比如,Java int 数组对应了 jintArray,boolean 数组对应了 jbooleanArray。 如同 String 的操作一样,JNI 提供了对应的转换函数:...

    JNI开发Java调用C传递int、String、Array类型参数

    JNI开发Java调用C传递int、String、Array类型参数; 详情参考: int类型: (https://blog.csdn.net/niuba123456/article/details/80959892) String类型(https://blog.csdn.net/niuba123456/article/details/80977247);...

    hello-jni.rar_C 调用JAVA_jni 数组

    java和c/c++相互调用实例,包括静态和动态生成c/c++源码,和c/c++数组,线程,对象的使用。

    Android JNI native调用 java层demo TESTJNI.zip

    android jni native C++访问java层数组,java类对象属性和方法,回调接口和线程回调接口 内附可以正常使用的demo

    java_jni.rar_javbi.vcom_jni 数组

    Java本地调用接口DLL的编写样本,涉及数组传递,相关的JAVA和C程序均已包括。

    JNI完全技术手册 带完整书签

    6.数组处理... 89 7.中文处理... 89 8.异常... 91 9.线程和同步访问... 91 10.时间... 92 Chap12:基本JNI调用技术(c/c++与java互调) 93 Chap13:JNI的c代码中,另外一个线程获取 JNIEnv. 96 chap 14:当JNI...

    jni C结构体转JAVA实体类

    可实现将C语言中的结构体转换为JAVA类型的实体类。 目前支持基础数据类型int、long、foloat、double、const char *、bool的转换,也支持将数组装换为JAVA中的ArrayList。目前有个难点是将枚举类型直接转换为JAVA中的...

    JNI技术手册 c/c++调用java

    目录 I. 目录 1 II. java c/cpp互相调用实例(姊妹篇...六、 数组处理: 60 七、 异常: 60 八、 多线程调用 61 Java代码 61 命令行运行:javap -s -p MyTest ,输出: 62 C代码testjava.c: 62 编译: 65 运行结果: 65

    java使用JNI调用C++动态链接库(初学必备)

    本文档在三个方面叙述了java使用JNI调用C++的实例,①java与c++间没有参数传值,②java传入整型,c++返回整型,③java传入两个整型参数,c++返回整型数组。 有需要做以上几方面处理的情下载本文档,简单、清晰、一看...

    jni数据类型转换

    jni数据类型转换例程 1. java向native传递常用基本数据类型 和字符串类型 2. java向native传递数组类型 3. java向native传递自定义java对象 4. java向native传递任意java对象(以向native传递ArrayList为例) 5....

    jni数据传递demo

    jni基本数据类型,数组及对象的传递demo,此demo可推出c,c++调用java方法的实现原理

    JNI调用大全

    Chap1:JNI完全手册......Chap8:如何将java传递过来的jbyteArray转换成C/C++中的BYTE数组... 47 Chap5:使用JNI技术实现java程序调用第三方dll(c/c++)文件的功能... 47 Chap9:如何编写jni方法(转载)... 55

    Java与C语言混合开发技术

    由于Java和C语言的数据类型系统不同,需要进行数据类型的转换,例如将Java中的字符串类型转换为C语言中的字符数组,而C语言中的整数类型转换为Java中的整型。此外,还介绍了异常处理机制的不同,Java使用try-catch...

    JNI++ 用户手册(英文),JNI++ User Guide

    内含JNI++ User Guide.pdf,java调用c++/c操作,可实现基本类型,数组传递,对象调用等功能

    android NDK中c和java大数据交换

    android NDK中c和java大数据交换。以一个很简单的例子,介绍如何在java中申请数组,然后将数组传递给c,最后将处理结果以数组的形式返回给java。希望给新手一点帮助。代码具体解释见本人博客

    JNI文档资料源码_2020_01_28_2.zip

    【Android NDK 开发】JNI 方法解析 ( 字符串数组参数传递 | 字符串遍历 | 类型强转 | Java 字符串与 C 字符串转换 | 字符串释放 ) 博客地址 : https://hanshuliang.blog.csdn.net/article/details/104103097 I...

Global site tag (gtag.js) - Google Analytics