数组的处理分为一下两种方式
1、基本类型
2、指向Java类型的引用 对象类型(Object[] ) 的数组
通用于两种类型的数组的函数 GetArrayLength(jarray array) 获取数组的长度
一、处理基本类型数组
1、 Get<TYPE>ArrayElements(<TYPE>Array array,jboolean* isCopy)
此函数可以把Java基本类型数组转换到C/C++中的数组,两种方式:
第一种:拷贝一份传回本地代码
第二种:把指向Java数组的指针直接传回到本地代码,处理完本地化的数组,通过Release<TYPE>ArrayElements释放数组
2、 Release<TYPE>ArrayElements(<TYPE>Array arr,<TYPE>* elems,jint mode )
可以选择如何处理Java和C++的数组:提交、撤销、内存释放、不释放 等
mode 取值:
0 ->对Java的数组更新并释放C++数组
JNI_CONNIT ->对Java的数组进行更新但不释放C++数组
JNI_ABORT ->对Java数组不进行更新,释放C++数组
3、 GetPrimitiveArrayCritical 与 ReleasePrimitiveArrayCritical
JDK1.2之后,增加直接传回指向Java数组的指针而加入的函数,同样也会有同GetStringCritical的死锁的问题
4、 Get<TYPE>ArrayRegion(<TYPE>Array array;jsize start,jsize len,<TYPE>* buf);
在C++中开辟一段内存,然后把Java基本类型的数组拷贝到这段内存 类似GetStringRegion
Set<TYPE>ArrayRegion(<TYPE>Array array;jsize start,jsize len,const <TYPE>* buf);
把Java基本类型的数组中的指定范围的元素用C++的数组中的元素来赋值
5、 <TYPE>Array New<TYPE>Array(jsize len)
指定一个长度然后返回相应的Java基本类型的数组
二、处理对象类型数组
1、Get/SetObjectArrayElements
JNI没有提供直接把Java的对象类型数组(Object[]) 直接转到jobject[] 数组的函数
而是直接通过Get/SetObjectArrayElements这样的函数来对Java的Object[]数组进行操作
取回的位jobject对象,不用释放任何资源
jobject GetObjectArrayElement(jobjectArray array, jsize index) {
return functions->GetObjectArrayElement(this,array,index);
}
void SetObjectArrayElement(jobjectArray array, jsize index,jobject val) {
functions->SetObjectArrayElement(this,array,index,val);
}
2、NewObjectArray
可以通过指定长度跟初始值来创建某个类的数组
三、操作基本类型实例
通过C++代码获取Java中数组并对数组排序更新,在Java端输出
Java代码
package com.fomagic;
public class TestNative {
int[] arrays={1,2,9,4,6,7,8,5,3,2};
public native void sayHello(); // C++本地代码实现
public static void main(String[] args){
System.loadLibrary("NativeCode");// 加载动态链接库,不能加 .dll
TestNative test = new TestNative();
test.sayHello();
for(int each : test.arrays){
System.out.println(each);
}
}
}
C++代码
#include "com_fomagic_TestNative.h"
#include <iostream>
#include <algorithm>
using namespace std;
//对 com_fomagic_TestNative.h 中声明的方法定义
JNIEXPORT void JNICALL Java_com_fomagic_TestNative_sayHello (JNIEnv *env, jobject obj)
{
jclass clazz_TestNative = env->GetObjectClass(obj);
jfieldID fid_arrays= env->GetFieldID(clazz_TestNative,"arrays","[I"); //根据签名获取ID
jintArray jint_arr=(jintArray) env->GetObjectField(obj,fid_arrays); //根据ID获取数组变量
jint* int_arr= env->GetIntArrayElements(jint_arr,NULL); //Java数组的地址直接传回到C++中
jsize len= env->GetArrayLength(jint_arr); //获取数组长度
/*for (int i = 0; i < len; i++)
{
cout<<int_arr[i]<<endl;
}*/
sort(int_arr,int_arr+len); //排序,int_arr指针变量指向的起始地址
env->ReleaseIntArrayElements(jint_arr,int_arr,0);
}