Android 는 JNI 를 통 해 자바 류 의 구조 방법 과 부모 류 를 호출 하 는 방법
구조 방법 을 호출 하 다.
구조 방법 을 호출 하 는 절 차 는 이전 호출 클래스 의 인 스 턴 스 방법 절차 와 유사 하 며 해당 하 는 클래스 와 방법 id 를 얻어 야 합 니 다.
클래스 에 대해 서 는 FindClass 를 통 해 해당 하 는 자바 형식 을 찾 을 수 있 습 니 다.
구조 방법 에 대해 서 는 방법 id 는
GetMethodID
방법 으로 얻 을 수 있 지만 구조 방법 에 대응 하 는 이름 은 반환 값 유형 은 void 형식 입 니 다.상기 준비 조건 을 완성 하면
NewObject
을 통 해 구조 방법 을 호출 하여 구체 적 인 종 류 를 만 들 수 있다.다음은 String 의 어떤 구조 방법 을 예 로 들 면
public String(char value[]) // Java String
대응 하 는 C + + 코드:
extern "C"
JNIEXPORT jstring JNICALL
Java_com_glumes_cppso_jnioperations_InvokeConstructorOps_invokeStringConstructors(JNIEnv *env, jobject instance) {
jclass stringClass;
jmethodID cid;
jcharArray elemArr;
jstring result;
// C++ Java
jstring temp = env->NewStringUTF("this is char array");
// Java , String
const jchar *chars = env->GetStringChars(temp, NULL);
int len = 10;
stringClass = env->FindClass("java/lang/String"); // String
if (stringClass == NULL) {
return NULL;
}
// ,([C)V String String(char value[])
cid = env->GetMethodID(stringClass, "", "([C)V");
if (cid == NULL) {
return NULL;
}
//
elemArr = env->NewCharArray(len);
if (elemArr == NULL) {
return NULL;
}
//
env->SetCharArrayRegion(elemArr, 0, len, chars);
//
result = (jstring) env->NewObject(stringClass, cid, elemArr);
env->DeleteLocalRef(elemArr);
env->DeleteLocalRef(stringClass);
return result;
}
String 의 구조 함 수 는 문자 배열 을 전달 해 야 하기 때문에 먼저 문자 배열 을 구성 하고 값 을 부여 하 며 해당 하 는 클래스 와 방법 id 를 얻 은 후에
NewObject
방법 으로 호출 하면 됩 니 다.사용자 정의 클래스 를 호출 하 는 구조 방법의 예 시 를 살 펴 보 겠 습 니 다. 이전 Animal 클래스 인지, 구조 방법 에는 String 형식의 인자 가 있 습 니 다.
/**
* Java Animal
*/
extern "C"
JNIEXPORT jobject JNICALL
Java_com_glumes_cppso_jnioperations_InvokeConstructorOps_invokeAnimalConstructors(JNIEnv *env, jobject instance) {
jclass animalClass;
jmethodID mid;
jobject result;
animalClass = env->FindClass("com/glumes/cppso/model/Animal");
if (animalClass == NULL) {
return NULL;
}
mid = env->GetMethodID(animalClass, "", "(Ljava/lang/String;)V");
if (mid == NULL) {
return NULL;
}
jstring args = env->NewStringUTF("this animal name");
result = env->NewObject(animalClass, mid, args);
env->DeleteLocalRef(animalClass);
return result;
}
전체 호출 절 차 는 절차 에 따라 만 하면 된다 는 것 을 알 수 있다.
뉴 오 브 젝 트 방법 외 에 도 JNI 는 AllocObject 방법 으로 대상 을 만 들 고 같은 Animal 류 구조 방법 을 사용 하 는 것 을 예 로 들 었 다.
/**
* AllocObject
*/
extern "C"
JNIEXPORT jobject JNICALL
Java_com_glumes_cppso_jnioperations_InvokeConstructorOps_allocObjectConstructor(JNIEnv *env, jobject instance) {
jclass animalClass;
jobject result;
jmethodID mid;
//
animalClass = env->FindClass("com/glumes/cppso/model/Animal");
if (animalClass == NULL) {
return NULL;
}
// id
mid = env->GetMethodID(animalClass, "", "(Ljava/lang/String;)V");
if (mid == NULL) {
return NULL;
}
//
jstring args = env->NewStringUTF("use AllocObject");
// ,
result = env->AllocObject(animalClass);
if (result == NULL) {
return NULL;
}
// CallNonvirtualVoidMethod
env->CallNonvirtualVoidMethod(result, animalClass, mid, args);
if (env->ExceptionCheck()) {
env->DeleteLocalRef(result);
return NULL;
}
return result;
}
마찬가지 로 필요 한 것 을 먼저 준비 해 야 한다.대응 하 는 유형의 유형, 방법 id, 구조 방법의 인 자 를 얻 습 니 다.
그리고
AllocObject
방법 으로 대상 을 만 듭 니 다. 그러나 주의해 야 할 것 은 이때 만 든 대상 은 초기 화 되 지 않 았 습 니 다. NewObject
방법 과 달리 만 든 대상 은 바로 초기 화 되 었 습 니 다. 어느 정도 에 AllocObject
방법 은 초기 화 지연 이 라 고 할 수 있 습 니 다.다음은
CallNonvirtualVoidMethod
을 통 해 대응 하 는 구조 방법 을 호출 해 야 한다.이 곳 에 들 어 오 는 매개 변 수 는 jclass 형식 이 아니 라 초기 화 되 지 않 은 클래스 jobject 입 니 다.이 방법 을 통 해 자바 의 클래스 를 만 들 수 있 습 니 다.
부류 호출 방법
JNI 를 통 해 부모 클래스 의 인 스 턴 스 방법 을 호출 할 수 있 습 니 다.
하위 클래스 에서 호출
CallNonvirtualMethod
방법 을 통 해 부모 클래스 를 호출 하 는 방법.먼저, 해당 하 는 하위 클래스 를 구성 한 다음 에 부모 클래스 의 유형 과 방법 id 를 얻 고 해당 하 는 매개 변 수 를 준비 하 며 부모 클래스 방법의 반환 값 에 따라 서로 다른
CallNonvirtualMethod
함 수 를 호출 합 니 다.인용 유형 에 대해 서 는 CallNonvirtual Object Method 방법 을 호출 합 니 다.기본 유형의 경우 CallNonvirtual BooleanMethod, CallNonvirtual IntMethod 등 을 호출 합 니 다.반환 값 이 없 는 형식 에 대해 서 는 CallNonvirtual Void Method 방법 을 호출 합 니 다.
구체 적 으로 코드 보기:
/**
*
* ,
*/
extern "C"
JNIEXPORT void JNICALL
Java_com_glumes_cppso_jnioperations_InvokeConstructorOps_callSuperMethod(JNIEnv *env, jobject instance) {
jclass cat_cls; // Cat
jmethodID cat_cid; // Cat id
jstring cat_name; // Cat
jobject cat;
//
cat_cls = env->FindClass("com/glumes/cppso/model/Cat");
if (cat_cls == NULL) {
return;
}
// id
cat_cid = env->GetMethodID(cat_cls, "", "(Ljava/lang/String;)V");
if (cat_cid == NULL) {
return;
}
//
cat_name = env->NewStringUTF("this is cat name");
// Cat
cat = env->NewObject(cat_cls, cat_cid, cat_name);
if (cat == NULL) {
return;
}
// getName
jclass animal_cls; //
jmethodID animal_mid; // id
//
animal_cls = env->FindClass("com/glumes/cppso/model/Animal");
if (animal_cls == NULL) {
return;
}
// id
animal_mid = env->GetMethodID(animal_cls, "getName", "()Ljava/lang/String;");
if (animal_mid == NULL) {
return;
}
jstring name = (jstring) env->CallNonvirtualObjectMethod(cat, animal_cls, animal_mid);
if (name == NULL) {
return;
}
LOGD("getName method value is %s", env->GetStringUTFChars(name, NULL));
//
animal_mid = env->GetMethodID(animal_cls, "callInstanceMethod", "(I)V");
if (animal_mid == NULL) {
return;
}
env->CallNonvirtualVoidMethod(cat, animal_cls, animal_mid);
}
Cat 류 는 Animal 류 의 하위 클래스 로 서 먼저 NewObject 방법 으로 Cat 류 를 만 든 다음 부모 류 를 호출 하 는 방법 입 니 다.
이로써 JNI 를 통 해 자 바 를 호출 하 는 것 은 기본적으로 완 성 된 셈 이다.
구체 적 인 예시 코드 는 나의 Github 프로젝트 를 참고 할 수 있 습 니 다. 스타 를 환영 합 니 다.
https://github.com/glumes/AndroidDevWithCpp
위 챗 공식 번호 에 관심 을 가 져 주 셔 서 감사합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.