시소당
이번에는 매개변수를 사용한 JNI를 구현해 보도록 하겠습니다. 물론 앞서서 기술했던 JNI로 hello출력하기와 별반 다를 게 없긴 하지만 매개변수를 함수를 통하여 전달하고 실행한다는점에 초점을 맞추도록 하겠습니다.
먼저 두 개의 native타입의 함수원형을 선언하고 main()에서는 객체를 만들고 native함수를 호출하여 C코드와 연동하도록 하는 자바 코드를 만들드록 하겠습니다.
1. class SumJni{
2. // 라이브러리 로딩
3. static{
4. System.loadLibrary("Sum");
5. }
6. // native method 정의
7. public native void setValue(int a, int b);
8. public native void prnValue();
9.
10. public static void main(String args[]){
11. SumJni sj = new SumJni();
12. sj.setValue(10,20);
13. sj.prnValue();
14. }
15. }
4행에 의해서 우리는 C로 코드를 만들고 dll을 만들어야 하는 파일명이 Sum임을 눈치챌 수 있습니다. 또한 나중에 C코드에서 setValue(a,b), prnValue()함수의 몸체를 만들어야 합니다.
위의 코드를 컴파일하고 헤더 파일을 만들도록 하겠습니다.
javac SumJni.java
javah SumJni
오류없이 컴파일되고 헤더파일이 만들어졌다면 다음과 같이 파일이 두 개 추가되었을 것입니다.
이제 C코드를 만들어 봅시다. javah에 의하여 C에서 구현해야할 함수의 원형이 선언되었기 때문에 반드시 C코드를 만들 때엔 헤더 파일의 내용을 참조해야 합니다. javah에 의해서 만들어진 헤더파일은 다음과 같습니다.
1. // 파일명 : SumJni.h
2.
3. /* DO NOT EDIT THIS FILE - it is machine generated */
4. #include <jni.h>
5. /* Header for class SumJni */
6.
7. #ifndef _Included_SumJni
8. #define _Included_SumJni
9. #ifdef __cplusplus
10. extern "C" {
11. #endif
12. /*
13. * Class: SumJni
14. * Method: setValue
15. * Signature: (II)V
16. */
17. JNIEXPORT void JNICALL Java_SumJni_setValue
18. (JNIEnv *, jobject, jint, jint);
19.
20. /*
21. * Class: SumJni
22. * Method: prnValue
23. * Signature: ()V
24. */
25. JNIEXPORT void JNICALL Java_SumJni_prnValue
26. (JNIEnv *, jobject);
27.
28. #ifdef __cplusplus
29. }
30. #endif
31. #endif
C로 구현해야할 함수는 Java_SumJni_setValue()와 Java_SumJni_prnValue()이군요. 이 함수명들을 사용하여 C의 소스코드를 작성하면 다음과 같습니다.
1. // 파일명 : Sum.c
2.
3. #include <jni.h>
4. #include "SumJni.h"
5. #include <stdio.h>
6.
7. int sum=0;
8.
9. JNIEXPORT void JNICALL Java_SumJni_setValue
10. (JNIEnv *env, jobject obj, jint a, jint b){
11.
12. sum = a + b;
13.
14. }
15.
16. JNIEXPORT void JNICALL Java_SumJni_prnValue
17. (JNIEnv *env, jobject obj){
18.
19. printf("sum=%d\n",sum);
20. }
헤더파일에서 명시한 함수의 원형을 바꿀 수는 없으므로 그대로 복사(?)해서 갖다 붙이고 실제로 구현해야하는 코드는 10행과 17행 뿐이군요. 물론 필요한 헤더파일을 include는 해야 하겠지요...
소스를 컴파일 합시다. 여기서는 저는 VC++6에 들어있는 컴파일러를 사용하여 컴파일 하도록 하겠습니다. 컴파일 하고 나면 다음과 같은 파일들이 추가되어 있을 것입니다.
cl -LD Sum.c
만들어야 할 모든 파일은 만들어졌습니다. 최종 SumJni.class파일을 실행하여 그 결과를 보도록 하겠습니다.
출처 : http://kr.blog.yahoo.com/hipwg/1066