본문 바로가기
Programming/etc

[JNI] JNI 사용법 및 튜토리얼 (2)

by ga.0_0.ga 2023. 3. 12.
728x90
반응형

이전 포스팅에 이어서 JNI에 대해 설명하겠습니다.

 

이전에는 자바의 클래스 파일을 만들고 이를 통해 헤더 파일을 생성하여 이용하는 방법에 대해 설명했습니다. 이번에는 헤더파일을 생성하지 않고 이용하는 방법에 대해 설명하겠습니다.

바로 JNI_OnLoad() 함수를 이용하는 것입니다.

자바 코드 부분은 이전 포스팅과 동일하고, C++ 구현부에만 차이가 있습니다.

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = NULL;
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK){
        return JNI_ERR;
    }
    jclass c = env->FindClass("com/test/testjni/HelloJNI");
    if (c == nullptr) return JNI_ERR;

    static const JNINativeMethod methods[] = {
        {const_cast<char*>("printHello"), const_cast<char*>("(V)V"), (void*)printHello},
        {const_cast<char*>("printString"), const_cast<char*>("(Ljava/lang/String)V"), (void*)printString},
    };  
    int rc =env->RegisterNatives(c, methods, sizeof(methods)/sizeof(JNINativeMethod));
    if (rc!=JNI_OK) return rc;

    return JNI_VERSION_1_6;

}

먼저 env->FindClass("com/test/testjni/HelloJNI") 에 패키지명, 클래스 명을 적어줍니다.

그리고, static const JNINativeMethod methods[] = { }; 안에 구현할 함수들을 적어줍니다.  {("함수이름"), "(파라미터)리턴", (void*)함수이름} 형식으로 작성하면 됩니다.

printString() 함수를 기준으로 설명하겠습니다.  

{const_cast<char*>("printString"), const_cast<char*>("(Ljava/lang/String)V"), (void*)printString}

( const_cast<char*> 는 warning 문구를 없애기 위해 추가한 부분으로 꼭 필요한 것은 아닙니다 )

첫번째 괄호 안에는 함수의 이름인 "printString"을 넣어주고, 두번째 괄호 안에는 ("(Ljava/lang/String)V")를 넣어줍니다. printString()함수는 매개변수로 String 을 받고 리턴형이 void 인 함수입니다. 이를 의미하는 Ljava/lang/String과 V를 적어주면 됩니다. 이와 관련해서는 JNI Signature에 대해 검색해보시면 됩니다!

만약 매개변수 자료형들이 (string, string, int) 이고 리턴형이 long라면 "(Ljava/lang/String;Ljava/lang/String;I)J" 로 표현하면 됩니다.

매개변수 자료형들이 (long, float)이고 리턴형이 boolean이라면 "(JF)Z" 가 됩니다!

매개변수 자료형들이 (byte, byte, int)이고 리턴형이 void라면 "([B[B)J" 입니다.

 

이후의 과정은 이전 포스팅에서와 동일합니다 :)

 

 

728x90
반응형

댓글