Android JNI中Java与C++对象如何建立一一对应的关系

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liwenlong_only/article/details/79613581

Android JNI中Java与C++对象如何建立一一对应的关系

环境

系统:Mac OSX
IDE:android studio 3.0

1.JAVA对象持有C++对象的指针

  • 在java类中创建long类型的变量如(long mNativeStudent ),用于存储c++对象的指针,java代码如下;
public class Student {

   private long mNativeStudent = -1; // 用于存放 c++ 对象的指针
   private final String TAG = "Student";
   public Student(){
      mNativeStudent = CreateStudent();
   }

   public void setName(String name){
       SetName(name);
   }

   public String getName(){
      return GetName();
   }

   public void setGrade(int grade){
      SetGrade(grade);
   }

   public int getGrade(){
      return GetGrade();
   }

   public String print(){
      return Print();
   }

   public static String printClassName(){
      return PrintClassName();
   }

   @Override
   protected void finalize() throws Throwable {
      DestoryStudent(mNativeStudent);
      super.finalize();
   }

   private native long CreateStudent();

   private native void DestoryStudent(long nativeStuent);

   private native void SetName(String name);

   private native String GetName();

   private native void SetGrade(int grade);

   private native int GetGrade();

   private native String Print();

   private static native String PrintClassName();
}
  • 在创建C++对象(如NativeStudent)的本地方法中,将C++对象的指针存入java变量中(mNativeStudent)
jlong CreateStudent(JNIEnv *env, jobject obj){
    NativeStudent *student = new(std::nothrow) NativeStudent();
    if(student){
        return (jlong)student;
    }else{
        LOGE("new NativeStudent object error.");
    }
}
  • 如果要取得C++对象,则通过mNativeStudent的获取C++对象的指针
NativeStudent * GetNativeStudentFromObj(JNIEnv *env, jobject obj){
    jclass objClazz = (jclass)env->GetObjectClass(obj);//obj为对应的Java对象
    if (objClazz == NULL){
        LOGE("env->GetObjectClass return null.");
        return nullptr;
    }
    jfieldID fid = env->GetFieldID(objClazz, "mNativeStudent", "J");
    if(fid == NULL){
        LOGE("env->GetFieldID error.");
        return nullptr;
    }
    jlong p = (jlong)env->GetLongField(obj, fid);
    return (NativeStudent *)p;
}

2.C++对象持有JAVA对象的引用

  • 在C++类中创建一个long类型的变量(如long mJavaObj),用于储存JAVA对象的引用
  • 在创建C++对象时,储存JAVA对象的引用
jlong CreateStudent(JNIEnv *env, jobject obj){
    NativeStudent *student = new(std::nothrow) NativeStudent();
    jobject gThiz = (jobject)env->NewGlobalRef(obj);//thizJAVA对象
    student->mJavaObj = (jint)gThiz; //c++对象存储java引用
    if(student){
        return (jlong)student;
    }else{
        LOGE("new NativeStudent object error.");
    }
}
  • 注意在销毁c++对象是要调用DeleteGlobalRef方法销毁全局引用
void DestoryStudent(JNIEnv *env, jobject obj, jlong nativeStudent){
    NativeStudent *student = (NativeStudent*)nativeStudent;
    env->DeleteGlobalRef((jobject)student->mJavaObj); //销毁创建的引用
    IL_SAFE_DELETE(student);
}

demo地址

猜你喜欢

转载自blog.csdn.net/liwenlong_only/article/details/79613581