1. 程式人生 > >JNI中如何在原生代碼C++中操作java中的基本型別的陣列以及物件陣列

JNI中如何在原生代碼C++中操作java中的基本型別的陣列以及物件陣列

功能:通過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;
}

}