JNI中如何在本地代码C++中操作java中的基本类型的数组以及对象数组

时间:2021-12-08 15:50:37

功能:通过C++本地代码将java中的数组进行排序,并重新赋值给data数组,java输出后是排好序的数组

package jni;

import java.util.Random;


public class TestNative {
public int[] data=new int[5];

public native void sayhello();

public String name="zhangsan";
public int number=10;

public double max(double num1,double num2){
return num1>num2?num1:num2;
}

public TestNative(){
for(int i=0;i<5;i++){
data[i]=new Random().nextInt(100);
}
}
public void print(int[] data){
for(int i=0;i<data.length;i++){
System.out.print(data[i]+" ");
}
System.out.println();
}

// Father p=new Child();
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.loadLibrary("NativeCode");
TestNative tst=new TestNative();
tst.sayhello();
System.out.println(tst.number);
System.out.println(tst.name);
tst.print(tst.data);
}

}

C++本地代码如下:

JNIEXPORT void JNICALL Java_jni_TestNative_sayhello(JNIEnv *env, jobject object){

获取当前类的class对象

jclass clazz_TestNative=env->GetObjectClass(object);

获取当前数组的fieldID

jfieldID fid_array=env->GetFieldID(clazz_TestNative,"data","[I");

jintArray jint_arr= (jintArray)env->GetObjectField(object,fid_array);

将jintArray 转换成c++认识的jint * 进行本地操作

 jint* int_arr=env->GetIntArrayElements(jint_arr,NULL);

得到数组的长度

jsize len=env->GetArrayLength(jint_arr);
调用C++本地的方法 ,进行排序

std::sort(int_arr,int_arr+len);

本地进行输出
for(jsize i=0;i<len;i++){
 cout<<int_arr[i]<<endl;
}

释放本地的空间
env->ReleaseIntArrayElements(jint_arr,int_arr,0);

}

C++代码中访问java的Person对象类型的数组

package jni;


public class Person {


private String name;
private int age;

public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + "]";
}

}

package jni;


import java.util.Random;


public class TestNative {

public Person[] persons=new Person[2];
public int[] data=new int[5];

public native void sayhello();

public String name="zhangsan";
public int number=10;

public double max(double num1,double num2){
return num1>num2?num1:num2;
}

public TestNative(){
for(int i=0;i<2;i++){
persons[i]=new Person("yy"+i,i);
}
for(int i=0;i<5;i++){
data[i]=new Random().nextInt(100);
}
}
public void print(int[] data){
for(int i=0;i<data.length;i++){
System.out.print(data[i]+" ");
}
System.out.println();
}
public void printPerson(Person[] persons){
for(Person p:persons){
System.out.println(p);
}
}

// Father p=new Child();
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

System.loadLibrary("NativeCode");
TestNative tst=new TestNative();
tst.printPerson(tst.persons);
tst.sayhello();
System.out.println(tst.number);
System.out.println(tst.name);
tst.print(tst.data);

}
}

C++中的访问代码如下:

JNIEXPORT void JNICALL Java_jni_TestNative_sayhello(JNIEnv *env, jobject object){

//首先得到jclass对象,是后面得到属性和方法ID的基础
jclass clazz_TestNative=env->GetObjectClass(object);
        //C++访问对象类型的数组
jfieldID person_id=env->GetFieldID(clazz_TestNative,"persons","[Ljni/Person;");
jobjectArray obj_arr=(jobjectArray)env->GetObjectField(object,person_id);
    
jsize len=env->GetArrayLength(obj_arr);
for(jsize i=0;i<len;i++){
jobject obj=env->GetObjectArrayElement(obj_arr,i);
cout<<obj<<endl;
jclass person_class=env->FindClass("jni/Person");
jmethodID name_id=env->GetMethodID(person_class,"getName","()Ljava/lang/String;");
jstring name_str=(jstring)env->CallObjectMethod(obj,name_id);
const char* name=env->GetStringUTFChars(name_str,NULL);
cout<<name<<endl;
}

}