JNI: JAVA 대상 은 C + + 대상 과 대칭 적 인 관 계 를 맺 습 니 다.

3117 단어
이 걸 왜 썼 는 지 먼저 말씀 드 리 겠 습 니 다. 이 문 제 는 제 가 면접 에서 물 어 본 질문 입 니 다.
자바 에 A. 자바 가 있 습 니 다. C + + 에 도 A. cpp 가 있 습 니 다. 이 두 가지 기능 함수 가 완전히 대응 합 니 다. 자바 층 을 조작 하 는 대상 을 어떻게 만 들 면 C + 층 을 조작 하 는 대상 에 해당 합 니까?
이 문 제 를 설명 하 십시오. 우선 자바 층 new 에서 A1Java 대상 을 만 들 때 대응 하 는 C++ 층 도 A1Cpp 대상 을 만 듭 니 다. A1java 대상 의 어떤 방법 을 호출 할 때 C + + 층 에 비 추어 도 대상 A1Cpp 을 호출 하 는 방법 입 니 다.
이 문 제 를 보고 제 첫 번 째 생각 은 제 가 javanew 에서 대상 을 만 들 때 호출 JNI 함수 가 C++ 층 에서 대상 을 만 들 면 문제 가 생 길 것 입 니 다. 우리 new 가 두 번 째 대상 이 나 왔 을 때 우리 가 만 든 대상 을 어떻게 저장 하 는 지 바 꾸 면 우 리 는 C++ 층 에 하나의 map 를 만들어 서 이전에 만 든 대상 을 저장 할 수 있 습 니 다.자바 층 jclasskey 으로 사용 하면 자바 대상 이 소각 되 었 을 때 C++ 대상 을 찾 아 소각 할 수 있 습 니 다.
그러나 이런 대답 은 분명히 면접 관 을 만족 시 키 지 못 하 게 했다. 내 려 와 서 곰 곰 이 생각해 보 니 내 대답 은 확실히 일치 하지 않 았 다 . 결국 나 는 중간 캐 시 로 java 층 과 C++ 층 의 관 계 를 해결 하 는 것 이 었 다. 사실은 더 좋 은 방법 이 있 었 다.
생각해 보 세 요. 우 리 는 왜 map 대상 과 java 대상 을 연결 시 키 는 것 이 필요 합 니까? 우 리 는 보통 무엇 을 통 해 C++ 대상 을 찾 을 수 있 습 니까?분명히 C++ 즉 대상 의 이다. 즉, 모든 은 하나의 java 대상 주소 에 대응 하고 있다. 만약 에 우리 가 C++ 이 주소 와 연결 되면 java 대상 을 찾 을 수 있다. 분명히 우 리 는 C++ 에 변 수 를 추가 하여 java 층 의 지침 을 저장 할 수 있다. 그러면 우 리 는 함 수 를 구성 할 때C++ 함 수 를 호출 하여 JNI 층 의 대상 을 구성 한 다음 에 이 대상 의 주 소 를 C++ 함수 로 이 JNI 에 설정 합 니 다. 그러면 우 리 는 자바 층 의 대상 방법 을 조작 할 때 이 대상 의 주 소 를 java 층 으로 전달 하면 이 주소 로 해당 하 는 JNI 대상 을 찾 은 다음 에 해당 하 는 함 수 를 조작 할 수 있 습 니 다. 이 동시에 중간 에 있 는 함 수 를 절약 할 수 있 습 니 다.C++, map 의 표현 에 더욱 부합된다.
자바 층:
class A{
private long nativeOjbHandle;
private String tag;

public A(String tag){
this.tag = tag;
initNative();
}


public native void initNative();


private native String getName();
}

JNI 층:

initNativeA(JNIEnv *env, jobject instance){
    NativeA *objNative = new NativeA();
     jclass clazz = (jclass)env->GetObjectClass(instance);
     jfieldID fid = (jfieldID)(*env).GetFieldID(clazz, "nativeOjbHandle", "J");
     env->SetIntField(thiz, fid, (jlong)objNative);
}

jstring
getNative (JNIEnv *env, jobject instance ){

    jclass objClazz = (jclass)env->GetObjectClass(instance);//obj    JAVA  
    jfieldID fid = env->GetFieldID(objClazz, "nativeOjbHandle", "J");
    jlong p = (jlong)env->GetObjectField(obj, fid);
    NativeA *nativeA = (NativeA *)p;
}


방법 2: C + + 대상 은 JAVA 대상 의 인용 을 가지 고 있 습 니 다. 클래스 에 C++ 형식의 변 수 를 만 듭 니 다 (예: jint. jint mObj 대상 의 인용 을 저장 할 때 C + 대상 을 만 들 때 JAVA 대상 의 인용 을 저장 합 니 다.
    jobject javaObjCls = (jobject)env->NewGlobalRef(thiz);//thiz JAVA  
    NativeAObj->javaObj = (jint)javaObjCls;
    

좋은 웹페이지 즐겨찾기