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 |