본문 바로가기

개발 언어/JAVA

[JNI] 배열혈 아규먼트

JNI(Java Native Interface) - 4. 배열형 아규먼트 -

 

이번 시간에는 배열로 들어온 아규먼트를 처리하는 법을 조사해 보겠습니다. 단순히 배열로 되었을 뿐인데 무었이 있나라고 생각하시면.... 음.... 역시나 다른 언어간의 교신이므로 있습니다. 무언가가.... 단순한 메모리 참조를 넘어선 그 뒤의 무언가가.....

아무튼 기본 자료 형태의 배열과 오브젝트 형태의 배열로 나뉘어져 있습니다만.... 조금의 차이를 제외하고는 거의 동일 합니다.

 

먼저 일차원 배열에 대해서 알아 보도록 하겠습니다.

간단한 예제를 통해서 접근해 보겠습니다.

class ArrayTest {
    public native void passArray(int []intary);

    static {
        System.loadLibrary("ArrayTest");
    }

    public static void main(String[] args) {
        ArrayTest test = new ArrayTest();
        int intary[] = new int[]{1,2};
        test.passArray(intary);
    }
}
위와 같이 int배열을 파라메터로 넘겨주는 네이티브 메소드를 작성합니다. 여느때와 같이 컴파일하고 헤더생성한 뒤 C파일을 생성하고 아래와 같이 코딩합니다.

#include "ArrayTest.h"

JNIEXPORT void JNICALL Java_ArrayTest_passArray (JNIEnv *env, jobject obj, jintArray intary) {
   
//내용이 들어갈 부분   

}

자 여기까지 준비가 끝나시면.... 이제 내부를 코딩할 차례입니다.

단순히 생각을 해 보자면...... 내부에 다음과 같이 코딩하기 쉽습니다.

    for(int i=0; i < 2: i++) {

        printf("value %d is %d\n", i, intary[i]);

    }

상기와 같이 코딩하였을 경우 에러는 나지 않지만 원치않는 출력 결과가 나오게 됩니다. 왜..... 일까요.......

분명 자료형으로는 별도로 준비된 jintArray가 사용되고 있는데도 불구하고 왜 인덱스참조시 원치않는 결과가 나오는 것일까가 분제입니다. 기본이기 때문에 다 아시겠지만, 과거 부품만들기 편을 보신 분들이라면 배열부터는 기본자료형이 아닌 주소참조 자료형이라는 것을 보셨을 것입니다. 이 부분부터가 바로 사용되어질 수 없는 부분입니다. 별도의 자료형이 존재는 하지만.... 이는 단순히 그 메모리 시작번지를 지정하기 위한 그리고 그 타입을 기억하기 위한 수단일 뿐 그 이상의 기능이 들어있지 않은 자료입니다. 즉 배열로 사용하기 위해서는 배열로 이동시켜 주어야 한다는 것입니다. 음...... 엄격하군요.... 다른 언어간의 교신.... 그래도 마소에서 밀고있는 COM파일 만드는 거 보다는 쉽다고 장담합니다. 그닥 공부해야 할 내용도 별로 없구요... 그러니 힘냅시다.

에 또... 그런 연유로 실제 int배열로 변환을 시켜야 하므로.... 제대로 말하자면 jint입니다만....

소스에 수정을 거쳐서 아래와 같이 코딩을 해 줍니다.

    jint *buf;
    buf = env->GetIntArrayElements(intary, NULL);
    int size = env->GetArrayLength(intary);
    for (int i = 0; i < size; i++) {
        printf("int array[%d] is %d\n", i, buf[i]);
    }

모.... 여기부터는 여러가지 방법이 있겠지만.... C의 장점을 살려서 포인터를 바로 사용해서 담는 법이 편하겠군요.....

주목해야 할 부분은 변환하는 부분으로써 buf = env->GetIntArrayElements(intary, NULL); 요 부분 입니다.

환경객체를 이용해서 int배열인자를 변환해서 뽑아내는 소스입니다. 간단히 이렇게 하면 바로 buf에 참조되어지겠지요....

밑에있는 사이즈 구하는 부분은 보너스 트랙입니다. 배열의 크기를 모르니 보통 정해진 크기로 들어오기보다는 몇개가 될지 모르는 경우가 많으므로 그 크기를 구하는 부분으로 이도 역시 환경객체를 이용합니다.

그냥 읽어 보기만 해도 이해가 가는 소스이므로 더이상의 설명은 없습니다...

상기와 같이 코딩을 한 뒤 라이브러리까지 만들고 클래스 실행시키시면 아래와 같은 출력을 얻을 수 있습니다.

---------- java run ----------
int array[0] is 1
int array[1] is 2

Output completed (0 sec consumed) - Normal Termination

깨끗하게 처리되었습니다. 음..... 간단하군요...


'개발 언어 > JAVA' 카테고리의 다른 글

JNI 종합편  (0) 2011.07.22
Java Native Interface 설명서  (0) 2011.07.22
[jni]객체의 메서드 실행하기  (0) 2011.07.22
[jni]객체 필드에 접근하기  (0) 2011.07.22
[jni]문자열 전달 인자  (2) 2011.07.22