본문 바로가기

Android

JNI 예제 - HelloWorld JNI


아래의 순서대로 실행하면 문제없이 자바에서 C 프로그램을 호출한 결과를 볼 수 있을 것이다.

사용환경은 다음과 같다.
 - CentOS5.3 64 bit
 - Java SE : javac 1.6.0_15
 - C compiler : GNU GCC

▶ 먼저 아래의 C 프로그램을 호출하는 자바소스를 작성하자.
[json01@localhost jni]$ vi HelloWorldJNI.java

public class HelloWorldJNI {

    native byte[] sayHelloWorld();

//    static {
//        System.setProperty("java.library.path", "/users/lib");
//        System.loadLibrary("HelloWorldJNI");
//    }

    public static void main(String[] args) {
        System.loadLibrary("HelloWorldJNI");
        byte buf[];
        HelloWorldJNI hello = new HelloWorldJNI();
        buf = hello.sayHelloWorld();
        System.out.println(" result:"+ buf );
    }

}


▶ 자바로 부터 호출되는 C 프로그램을 작성하자.
[json01@localhost jni]$ vi HelloWorldJNI.c

#include "HelloWorldJNI.h"
#include <jni.h>

JNIEXPORT jbyteArray JNICALL Java_HelloWorldJNI_sayHelloWorld
(JNIEnv *env, jobject job)
{
    jbyteArray jb;
    static char outputbuf[20];

    strcpy(outputbuf, "Hello World. JNI\n");
    jb = (*env)->NewStringUTF(env, outputbuf);

    return(jb);
}


▶ 작성한 C 프로그램으로 부터 헤더 파일을 작성하자.
[json01@localhost jni]$ javah HelloWorldJNI
[json01@localhost jni]$ ls -al
合計 16
-rw-r--r-- 1 json01 json01 406 10月  1 14:48 HelloWorldJNI.java
-rw-r--r-- 1 json01 json01 299 10月  1 14:52 HelloWorldJNI.c
-rw-r--r-- 1 json01 json01 415 10月  1 14:52 HelloWorldJNI.h
[json01@localhost jni]$
[json01@localhost jni]$ cat -n HelloWorldJNI.h
     1  /* DO NOT EDIT THIS FILE - it is machine generated */
     2  #include <jni.h>
     3  /* Header for class HelloWorldJNI */
     4
     5  #ifndef _Included_HelloWorldJNI
     6  #define _Included_HelloWorldJNI
     7  #ifdef __cplusplus
     8  extern "C" {
     9  #endif
    10  /*
    11   * Class:     HelloWorldJNI
    12   * Method:    sayHelloWorld
    13   * Signature: ()[B
    14   */
    15  JNIEXPORT jbyteArray JNICALL Java_HelloWorldJNI_sayHelloWorld
    16    (JNIEnv *, jobject);
    17
    18  #ifdef __cplusplus
    19  }
    20  #endif
    21  #endif

▶ C 프로그램 컴파일과 라일브러리 작성
[json01@localhost jni]$ gcc -c -fPIC -o HelloWorldJNI.o -I/usr/java/jdk1.6.0_15/include -I/usr/java/jdk1.6.0_15/include/linux -I/h
ome/json01/src/jni HelloWorldJNI.c
HelloWorldJNI.c: In function ‘Java_HelloWorldJNI_sayHelloWorld’:
HelloWorldJNI.c:10: 警告: incompatible implicit declaration of built-in function ‘strcpy’
[json01@localhost jni]$
[json01@localhost jni]$ ls -al
合計 20
-rw-r--r-- 1 json01 json01  715 10月  1 14:47 HelloWorldJNI.class
-rw-r--r-- 1 json01 json01  406 10月  1 14:48 HelloWorldJNI.java
-rw-r--r-- 1 json01 json01  299 10月  1 14:52 HelloWorldJNI.c
-rw-r--r-- 1 json01 json01  415 10月  1 14:52 HelloWorldJNI.h
-rw-r--r-- 1 json01 json01 1616 10月  1 14:55 HelloWorldJNI.o
[json01@localhost jni]$
[json01@localhost jni]$ gcc -shared -o libHelloWorldJNI.so HelloWorldJNI.o
[json01@localhost jni]$
[json01@localhost jni]$ lsr
合計 28
-rw-r--r-- 1 json01 json01  715 10月  1 14:47 HelloWorldJNI.class
-rw-r--r-- 1 json01 json01  406 10月  1 14:48 HelloWorldJNI.java
-rw-r--r-- 1 json01 json01  299 10月  1 14:52 HelloWorldJNI.c
-rw-r--r-- 1 json01 json01  415 10月  1 14:52 HelloWorldJNI.h
-rw-r--r-- 1 json01 json01 1616 10月  1 14:55 HelloWorldJNI.o
-rwxr-xr-x 1 json01 json01 5797 10月  1 14:56 libHelloWorldJNI.so
[json01@localhost jni]$
[json01@localhost jni]$ cp -f libHelloWorldJNI.so /users/lib
[json01@localhost jni]$
[json01@localhost jni]$ lsr /users/lib
合計 8
-rwxr-xr-x 1 json01 json01 5797 10月  1 14:57 libHelloWorldJNI.so


▶ 자바 컴파일
[json01@localhost jni]$ javac *.java
[json01@localhost jni]$ lsr
合計 28
-rw-r--r-- 1 json01 json01  299 10月  1 14:52 HelloWorldJNI.c
-rw-r--r-- 1 json01 json01  415 10月  1 14:52 HelloWorldJNI.h
-rw-r--r-- 1 json01 json01 1616 10月  1 14:55 HelloWorldJNI.o
-rwxr-xr-x 1 json01 json01 5797 10月  1 14:56 libHelloWorldJNI.so
-rw-r--r-- 1 json01 json01  402 10月  1 14:58 HelloWorldJNI.java
-rw-r--r-- 1 json01 json01  935 10月  1 14:58 HelloWorldJNI.class

▶ 자바 실행
 - 하지만 환경변수 LD_LIBRARY_PATH에 라이브러리가 없기에 아래의 에러가 발생했다.
[json01@localhost jni]$ java HelloWorldJNI
Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloWorldJNI in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1709)
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)
        at java.lang.System.loadLibrary(System.java:1028)
        at HelloWorldJNI.<clinit>(HelloWorldJNI.java:7)
Could not find the main class: HelloWorldJNI.  Program will exit.


▶ 환경변수 재설정.
[json01@localhost jni]$ vi /users/env/csh/csh_comm_env

# j-son add

echo "***** setting csh_comm_env ****"

#################
# section:environment variables
#################
setenv JAVA_HOME /usr/java/jdk1.6.0_15
setenv ORACLE_SID orcl
setenv ORACLE_BASE /opt/app/oracle
setenv ORACLE_HOME ${ORACLE_BASE}/product/11.1.0/db_1
#setenv ORA_NLS33 ${ORACLE_BASE}/ocommon/nls/admin/data
setenv NLS_LANG 'Japanese_Japan.UTF8'
setenv LANG ja_JP.UTF-8

set path = ($JAVA_HOME/bin $path $ORACLE_HOME/bin)
setenv LD_LIBRARY_PATH ${ORACLE_HOME}/lib:/users/lib


#################
# section:alias
#################
alias lsr 'ls -rtl'
alias history=200
alias h history
set savehist = 20


▶ 환경변수 적용하기
[json01@localhost jni]$ source ~/.login
***** setting .login ****
***** setting csh_comm_env ****
***** setting csh_comm_jboss ****
*************************************
***** Have A Nice Day 2009/10/01 ****
*************************************


▶ 자바 실행과 그 결과
[json01@localhost jni]$ java HelloWorldJNI
 result:Hello World. JNI