Android JNI中Java與C++物件如何建立一一對應的關係
阿新 • • 發佈:2018-12-18
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);//thiz為JAVA物件
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);
}