1 / 18

20 장 JNI (Java Native Interface)

20 장 JNI (Java Native Interface). 김 대 성 2002.1.21 yalli2@freechal.com http://www.jabook.org. 1. JNI 란 ?. 20.1 JNI 란 ?. Java Native Interface 다른 언어로 작성된 프로그램을 자바에서 실행할 수 있게 연결해주는 인터페이스 JNI 의 장점과 단점 장점 자바에서 구현할 수 없는 기능을 구현하게 해줌 각 언어의 장점을 이용할 수 있음 단점 플랫폼의 독립성을 잃어버림

katina
Download Presentation

20 장 JNI (Java Native Interface)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 20장 JNI(Java Native Interface) 김 대 성 2002.1.21 yalli2@freechal.com http://www.jabook.org

  2. 1. JNI란? 20.1 JNI란? • Java Native Interface • 다른 언어로 작성된 프로그램을 자바에서 실행할 수 있게 연결해주는 인터페이스 • JNI의 장점과 단점 • 장점 • 자바에서 구현할 수 없는 기능을 구현하게 해줌 • 각 언어의 장점을 이용할 수 있음 • 단점 • 플랫폼의 독립성을 잃어버림 • 플랫폼이 바뀌면 코드의 재사용성도 잃어버림 • 언어별 데이터 형의 차이를 일일이 수정해야함 • 여기서는 언급이 안된 예외처리부분도 신경을 써야함

  3. 2. 기초 JNI 예제 20.2 기초 JNI 예제 • JNI 실행 순서 • 먼저 Static블록에 있는 loadLibrary()메서드가 실행 • helloworld.dll 로딩 • main()메서드 실행 • printHelloWorld()메서드 호출 • 자바가상머신은 Helloworld.dll을 통해 C에서 생성한 프로그램 실행 • printf()메서드 실행하여 자바로 리턴 • 도스창에 Hello World! 출력 • main()메서드 종료

  4. public class HelloWorld{ static{ System.loadLibrary(“helloworld"); } public native void printHelloWorld(); public static void main(String[] args) throws Exception{ new HelloWorld().printHelloWorld(); } } 2. 기초 JNI 예제 1단계 • public static void loadLibrary(String labname); • C언어로 만들어진 dll파일을 로딩하는 역할 • Native 메서드가 호출되면 바로 실행하기 위해 사용 HelloWorld.java (라이브러리를 포함하는 자바 파일) 결과화면> C:\20>javac HelloWorld.java public native void printHelloWorld(); • native키워드 • 컴파일러에게 이 메서드의 구현은 외부의 다른 언어로 구현됨을 암시 System.loadLibrary(“helloWorld”);

  5. 2. 기초 JNI 예제 2단계 • 1단계에서 작성한 자바파일을 컴파일 • 다른 객체들이 Native메서드를 호출할 수 있도록 하기 위해 C:\20>javac HelloWorld.java

  6. 2. 기초 JNI 예제 3단계 • JVM이 사용할 헤더파일 생성 • JVM이 native메서드를 실행하기 위해 helloworld.dll의 헤더파일 생성 • 이 헤더파일을 통해서 C에서 작성된 helloworld.dll을 찾음 • 이 헤더파일은 C에서 사용하는 방법으로는 만들 수 없음 • 헤더파일의 내용 • HelloWorld클래스에서 선언한 printHelloWorld()메서드의 원형이 C의 문법으로 정의되어 있음 • 헤더파일 생성방법 ㅡ> javah 자바파일명 • Jdk안에 포함되어 있다. C:\20>javah HelloWorld

  7. #include <jni.h> #include “HelloWorld.h” #include <stdio.h> JNIEXPORT void JNICALL Java_HelloWorld_printHelloWorld (JNIEnv * env, jobject obj){ printf(“Hello World!\n”); return; } HelloWorld.c (native메서드를 실행할 C소스) 2. 기초 JNI 예제 4단계 • C언어로 Native Method생성 • 자바에서 printHelloWorld()메서드를 호출하면 C의 printf()함수가 실행 • 반드시 jni.h, HelloWorld.h, stdio.h 헤더 파일을 include 할 것

  8. 2. 기초 JNI 예제 5단계 • helloworld.dll 작성 • C 파일과 헤더 파일을 사용하여 helloworld.dll 생성 • -Ic:\jdk1.3.1\include: jni.h의 경로 • -Ic:\jdk1.3.1\include\win32 : jni_md.h의 경로 • -LD HelloWorld.c:컴파일할 c파일명 • -Fehelloworld.dll:생성할 dll파일명 • 반드시 loadLibrary()메서드에 주었던 매개변수명과 일치할 것 C:\20>cl -Ic:\jdk1.3.1\include -Ic:\jdk1.3.1\include\win32 -LD HelloWorld.c -Fehelloworld.dll HelloWorld.c /dll /implib:helloworld.lib /out:helloworld.dll HelloWorld.obj Creating library helloworld.lib and object helloworld.exp

  9. 2. 기초 JNI 예제 6단계 • Java HelloWorld를 실행 • 실행 순서 • 먼저 Static블록에 있는 loadLibrary()메서드가 실행 • helloworld.dll 로딩 • main()메서드 실행 • printHelloWorld()메서드 호출 • 자바가상머신은 Helloworld.dll을 통해 C에서 생성한 프로그램 실행 • printf()메서드 실행하여 자바로 리턴 • 도스창에 Hello World! 출력 • main()메서드 종료 C:\20>java HelloWorld Hello World!

  10. public class Calculator{ static{ System.loadLibrary("calculator"); } public native int add(int a, int b); public static void main(String[] args) throws Exception{ System.out.println(new Calculator().add(10,5)); } } #include <jni.h> #include "Calculator.h" #include <stdio.h> JNIEXPORT jint JNICALL Java_Calculator_add(JNIEnv *env, jobject obj, jint a, jint b){ jint sum; printf(“a+b= ”); sum = a + b; return sum; } Calculator.java (native메서드 생성) Calculator.c (Native Type의 사용의 예) 3. 숫자 인자와 반환값 20.3 숫자 인자와 반환값 • Native Type • 자바와 다른 언어간의 기본형데이터의 차이를 해결하기 위한 방법 • 단순히 java Type 앞에 j를 붙이면 된다. • 예> int -> jint 결과화면> C:\20>javac Calculator.java C:\20>javah Calculator C:\20>cl -Ic:\jdk1.3.1\include -Ic:\jdk1.3.1\include\win32 -LD Calculator.c -Fecalculator.dll C:\20>java Calculator a+b=15

  11. JNIEXPORT jstring JNICALL Java_Prompt_getLine(JNIEnv *env, jobject obj , jstring prompt) { printf("%s", prompt); ... } 잘못된 jstring의 사용 예 4. 문자열 전달 인자 20.4 문자열 전달 인자(1) • 자바와 C언어간의 문자열 데이터타입을 맞춰주기 위해 사용 • 자바에서는 String을 위해 16비트의 Unicode문자세트 사용 • C에서는 일반적으로 8비트의 문자배열로 문자열을 표현 • GetStringUTFChars()메서드를 사용하여 UTF-8문자열로 변경 • UTF-8문자열사용이 끝나면 ReleaseStringUTFChars()메서드로 해제 • 가상머신에게 UTF-8문자열을 더 이상 사용하지 않는다고 알려주는 역할

  12. public class MessageType { static { System.loadLibrary("message"); } public native String printMessage(String str); public static void main(String[] args) throws Exception { MessageType h = new MessageType(); System.out.println(h.printMessage("Type anything? : ")); } } MessageType.java (jstring 사용 예제) 4. 문자열 전달 인자 20.4 문자열 전달 인자(2) 결과화면> C:\20>javac MessageType.java C:\20>javah MessageType

  13. #include <jni.h> #include "MessageType.h" #include <stdio.h> JNIEXPORT jstring JNICALL Java_MessageType_printMessage(JNIEnv* env, jobject obj, jstring msg) { char buf[128]; const char *str = (*env)->GetStringUTFChars(env, msg, 0); printf("%s", str); (*env)->ReleaseStringUTFChars(env, msg, str); scanf("%s", buf); return (*env)->NewStringUTF(env, buf); } MessageType.c (jstring을 사용한 C파일) 4. 문자열 전달 인자 20.4 문자열 전달 인자(3) 1 2 3 자바의 16비트문자열을 C언어의 8바이트 문자열로 변환 가상머신에게 UTF-8문자열의 사용이 끝남을 알리고 메모리에서 자원을 해지 사용자로 부터 입력받은 문자열을 자바의 유니코드로 변환 1 2 3 결과화면> C:\20>cl -Ic:\jdk1.3.1\include -Ic:\jdk1.3.1\include\win32 -LD MessageType.c -Femessage.dll C:\JavaExample\20>java MessageType Type anything? : Hi!jabook Hi!jabook

  14. public class FieldControl { int int_a = 10; double double_b = -1.2345; static { System.loadLibrary("control"); } public native double add(); public static void main(String[] args) throws Exception { double c = new FieldControl().add(); System.out.println("final result ==> a + b = " + c); } } MessageType.java (멤버변수를 생성하는 자바 소스) 5. 객체 변수에 접근하기 20.5 객체 변수에 접근하기(1) • JNI가 제공하는 함수를 사용, 자바 객체의 변수에 접근 • Native 메서드에게 자바의 객체형과 변수의 형과 이름을 알려줄 것 결과화면> C:\20>javac FieldControl.java C:\20>javah FieldControl

  15. #include <jni.h> #include "FieldControl.h" #include <stdio.h> JNIEXPORT jdouble JNICALL Java_FieldControl_add (JNIEnv *env, jobject obj){ double c; jclass class_fieldcontrol = (*env)->GetObjectClass(env, obj); jfieldID id_a = (*env)->GetFieldID(env, class_fieldcontrol, "int_a", "I"); jint a = (*env)->GetIntField(env,obj,id_a); jfieldID id_b = (*env)->GetFieldID(env, class_fieldcontrol, "double_b", "D"); jdouble b = (*env)->GetDoubleField(env,obj,id_b); printf("a : %d \n", a); printf("b : %f \n", b); c= a+b; printf("before ==> a + b = %f \n", a+b); a += 5; (*env)->SetIntField(env, obj, id_a, a); b += 2.123; (*env)->SetDoubleField(env, obj, id_b, b); c= a+b; printf("after ==> a + b = %f \n", a+b); return c; } FieldControl.c (자바의 멤버변수를 조작하는 C언어의 소스코드) 5. 객체 변수에 접근하기 20.5 객체 변수에 접근하기(2) 결과화면> C:\20>cl -Ic:\jdk1.3.1\include -Ic:\jdk1.3.1\include\win32 -LD FieldControl.c -Fecontrol.dll C:\20>java FieldControl a : 10 b : -1.234500 before ==> a + b = 8.765500 after ==> a + b = 15.888500 final result ==> a + b = 15.8885

  16. public class MethodControl { static { System.loadLibrary("control"); } public native void add(); public int multi(int a, int b){ return a*b; } public static void main(String[] args) throws Exception{ new MethodControl().add(); } } MethodControl.java (멤버변수를 생성하는 자바 소스) 6. 객체의 메서드 실행하기 20.6 자바 메서드 실행하기(1) • C에서 자바의 메서드를 호출하는 방법 • 1단계 : 자바 객체 타입 알아오기 • 2단계 : 자바 객체 타입에서 호출하려는 메서드의 식별정보 알아오기 • 3단계 : 메서드의 식별정보를 사용해서 메서드 호출하기 결과화면> C:\20>javac MethodControl.java C:\20>javah MethodControl

  17. #include <jni.h> #include "MethodControl.h" #include <stdio.h> JNIEXPORT void JNICALL Java_MethodControl_add (JNIEnv *env, jobject obj){ jclass class_methodcontrol = (*env)->GetObjectClass(env, obj); jmethodID m_id = (*env)->GetMethodID(env, class_methodcontrol, "multi", "(II)I"); jint c_a, c_b, c_c; c_a = 5; c_b = 10; c_c = (*env)->CallIntMethod(env, obj, m_id, c_a, c_b); printf("c = %d \n", c_c); } 6. 객체의 메서드 실행하기 20.6 자바 메서드 실행하기(2) FieldControl.c (자바의 메서드를 호출하는 C언어의 소스코드) 결과화면> C:\20>cl -Ic:\jdk1.3.1\include -Ic:\jdk1.3.1\include\win32 -LD MethodControl.c -Fecontrol.dll C:\20>java MethodControl c = 50

  18. 7. 마무리 20.7 마무리 • JNI • 자바에서 다른 언어로 쓰여진 애플리케이션을 사용할 수 있도록 연결 • JNI의 장점과 단점 • 장점 • 자바에서 구현할 수 없는 기능을 구현하게 해줌 • 각 언어의 장점을 이용할 수 있음 • 단점 • 플랫폼의 독립성을 잃어버림 • 플랫폼이 바뀌면 코드의 재사용성도 잃어버림 • 언어별 데이터 형의 차이를 일일이 수정해야함 • 여기서는 언급이 안된 예외처리부분도 신경을 써야함 • JNI 실행 순서 • 먼저 Static블록에 있는 loadLibrary()메서드가 실행 • helloworld.dll 로딩 • main()메서드 실행 • printHelloWorld()메서드 호출 • 자바가상머신은 Helloworld.dll을 통해 C에서 생성한 프로그램 실행 • printf()메서드 실행하여 자바로 리턴 • 도스창에 Hello World! 출력 • main()메서드 종료

More Related