IT_Programming/Java

native method 정의 및 구현

JJun ™ 2007. 6. 28. 13:08

Java Native Interface
JNI는 native method를 이용해서 C/C++의 code를 Java에서 이용할수 있는 방법이다.
native 메소드를 정의해서, 사용하는 방법에 대해 소개를 하겠습니다.


1. Example Java Source
C/C++의 code를 자바에서 불러 사용하려면, native method를 정의해야 하는데, 아래 코드와 같이
method body를 갖지않는 method를 native keyword를 통해 정의한다.
이것은 method의 body가 C/C++ code의 dll(Unix에서는 so) 파일로 되어 있다는 의미이다.
그래서 runtime에는 이 dll 파일을 메모리에 loading을 해야만 method를 실행할수가 있는데,
dll 파일을 loading하는 library는 System class의 loadLibrary() 메소드이다.
classpath경로에서 파라미터의 파일을 메모리에 loading을 하죠. 

public class Hello {

    public static native void print();

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

    public static void main(String args[]) {
      Hello.print();
    }
}

compile
prompt>javac Hello.java

compile된 class를 실행하면 당연히 에러가 발생되겠죠. 다음과 같이.
prompt>java Hello
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.libr
ary.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1312)
at java.lang.Runtime.loadLibrary0(Runtime.java:749)
at java.lang.System.loadLibrary(System.java:820)
at Hello.(Hello.java:6)


2. C/C++의 Header file 생성
native method를 C/C++로 구현 하기 위해서는 Java method 선언을 C/C++의 method선언으로
mapping시켜주어야 겠죠.
이것은 javah 라는  명령어를 이용합니다.
그래서, 다음과 같은 명령어로 C/C++의 Header 파일을 생성합니다.

prompt>javah -jni -classpath . -o Hello.h Hello

//생성된 header file : Hello.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class Hello */

#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     Hello
* Method:    print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Hello_print
(JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif


3. C code 생성을 위한 C/C++ compiler install
생성된 header file에 정의된 JNIEXPORT void JNICALL Java_Hello_print(JNIEnv *, jclass); 메소드를
구현하기 위해 Borland C++ Compiler5.5 를 다운 받아 설치한다.
http://www.borland.com/downloads/
설치방법은 인스톨 파일을 실행하면, 설치 디렉토리에 readme file이 있는데, bcc32.cfg, ilink32.cfg 파일을 readme 파일의 내용과 같이 만들어 bin dir에 저장하면 끝난다.


4. C source code
Hello.h 파일에 선언된 메소드를 다음과 같이 구현한다.

//hello.cpp file
#include "Hello.h"

JNIEXPORT void JNICALL Java_Hello_print
(JNIEnv *, jclass)
{
    printf("Hello World");
}


5. compile and dll file 생성
다음과 같은 명령어로 compile해서 hello.dll 파일을 생성한다.
prompt>bcc32 -c -Id:\java\jdk1.3\include -Id:\java\jdk1.3\include\win32 hello.cpp
prompt>bcc32 -tWD hello.obj


6. 실행
hello.dll 파일이 현재 디렉토리에 만들어 졌기 때문에, System.loadLibrary()로 메모리에 loading

할 수 있고, print() 라는 native method가 실행될수 있겠죠.

prompt>java Hello
Hello World