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
 29 #define JNIEXPORT
 30 #define JNIIMPORT
 31 #define JNICALL
 32

 

예약어의 개념으로 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
        (JNIEnv *env, jclass cls, jboolean jbl, jbyte jbt, jchar jch, jshort jst)

 

argument 가 string 이고 반환형이 int 인 함수

JNIEXPORT jint JNICALL Java_JniFunctions_printString
        (JNIEnv *env, jclass cls, jstring jstr)

 

argument 가 int[] 이고 반환형이 int 인 함수

JNIEXPORT jint JNICALL Java_JniFunctions_sumInteger
        (JNIEnv *env, jclass cls, jintArray ji_array)

 

argument 가 int[], int 이고 반환형이 int 인 함수

JNIEXPORT jint JNICALL Java_JniFunctions_setIntArray
(JNIEnv *env, jclass cls, jintArray ji_array, jint value)

그 밖에 class 들의 instance 나 다차원 배열은 모두 jobject 를 사용하면 된다.

 

java 의 모든 class 와 배열은 jobject 를 상속받는다는 것을 다시 한번 상기해보면 된다.