안녕하세요 돼지왕왕돼지입니다.
지금까지 JNI 에 대해 이론적으로 쌈빡하게 알아봤었죠?
2012/03/21 - [프로그래밍 놀이터/자바] - [Java] JNI 가 뭔가요? ( JNI Introduction )
2012/03/21 - [프로그래밍 놀이터/자바] - [Java] JNI Design Overview. ( JNI 의 전체 구조 )
2012/03/22 - [프로그래밍 놀이터/자바] - [Java] JNI Type 과 Data Structure.
2012/03/22 - [프로그래밍 놀이터/자바] - [Java] JNI functions.
2012/03/22 - [프로그래밍 놀이터/자바] - [Java] JNI Invocation API.
오늘은 실질적으로 JNI 를 사용한 아주 간단한 앱. HelloJNI 를 만들어보겠습니다.
이 글은 http://java.sun.com/docs/books/jni/html/start.html#769 를 번역 및 정리한 글입니다.
HelloJNI
HelloJNI 는 Java Application 이 JNI 를 통해서 C 언어로 정의된 native function을 호출, "Hello JNI!" 를 프린트하는 예제입니다. 다음은 이 예제 프로그램의 step을 보여줍니다.
Declare the Native Method
<HelloJNI.java>
class HelloJNI{
private native void print();
public static void main( String[] args ){
new HelloJNI().print();
}
static{
System.loadLibrary( "HelloJNI" );
}
}
- 보통 static initializer 를 이용하여, native function 들을 implement 한 library 를 로드합니다.
- native function 은 native 라는 modifier 를 써서 정의합니다. 그리고 native function 정의는 구현부 없이 ; 로 마무리합니다.
- System.loadLibrary( "HelloJNI" ); 는 platform-dependent 한 구현을 보여주는데, Win32 에서는 HelloJNI.dll 로 mapping 되고 Solaris 에서는 libHelloJNI.so 로 mapping 됩니다.
Compile the HelloJNI Class
javac HelloJNI.java
Create the Native Method Header File
javah tool 을 이용해서 JNI-style header file 을 만듭니다. 이 header file 은 아시다시피 C 함수를 구현하는데 편리하게 사용되지요.
javah -jni HelloJNI
출력되는 파일은 HelloJNI.h 입니다. 생성된 헤더 파일 중 가장 중요한 부분은 function prototype 입니다.
<HelloJNI.h>
...
JNIEXPORT void JNICALL
Java_HelloJNI_print ( JNIEnv *, jobject );
...
여기서 주목해서 봐야 할 부분은 argument 부분입니다. 첫번째 argument 로 전달되는 JNIEnv 는 JNI interface pointer 로 JNI function table 을 가르키고 있는 pointer 입니다. 두번째 argument 는 this에 해당하는 HelloJNI object 그 자신입니다.
Write the Native Method implementation
javah 를 통해 만들어진 JNI-style header file은 native C, C++ code 를 짜는 데 좋습니다. native code 구현은 다음과 같습니다.
<HelloJNI.c>
#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
JNIEXPORT void JNICALL
Java_HelloJNI_print( JNIEnv *env, jobject obj ){
printf( "Hello JNI!\n" );
return;
}
jni.h 헤더파일은 jni 에 사용되는 모든 코드에 load 되어야 합니다.
Compile the C Source and Create a Native Library
OS 마다 naive library 를 build 하는 방법이 다릅니다.
Solaris 에서는 다음의 command 를 통해 libHelloJNI.so 를 만듭니다.
cc -G -I/java/include -I/java/include/solaris HelloJNI.c -o libHelloJNI.so
-G option 은 C compiler 에게 일반 실행파일이 아닌 shared library 를 만든다는 것을 명시해주는 것입니다.
Win32에서는 다음 명령을 통해 dynamic link library( DLL ) HelloJNI.dll 을 만듭니다.
cl -lc:\java\include -lc\java\include\win32 -MD -LD HelloJNI.c -FeHelloJNI.dll
-MD option 은 WIn32 multithread C library 와 link 되도록 만들어 줍니다. _LD 는 일반 실행파일이 아닌 DLL 을 만든다는 것을 알려줍니다
Run the Program
이제 실행에 필요한 2개의 파일을 가지고 있습니다. 하나는 HelloJNI.class 이고 하나는 HelloJNI.dll 입니다.
java HelloJNI
를 통해서 수행을 합니다. 간혹 java.lang.UnsatisfiedLinkError : no HelloJNI in library path 를 내뿜는 경우가 있습니다. 이 에러는 library path 가 맞지 않아서 그런 것인데, library path 는 Java VM이 미리 설정해 놓습니다.
Solaris system 에서는 LD_LIBRARY_PATH 환경 변수에 native library path 가 정의되어 있고, Win32 계열은 현재 directory 또는 PATH 환경 변수에 정의된 폴더를 참조합니다.
Java 2 SDK 1.2 부터는 java 실행명령에 libary path 를 명시할 수도 있습니다.
java -Djava.library.path =. HelloJNI
-D 옵션은 Java의 system property 를 설정한다는 의미이고, java.library.path를 .으로 설정한 것은 현재 폴더에서 library 를 검색한다는 의미입니다.
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[Android/안드로이드] cygwin 설치방법 ( JNI 사용 위한 native library compile에 focus ) (0) | 2012.03.24 |
---|---|
[Android/안드로이드] JNI Tutorial HelloJNI ( 샘플 소스 포함 ) (2) | 2012.03.24 |
[Java] JNI Invocation API. (0) | 2012.03.22 |
[Java] JNI functions. (0) | 2012.03.22 |
[Java] JNI Type 과 Data Structure. (0) | 2012.03.22 |
댓글