강좌 & 팁
JNI 에서 java native 함수와 c / c++ 의 함수를 matching 하기 위해서는
c / c++ 함수의 규칙을 정확히 지켜서 선언해야한다.
javah 를 이용해서 XXX.h 파일을 생성해서 확인할 수도 있지만
매번 그렇게 하는 것보다는 어느 정도 규칙을 알고 있으면 수정해서 맞게 사용할 수 있다.
먼저 가장 기본적인 argument 가 없고 반환형도 없는 형태의 함수의 선언을 보면 다음과 같다.
JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jclass cls) { ..... } |
반환형 앞뒤로 붙은 JNIEXPORT 와 JNICALL 은 실제로는 아무 의미가 없다.
/usr/lib/jvm/java-6-openjdk/include/jni_md.h
28 |
예약어의 개념으로 define 해놓은 것으로 보이지만, 실제로는 없는 것이나 마찬가지이다.
관습적으로 이렇게 쓰는 것같으므로 그냥 붙여주면 된다.
그리고 함수의 이름 Java_HelloJNI_printHello 는 java class 의 path 와 함수의 이름을 언더바로
연결해 놓은 것이라고 보면 된다.
모든 java class 는 java 로 시작하고, 다음은 java 코드에서 선언한 class 와 함수의 이름이다.
argument 부분의 (JNIEnv *env, jclass cls) 는 기본적으로 들어가는 argument 이다.
JNIEnv *env 는 JNI 에서 지원하는 기본 함수들이 포함된 struct 또는 class 이다. c 코드냐 c++ 코드냐에 따라 달라진다.
jclass cls 는 java 쪽에 선언된 함수를 포함하는 클래스에 대한 정보이다. 해당 class 의 맴버에 접근할 때 주로 사용하게 된다.
알수 없는 문자와 형태로 보이던 JNI 함수의 선언도 뜯어놓고 보면 어느 정도 이해할 수 있다.
이제 함수의 argument 와 반환형에 따라 위의 기본 선언에서 수정만해서도 충분히 사용할 수 있다.
argument 가 boolean, byte, char, short 이고 반환형이 int 인 함수.
JNIEXPORT jint JNICALL Java_Primitive_primitivePrint1 |
argument 가 string 이고 반환형이 int 인 함수
JNIEXPORT jint JNICALL Java_JniFunctions_printString |
argument 가 int[] 이고 반환형이 int 인 함수
JNIEXPORT jint JNICALL Java_JniFunctions_sumInteger |
argument 가 int[], int 이고 반환형이 int 인 함수
JNIEXPORT jint JNICALL Java_JniFunctions_setIntArray |
그 밖에 class 들의 instance 나 다차원 배열은 모두 jobject 를 사용하면 된다.
java 의 모든 class 와 배열은 jobject 를 상속받는다는 것을 다시 한번 상기해보면 된다.