이전 포스팅에 이어서 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" 입니다.
이후의 과정은 이전 포스팅에서와 동일합니다 :)
'Etc' 카테고리의 다른 글
safetensor 모델을 diffusers에서 사용 가능하게 변경하기 (0) | 2024.11.11 |
---|---|
[JNI] jbyte를 C++의 vector<uchar>로 변환하는 방법 (0) | 2023.03.12 |
[JNI] JNI 사용법 및 튜토리얼 (1) (3) | 2023.03.11 |
[C++] 클래스 메모리 주소를 클래스로 변환하기 (0) | 2023.03.11 |