본문 바로가기
프로그래밍/Android-Java

[ANDROID] JNI (c++) 에서 JAVA 함수 콜하기

by 채연2 2022. 1. 7.

자바에서 이벤트 처리를 할 때 jni쪽으로 전달할 순 있지만, 역으로 jni 쪽에서 이벤트 처리를 할 때 java 쪽으로 이벤트를 주고 싶었다.

 

근데 이미 짜여져 있는 코드에서 추가 수정 작업을 하려니

JNIEnv *env

위 env 변수가 발목을 잡았다. 따로 전역변수 선언해서 저장해 놓고 쓸 수가 없었다................

그래서 삽푸다가 겨우 해결한 방안은 다음이다.

 

 

 

static JavaVM *rjvm = NULL;
static jobject robject = NULL;

extern "C" JNIEXPORT void JNICALL
Java_com_cy_test_MainActivity_onvifStartServer(
        JNIEnv
        *env,
        jobject thiz) {
    main_onvif_server(env);
    if (rjvm == NULL)
        env->GetJavaVM(&rjvm);

    if (robject == NULL)
        robject = env->NewGlobalRef(thiz);
}

우선 헤더 파일에 전역변수로 rjvm, robject를 선언해 주고, JNI 함수가 호출이 되면 각 변수를 초기화 해준다.

 

 

if (rjvm == NULL) {
    return;
}

JNIEnv *env;

int getEnvStat = rjvm->GetEnv((void **) &env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
    if (rjvm->AttachCurrentThread(&env, NULL) != 0) {
       return;
    }
}

jclass cls = env->GetObjectClass(robject);
jmethodID mid = env->GetMethodID(cls, "onvifZoomIn", "()V");
env->CallVoidMethod(robject, mid);

그리고 이벤트 처리하는 함수에 다음과 같이 코딩을 해준다.

물론, MainActivity에는 public void onvifZoomIn(); 이라는 함수가 선언되어 있어야한다.

 

 

 

 

 

여기서 하나 더!

나는 여러 파라미터가 있는 함수를 호출하고 싶다! 하면 다음 처럼 하면 된다.

jstring str_ipaddr = env->NewStringUTF(temp_status->ipaddr);
jstring str_netmask = env->NewStringUTF(temp_status->netmask);
jstring str_gateway = env->NewStringUTF(temp_status->gateway);
jstring str_dns = env->NewStringUTF(temp_status->dns);

mid = env->GetMethodID(cls, "onvifNetworkSTATIC",
                                   "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
env->CallVoidMethod(robject, mid, str_ipaddr, str_netmask, str_gateway, str_dns);

 

320x100

댓글