五、C++处理Java的数组

数组的处理分为一下两种方式

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);
}

 

 

你可能感兴趣的:(java,C++,jni)