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

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虚拟机(JVM)的内存管理和类型转换的理解。 1. **创建本地方法** 在Java类中,我们可以声明一个本地方法,使用`native`关键字,例如: ```java public class JniObjArrayExample { ...

    jni返回对象数组例子

    本示例主要探讨如何在JNI中创建并返回一个对象数组到Java层。 首先,我们需要定义一个Java类,这个类将包含JNI方法的声明。例如,我们可能有一个`Person`类,表示一个人的信息: ```java public class Person { ...

    JNI-array-arg.rar_JNI-array-arg_jni_jni 数组_jni array

    在JNI中,这两种类型的数组处理方式有所不同。 对于基本类型数组,JNI提供了专门的函数来获取和设置数组元素,例如`GetIntArrayElements`、`SetIntArrayRegion`等。这些函数允许开发者在本地代码中直接操作Java数组...

    java_jni.rar_javbi.vcom_jni 数组

    6. **内存管理**:注意在JNI中处理Java数组时,必须正确地管理内存。对于通过`Get...ArrayElements`获取的元素,需要在操作完成后释放,以避免内存泄漏。 在提供的压缩包中,`WdmDynoFilter_wdf`可能是一个与...

    androidjni编程,java和c层的互相通信传递数据

    - `数组处理`:可以使用JNI处理Java数组,包括基本类型数组和对象数组。例如,`GetIntArrayElements()`用于获取整型数组的元素。 - `字符串处理`:Java的`String`在JNI中表示为`jstring`,可以使用`...

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

    1. **创建和访问Java数组** 在Java中,你可以声明一个简单的类型数组,例如`int[]`或`float[]`。要在本地代码中访问这些数组,你需要先获取`JNIEnv`指针,这是JNI的核心,它包含了所有与Java虚拟机交互的函数。 ``...

    jni 调用对象以及数组

    3. **处理Java数组:** JNI支持各种类型的数组,包括基本类型和引用类型。对于基本类型数组,如int[],可以使用`GetIntArrayElements()`获取原始C数组,操作完成后,使用`ReleaseIntArrayElements()`释放。对于引用...

    hello-jni.rar_C 调用JAVA_jni 数组

    1. **创建和访问Java数组**:JNI提供了多种函数来创建和访问Java数组,包括基本类型数组和对象数组。例如,`NewIntArray()`用于创建整型数组,`GetIntArrayElements()`可以获取数组元素的原始指针以便在C/C++中操作...

    java jni 传递结构体

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

    Android ArrayJni

    综上所述,Android ArrayJni涉及到的关键技术是使用JNI处理Java数组,包括数组的创建、访问、修改以及内存管理。熟练掌握这些技巧,可以帮助开发者充分利用本地代码的优势,提升Android应用的性能和功能。

    NDK08_JNI访问数组、引用、异常、缓存

    访问Java数组时,需要先通过JNIEnv指针获取到数组的本地表示。例如,对于基本类型数组,可以使用`GetIntArrayElements`函数获取int数组的元素,而对象数组则需使用`GetObjectArrayElement`。记得在操作完成后,使用`...

    Android中的JNI数组操作教程

    在 Android JNI 基础知识篇提到了 Java 数组类型对应的 JNI 数组类型。比如,Java int 数组对应了 jintArray,boolean 数组对应了 jbooleanArray。 JNI 提供了对应的转换函数: * GetArrayElements:获取数组元素 ...

    JNI-Java Native Interface资料(精华)

    对于数组,JNI提供了类似`GetArrayLength`、`GetIntArrayElements`等函数,允许本地代码读取和修改Java数组的内容。 #### 访问Java字段与方法 通过JNI,本地代码可以访问Java类的字段和方法。这包括静态和实例字段...

    delphi通过JNI调用JAVA函数

    3. **生成JNI头文件**:使用`javah`工具(在JDK的bin目录下)处理上述Java类,生成C风格的头文件。这将定义C/C++接口,供Delphi代码使用。 4. **编写Delphi实现**:将生成的头文件翻译成Delphi代码。 Delphi不直接...

    jni例子——使用int数组

    JNI提供了一种机制,可以将Java数组转换为本地数组,反之亦然。 - 对于`int`数组,我们可以使用`GetIntArrayElements()`函数获取Java数组的元素副本,`ReleaseIntArrayElements()`则用于释放这些元素并同步任何可能...

    aes-jni-java和c互加解密

    同时,C/C++的原始字节数组也需要转换为Java的`byte[]`数组。 为了实现AES加密,C/C++代码通常会使用开源加密库,如OpenSSL或Bouncy Castle的C库。这些库提供了AES加密的核心函数,如`AES_encrypt`和`AES_decrypt`...

    JNI处理各种类型数据,不包含获取Java的HashMap

    3. 数组操作:JNI提供了丰富的函数来处理数组,如`GetIntArrayElements`可以获取整型数组的元素,而`SetIntArrayRegion`则可以设置数组某一段的值。 4. 对象操作:对于非基本类型的对象,如创建新对象、调用方法、...

    JNI_JAVA_C++.zip

    JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。在本主题"JNI_JAVA_C++"中,我们将深入探讨如何利用JNI在Java和C++之间实现数据交换,以及调用和实现彼此的函数。...

    JNA调用C++动态库,传入二维数组,通过C++返回二维数组,java调用C++完整案例

    在C++中,你可能需要提供一个辅助函数来处理Java传递过来的一维数组,转换为C++的二维数组格式。 此外,对于大型数据结构,考虑到性能问题,可能需要考虑使用直接内存映射(Direct Memory Mapping)或者自定义类型...

    用JNI实现java和C++的相互调用

    例如,`jni.PrintHello()`将调用C++中的`Java_JniTest_PrintHello()`,`jni.PrintArray(arr)`则会调用`Java_JniTest_TestArray()`,并将数组`arr`传递给C++代码进行处理。 总结来说,JNI是Java与C/C++之间通信的...

Global site tag (gtag.js) - Google Analytics