JNI 에서 배열을 argument 로 넘기고 c/c++ 단에서 다루는 방법을 살펴보도록 하겠습니다.

 

===== (4) 배열 다루기 =================================================================

 

1. JNI 배열 타입

JNI 에서는 기본 변수형과 마찬가지로 기본 배열에 대한 별도의 타입을 제공하고 있다.

 

/usr/lib/jvm/java-6-openjdk/include/jni.h

typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jarray jobjectArray;

c 와 c++ 에서 야간 다르게 typedef 되어 있는데... 이는 class 의 사용 여부에 따라

JNI 자체에서 구현을 다르게 해놓았기 때문으로 보인다.

 

2. 사용 함수

JNI 의 배열 관련 함수는 몇가지 타입이 있는데 우선 int 형에 대해 알아보면 다음과 같다.

얻기 : jint * GetIntArrayElements(jintArray array, jboolean *isCopy);

반환 : void ReleaseIntArrayElements(jintArray array, jint *elems, jint mode);

부분 얻기 : void GetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf)

값 설정 : void SetIntArrayRegion(jintArray array, jsize start, jsize len, const jint *buf)

생성 : jintArray NewIntArray(jsize len);

길이 얻기 : jsize GetArrayLength(jarray array);

위와 같은 함수들이 각 타입에 따라 이름만 다른 형태로 있다고 보면 된다.

 

3. 예제

 

MainStart.java 

public class MainStart {
        public static void main(String[] args) {
                int[] iArray = new int[10];

                for(int i=0; i<iArray.length; i++) {
                        iArray[i] = i*3;
                }

                int sum = JniFunctions.sumInteger(iArray);
                System.out.println("sum is " + sum);
        }
}

 

MainStart.java 

public class JniFunctions {
        static {
                System.loadLibrary("mylib");
        }

        public static native int sumInteger(int[] iArr);

}

int[10] 의 배열을 만들어서 값을 넣고 JNI 함수에서 그 값들을 더해서 return 해주는 예제이다.

 

JniFunctions.cpp

#include <jni.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL Java_JniFunctions_sumInteger
        (JNIEnv *env, jclass cls, jintArray ji_array)
{
        jint *int_buf;
        int size;
        int sum, i;

        size = env->GetArrayLength(ji_array);
        int_buf = env->GetIntArrayElements(ji_array, NULL);
        sum = 0;
        for(i=0; i<size; i++) {
                sum += int_buf[i];
                printf("array [%d] = %d, sum = %d\n", i, int_buf[i], sum);
        }
        env->ReleaseIntArrayElements(ji_array, int_buf, 0);

        return sum;
}

#ifdef __cplusplus
}
#endif

위와 같이 jintArray 의 길이를 얻고, jint * 형태로 변환해서 받을 수 있는 함수들이 있다.

jstring 과 마찬가지로 사용후에는 반드시 release 함수를 호출해 주어야 한다.

 

그 밖에, 생성, 설정 함수는 다른 예제에서 살펴보도록 하자.

이 함수들을 사용할 때는, java 와 c/c++ 간의 메모리 alloc, free 와 같이 더 고려해야 할 것들이 더 생기기 된다.

 

===================================================================================