<31353DB1E8BBF3C8C62E687770>

Similar documents
JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

슬라이드 1

PowerPoint Presentation

PowerPoint Presentation

PowerPoint Presentation

PowerPoint Presentation

JAVA PROGRAMMING 실습 08.다형성

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

gnu-lee-oop-kor-lec06-3-chap7

금오공대 컴퓨터공학전공 강의자료

PowerPoint 프레젠테이션

PowerPoint Presentation

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

PowerPoint Template

설계란 무엇인가?

02 C h a p t e r Java

PowerPoint 프레젠테이션

JVM 메모리구조

Microsoft PowerPoint - chap10-함수의활용.pptx

Microsoft PowerPoint - ch07 - 포인터 pm0415

PowerPoint Presentation

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

Microsoft PowerPoint - Java7.pptx

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

슬라이드 1

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

11장 포인터

쉽게 풀어쓴 C 프로그래밍

Design Issues

17장 클래스와 메소드

쉽게 풀어쓴 C 프로그래밍

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap06-2pointer.ppt

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

JAVA PROGRAMMING 실습 02. 표준 입출력

JAVA PROGRAMMING 실습 02. 표준 입출력

Microsoft PowerPoint - chap01-C언어개요.pptx

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

쉽게 풀어쓴 C 프로그래밍

JAVA PROGRAMMING 실습 05. 객체의 활용

TEST BANK & SOLUTION

1. 자바프로그램기초 및개발환경 2 장 & 3 장. 자바개발도구 충남대학교 컴퓨터공학과

PowerPoint 프레젠테이션

Data Structure

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

class Sale void makelineitem(productspecification* spec, int qty) SalesLineItem* sl = new SalesLineItem(spec, qty); ; 2. 아래의액티비티다이어그램을보고 Java 또는 C ++,

Microsoft PowerPoint - additional01.ppt [호환 모드]

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap06-1Array.ppt

1 장 C 언어복습 표준입출력배열포인터배열과포인터함수 const와포인터구조체컴파일러사용방법 C++ 프로그래밍입문

Microsoft PowerPoint - 2강

슬라이드 1

untitled

PowerPoint Presentation

PowerPoint Presentation

쉽게

Microsoft PowerPoint - C++ 5 .pptx

API 매뉴얼

ThisJava ..

Microsoft Word - JNI.doc

Microsoft PowerPoint - chap11-포인터의활용.pptx

OCW_C언어 기초

설계란 무엇인가?

Microsoft PowerPoint 장강의노트.ppt

JAVA PROGRAMMING 실습 09. 예외처리

SFCMVCLHFEXZ.hwp

(8) getpi() 함수는정적함수이므로 main() 에서호출할수있다. (9) class Circle private double radius; static final double PI= ; // PI 이름으로 로초기화된정적상수 public

강의 개요

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

11장 포인터

윤성우의 열혈 TCP/IP 소켓 프로그래밍

adfasdfasfdasfasfadf

쉽게 풀어쓴 C 프로그래밊

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

학습목표 함수프로시저, 서브프로시저의의미를안다. 매개변수전달방식을학습한다. 함수를이용한프로그래밍한다. 2

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

Microsoft PowerPoint - 제11장 포인터(강의)

Microsoft PowerPoint - Lect04.pptx

쉽게 풀어쓴 C 프로그래밍

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

슬라이드 1

C++ Programming

교육자료

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

Microsoft PowerPoint - chap06-5 [호환 모드]

Microsoft PowerPoint - chap12-고급기능.pptx

PowerPoint Template

금오공대 컴퓨터공학전공 강의자료

Microsoft PowerPoint - lec2.ppt

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

JAVA PROGRAMMING 실습 02. 표준 입출력

<4D F736F F F696E74202D2036C0CFC2B05FB0B4C3BCC1F6C7E2C7C1B7CEB1D7B7A1B9D62E707074>

Lab 3. 실습문제 (Single linked list)_해답.hwp

PowerPoint 프레젠테이션

PowerPoint Presentation

Microsoft PowerPoint - CSharp-10-예외처리

Transcription:

자바네이티브메소드를위한통합개발환경 Integrated Development Environment for Java Native Methods 김상훈세명대학교컴퓨터학부 Sang-Hoon Kim(kimsh@semyung.ac.kr) 요약다양한모바일장비의등장으로인하여해당장비에서실행가능한응용프로그램의요구가증가하고있다. 플랫폼독립적이란특성을가지는자바언어는이러한환경에최적의프로그래밍언어로급부상하고있다. 그러나자바는가상기계에의해실행되므로플랫폼의존적인기능을제공하지못하는단점을가진다. 썬마이크로시스템즈에서는이러한문제점을해결하기위해자바네이티브메소드라는 JNI 기술을제시하였다. JNI 기술을이용하기위해서는 JVM의내부구조와 JNI에대한풍부한지식이필요하다. 또한수많은 JNI 함수의사용으로인하여프로그램개발생산성과품질의저하를초래하고있다. JNI에대한지식없이쉽고빠르게네이티브프로그래밍이가능하도록도와주는지원도구의필요성대두되고있다. 이를위해서는자바언어와 C/C++ 언어사이에존재하는구문과의미상차이점을자동적으로처리해주어야한다. 본연구에서자바와 C/C++ 언어간에차이점과이를극복하기위한방안을제시하고이를바탕으로개발한 JNI 통합개발환경을소개한다. 중심어 : 자바 자바네이티브인터페이스 자바가상기계 Abstract As a result of a growing demand for various mobile devices, the demand for application programs on the devices is on the rise. The Java language that is platform-independent rapidly rose as the best programming language for mobile devices. However, the Java has a problem that does not support platform-dependent features needed by the application. To solve this problem, the JNI technology was introduced by Sun Microsystems. Programmers using the JNI to write native methods need to have a lot of knowledge about the JNI and the internal structure of the JVM. Also, the increased load by using a number of JNI functions may decrease software productivity and quality. Demands for tools writing native method without understanding of JNI are progressively increasing. To develop these tools, it is necessary to translate automatically the differences between Java and C/C++. In this study, I suggested a way to overcome differences between both languages and developed JNI editor that is an integrated develope environment on the basis of this. keyword : Java Java Native Interface Java Virtual Machine 접수번호 : #100527-001 접수일자 : 2010 년 05 월 27 일 심사완료일 : 2010 년 06 월 29 일교신저자 : 김상훈, e-mail : kimsh@semyung.ac.kr

자바네이티브메소드를위한통합개발환경 123 I. 서론다양한모바일장비들의증가에비례하여콘텐츠의수요또한급속히증가하고있다. 플랫폼에독립적이라는자바언어 [9] 의특성은이러한상황에최적이다. 그러나자바는소프트웨어적으로이루어진자바가상기계 (Java Virtual Machine: JVM)[10] 를사용하므로플랫폼의존적인작업및기존코드의재사용의어려우며실행속도저하를가져온다. 이문제를해결하기위해썬마이크로시스템즈는자바네이티브인터페이스 (Java Native Interface: JNI)[7] 라는기술을제시하였다. JNI 기술은자바와네이티브언어간의교량역할을제공한다. 현재는사용가능한네이티브언어로 C와 C++ 가있다. JNI를사용하기위해서는 JVM의내부구조와 JNI에대한지식을요구한다. 또한 JVM과의적절한정보교환을위해다수의전처리와후처리과정이필요하다. 따라서 JNI에대한충분한지식을가지고있더라도각종 JNI 함수의적절한선택과처리는시간소모적이고지루한작업이며, 이는소프트웨어개발생산성과품질의저하를가져오고있다. 이문제로고생하는개발자들에게도움을줄수있는통합개발환경 (Integrated Development Environment: IDE) 인 JNIEditor를본연구에서제시한다. 본도구는자바프로그램과 C/C++ 프로그램상호간에자료및제어전달에필요한다양한전처리및후처리과정을자동으로처리하여프로그래머가두언어간의정보전달체계를의식하지않고프로그래밍에집중할수있다. 또한 JNI를사용하기위해서는헤더파일생성, 네이티브메소드구현, 컴파일, 동적라이브러리생성등다수의부가작업이필요하다. JNIEditor는이상에서열거한기능을통합적으로수행하여주는통합개발환경이다. 역사적으로 C 언어에서 C++ 로, C++ 에서자바로발전하는과정을가진다. 이러한역사적배경으로인하여기본문형과자료형측면에서자바와 C/C++ 는매우유사한형태를가진다. 그러나자바의클래스, 필드, 메소드란개념은 C 언어에존재하지않으므로이에대응하 는 C 언어의개념이필요하다. 본연구에서는클래스를파일로변환하고, 필드와메소드를파일영역을가지는외부정적변수와외부함수로변환한다. 자바의기본자료형과참조형은 C 언어의기본형과포인터로대응시켜변환한다. C++ 언어는 C 언어에비해엄격한형검사 (type checking) 를수행한다는점을제외하면 C 언어는 C++ 언어의진부분집합 (proper subset) 이다. 이성질을이용하여네이티브언어로는 C와 C++ 를모두가능하도록하였다. 논문의구성은다음과같다. 기존환경에서네이티브메소드작성의어려움과이를해결하기위한관련연구를 2장에서살펴본다. 3장에서는자바언어와 C/C++ 언어간의차이를극복하고상호연결시기위한방안을제시하고, 3장에서제안한방법에따라구현된 JNIEditor 및사용사례를 4장에서설명한다. 5장평가및결론에서는연구의성과와제약사항을알아보도록한다. Ⅱ. 연구배경연구의필요성에대해알아보도록하자. 우선명령어창또는통합개발환경에서 JNI를사용하는데어려움을알아보고, 이를해결하기위한기존연구와지원라이브러리들의문제점에대해살펴본다. 최근가장많이사용되는자바를위한통합개발환경에는 Eclipse[3] 와 NetBeans[1] 가있다. 이들은프로그램작성, 컴파일, 테스트, 디버깅, 실행등을통합적으로지원하는개발환경으로일반자바프로그램개발에집중되어있다. 명령어창또는기존통합개발환경에서네이티브메소드를구현하는과정과그의어려움을알아본다. 네이티브메소드선언 sumarray() 를포함한 SumTester 클래스인 [ 그림 1] 과, 그선언에해당하는네이티브메소드구현인 [ 그림 2] 를살펴보자. 네이티브메소드를구현한함수는 JNI 명세에따라변형되어네이티브메소드선언과다른형태의함수원형을사용하여야한다. 그리고그함수의매개변수 arr로전달된정수배열은 JVM 내부에유지되므로 C 코드에서직접접근할수없다. 배열객체를접근하기위해서는버퍼

124 한국콘텐츠학회논문지 '10 Vol. 10 No. 7 를할당후, 그버퍼로정수형배열을얻어오는 JNI 함수 GetIntArrayRegion 을사용하거나, 또는 [ 그림 2] 와같이배열의원소로직접접근할수있는포인터를얻어오는 GetIntArrayElements라는 JNI 함수를사용하여야한다. 전달된배열을가지고작업을수행한후, 더이상네이티브코드가자바의기본형배열을접근하지않는다는것을 JVM 알리기위해 ReleaseArrayElements를호출하여야한다. 이를행하지않으면변경된배열의내용이 JVM에반영되지않는다. import java.util.*; public class SumTester { private native int sumarray(int[] arr, size); public static void main(string[] args) { Scanner scan = new Scanner(System.in); SumTester st = new SumTester(); int[] arr = new int[5]; for(int i = 0; i < arr.length; i++) arr[i] = scan.nextint(); scan.close(); System.out.println(st.sumArray(arr)); static { System.loadLibrary("SumTester"); #include "SumTester.h" 그림 1. class SumTester JNIEXPORT jint JNICALL Java_SumTester_sumArray(JNIEnv *env, jobject obj, jintarray arr, jint size){ jint * carr; jint sum = 0; int i; carr = (*env)->getintarrayelements(env, arr, NULL); if(carr == NULL) return 0; for(i=0; i < size; i ++) sum += carr[i]; (*env)->releaseintarrayelements(env, arr, carr, 0); return sum; 그림 2. 네이티브메소드 sumarray 단순히배열의합을구하는프로그램에서조차도 JNI 에서요구하는형태로변형된네이티브함수이름의작 성및 JNI가사용하는자료형의이해가필요하며자바배열을접근하기위한전처리와후처리과정을요구하고있다. 이는 JVM과의인터페이스인 JNI를충분히습득한프로그래머에게조차도귀찮고지루한작업이며이로인하여코딩오류를유발시킬가능성이크고개발생산성저하를야기한다. 기존개발환경을사용한네이티브메소드구현의어려움을해소하기위해이러한복잡한처리과정을 C++ 의 template 기능을이용하여캡슐화를시도한연구 JNI - C++ inegration made easy" 가있다 [4]. [ 그림 3] 은이연구에서제시한 JNI 캡슐화프레임워크를사용하여네이티브메소드구현예이다. // JniExample.java public class JniExample { public int intfield = 17; public int[] intarray = new int[2];... private static native void native_call(jniexample x);... // jni_example.cpp JNIEXPORT void JNICALL Java_JniExample_native_1call( // 가 JNIEnv* env, jclass clazz, jobject obj) { // Lookup the Java fields in 'obj' JNIField<jint> intfield(env, obj, "intfield"); // 나 JNIStringUTFChars str(env, "JniExample", "stringfield"); // 다 // Set new values intfield = 0; arr[0]=0; arr[1]=0; 그림 3. JIN 캡슐화프레임워크를사용한코드 [ 그림 3] 의 jni_example.cpp" 의함수원형 ( 가 ) 을살펴보면기존방식과동일하게변형된함수원형을사용하여야한다. 다시말해서 JNI 명세를인지해야한다는것이다. C++ 의 constructor와 destructor가각각전처리와후처리를담당하고있다. 따라서네이티브코드에서자바객체를접근하기위해서는네이티브코드구현자가접근하는멤버단위로 [ 그림 3] 의나, 다와같은코드를삽입하여주어야한다. 이방법은 JNI 함수복잡한사용부담을덜어주는장점은가지나대신위연구에서

자바네이티브메소드를위한통합개발환경 125 제시한템플릿의사용이란새로운부담이생기고있다. 마지막으로 C++ 템플릿을기반으로하고있어네이티브언어로 C 언어를사용할수없다는한계점을가진다. 이외에현재기존네이티브코드로작성된라이브러리의수월한호출을가능하도록도와주는 JNA[8], HawtJNI[5], GlueGen[6] 등이있다. 이들도구들은자바환경에서 JNI의존재를의식하지않고네이티브함수들을자유로이호출할수있도록도와주는라이브러리또는도구들이다. 그러나 C 환경에서자바객체의접근에대한고려는없거나또는빈약하다는단점을가진다. 또한 JNI를대신하는새로운클래스와메소드를습득해야하는추가부담을가진다. 본연구에서는네이티브언어로 C와 C++ 모두사용가능하며변형되지않은네이티브메소드선언을그대로사용하고자한다. 또한자바언어와네이티브언어상호간에 JNI의존재를의식하지않고접근할수있도록하고자한다. 더구나기존통합개발환경은 JNI 네이티브메소드번역및실행을위해많은부가적인작업을수동으로해야한다. 이또한매우불편한일이다. 따라서네이티브코드작성, javah 를사용한헤더파일생성, 동적라이브러리생성, 실행을통합적으로수행할수있는도구를개발하고자한다. Ⅲ. 자바와네이티브언어의연결 JNIEditor 는자바환경과네이티브코드환경간의차이를극복해주는코드를자동으로생성하여주어야한다. 이를지원하기위한네이티브코드환경의기본구조와수행작업에대해알아보도록하자. 자바객체와네이티브메소드상호간의접근은다음두가지관점으로나누어고려해야한다. 첫째는자바객체에서네이티브함수를호출하는것이고, 두번째는네이티브함수에서자바객체의필드를접근하고자바메소드를호출하는것이다. JNI의존재를의식하지않고상호간에접근또는호출을가능하도록하기위해서는두언어간에구문구조및의미의차이를해결하여 주어야한다. 자바의기본자료형과 C/C++ 의기본자료형은유사하나동일하지않다. 구조자료형 (structured data type) 은다른모양을가진다. 따라서자료형간의변환이필요하다. 매개변수의전달에서도차이를보인다. 기본자료형에서는두언어모두값전달방식 (call by value) 을취하고있으나구조자료형의경우자바는 C/C++ 의포인터또는참조전달의형태만을취하고있다. JNIEditor를사용하는개발자는 C/C++ 와자바언어를모두알고있는프로그래머를대상으로한것이므로이러한차이점의극복은문제가되지않는다. 본논문에서는유사하나역할에있어중요한차이를보이는몇가지메소드 ( 함수 ) 가등장한다. 이를간단히그리고명료하게설명하기위해용어를명확히정의가필요하다. 자바클래스에나타나는네이티브메소드선언에대응되며, JNI 명세에따른함수헤더를가지는함수를자바네이티브메소드구현이라하겠다. 그리고네이티브메소드구현의실재실행코드를가지고있는함수를 C 언어에서는메소드라는용어대신함수란용어를사용하고있으므로네이티브함수라기술할것이다. 이네이티브함수에서자바메소드를직접호출할수없다. 호출하기위해서는메소드 ID를얻어와 Call<Type>Method 를사용하여간접적으로호출하게된다. 또한매개변수의변환이필요하다. 이러한과정을대리로처리하여호출해주는함수를프락시함수 (proxy function) 라하겠다. 자바클래스 네이티브메소드 1 선언네이티브메소드 2 선언. 네이티브메소드 n 선언 자바메소드 네이티브메소드프레임 n... 네이티브메소드프레임 2 네이티브메소드프레임 1 네이티브메소드구현 전처리 후처리...... 네이티브함수 그림 4. 자바메소드와네이티브메소드간의관계 네이티브함수에서필드와메소드를자유로이접근

126 한국콘텐츠학회논문지 '10 Vol. 10 No. 7 하기위해서는그의참조가네이티브언어환경내에미리정의되고초기화되어있어야한다. 이러한참조는네이티브메소드단위로존재한다. 이러한참조와네이티브함수그리고부가선언들을포함하고있는파일단위의구조를네이티브메소드프레임이라하겠다. 네이티브코드환경은네이티브메소드의개수만큼의네이티브메소드프레임을가지며이는파일로만들어진다. 네이티브메소드와자바객체가상호간에접근을처리하여주는다양한변수및함수선언으로이루어진네이티브메소드프레임은파일영역을갖는다. [ 그림 4] 는이상에서설명한자바메소드, 네이티브메소드선언, 네이티브메소드구현, 네이티브함수들간의관계를그림으로표현한것이다. 3.1 네이티브함수의호출자바메소드에서네이티브함수의호출은네이티브메소드구현부분을경유하여간접호출이이루어진다. 이를그림으로도시하면 [ 그림 5] 이며그림의원숫자는호출순서이다. 자바메소드는네이티브메소드선언을참조하여호출을한다. [ 표 1] 은네이티브메소드선언, 네이티브메소드구현, 네이티브함수의헤더를보여주고있다. 네이티브메소드선언과달리 JNI 명세규칙에따라작성된네이티브메소드구현은아주상이한형태를가진다. 그러나네이티브메소드선언과네이티브함수는유사한형태를보여주고있다. 네이티브메소드구현자는네이티브함수의원형을참고하여네이티브프로그램을작성하게된다. 표 1. 네이티브메소드의종류별헤더 메소드종류 네이티브메소드선언 네이티브메소드구현 네이티브함수 메소드헤더 public native int getport(short num, String str) JNIEXPORT jint JNICALL Java_NMSim_getPort( JNIEnv *_env, jclass _cls, jshort num, jstring str) long getport(short num, const char * str) 자바메소드가네이티브함수를호출하는경우매개변수로전달되는자료와반환으로돌려받는값에대해고려하여보자. 기본자료형은두언어간에유사하다. 매개변수전달방식은모두값전달방식을사용하고있으므로 [ 표 2] 와같이대응하는자료형으로의단순변환만으로직접접근하여사용가능하다. 자바에서구조자료형은 C의입장에서보면모두포인터이다. 또한직접접근은불가능하며 JNI을경유하여접근하여야한다. 따라서자바에서전달받은구조자료형의객체는 C 언어에서접근할수있는형태로변환해주어야한다. 자바는구조자료형으로배열, 클래스, 인터페이스를제공하고있다. 그러나네이티브코드에서복잡한구조를가지는객체를접근하는경우는드물며다단계의전후처리부담으로인하여비효율적인구현이되기쉽다. 따라서본연구에서는자바참조형중에서접근가능한자료형은스트링과기본형배열로제한하고있다. 표 2. 기본자료형매핑 자바클래스 네이티브메소드프레임 i 네이티브메소드구현네이티브함수 자바 C/C++ 언어 자바 C/C++ 언어 boolean unsigned char long long long byte signed char float float 네이티브메소드 i 선언 자바메소드 1 전처리 2 char unsigned short double double short short void void int long 4 3 후처리그림 5. 네이티브함수호출 매개변수로전달된자바스트링은 JNI 함수인 GetStringUTFChars 을사용하여 C 스트링으로변환하여읽어온다. 이때자바스트링의자료형은 jstring이

자바네이티브메소드를위한통합개발환경 127 며 C 스트링의자료형은 const char* 이다. 반환된스트링의사용을종료하면 ReleaseStringUTFChars를호출하여 C 스트링을위해사용된메모리를 free해주어야한다. 스트링과마찬가지로배열도 C 환경에서직접접근하여사용할수없다. C 환경에서기본형배열을직접접근할수있도록배열로의포인터를얻어오기위해 JNI 함수 Get<Type>ArrayElements 를사용하고, 사용을종료한후이사실을 JVM에알리고변경사항을반영하기위해 Release<Type>ArrayEmements를호출해야한다. C 언어의배열과는달리자바배열은원소의개수를나타내는 length 속성을가진다. 이차이점을해소하기위해매개변수로전달된각배열마다 length 변수가추가적으로필요하다. 메소드이름과배열명그리고 length 를연결한 methodname_arrayname_ length 형태의정적외부변수를두어처리한다. 매개변수로전달된기본형배열과이에대응하는 C 언어의배열형간의대응관계는 byte[] 는 char *, short[] 는 short *, int[] 는 long * 등이며 [ 표 2] 의나머지자료형도유사한형태로대응된다. 지금까지매개변수를통하여자바환경에서부터네이티브언어환경으로전달된객체의접근방법을자료형별로나누어살펴보았다. 3.2 자바객체의필드접근네이티브함수에서자바객체의필드를접근하는방법에대해살펴보도록하자. 자바의필드는매개변수와는달리기본자료형도직접접근이불가능하다. 필드의값을참조하기위해서는 GetFieldID 와 Get<Type>Field를사용하여필드의값을네이티브언어환경으로가져와야한다. 또한네이티브함수에서필드의값을변경하였다면 Set<Type>Field 를사용하여변경사항을자바객체에반영시켜야한다. 이와같이기본자료형에서조차도전처리와후처리과정이요구된다. 자바객체의필드에해당하는변수를네이티브언어환경인네이티브메소드프레임파일의정적외부변수로등장시키고전후처리하는과정이필요하다. 자바클래스 필드선언 int f1; double f2; 자바메소드 1 1 네이티브메소드프레임 i 네이티브메소드구현 3 전처리 후처리 그림 6. 필드의접근과변경반영 static int f1; 2 static double f2; 네이티브함수 // access f1 sum = f1; 필드의접근및변경반영과정을 [ 그림 6] 에서보여주고있다. JNIEditor는네이티브함수구현자가접근이필요한필드를선택하도록하고있다. 모든필드를네이티브메소드프레임영역으로이동시킨다면사용하지않는필드가발생할수있다. 사용하지않는필드에대한전처리와후처리과정은불필요한자원의낭비를초래한다. 따라서필요한필드를사용자가선택하도록하였다. 사용자에의해선택된각필드는그에해당하는정적외부변수로 C 환경에생성되고, 전처리과정을통하여정적외부변수의값을해당필드의값으로초기화된다. 이후네이티브함수에서이정적외부변수를자바의필드로고려하여자유로이접근할수있다. 사용이종료된후, 즉네이티브함수의종료직후변경된필드의내용은후처리과정을통하여자바객체의실제필드에반영하게된다. 나머지자료형들간의대응관계와접근방법은매개변수와동일하다. 본방법에제약사항이존재한다. 네이티브함수에서필드의값을변경한후자바메소드를호출하여그필드의값을참조한다면변경된값을접근할수없다. 이는네이티브함수의종료후수행하는후처리과정에서변경에대한반영을수행하기때문에발생하는문제이다. 이를해결하기위해서는모든자바메소드호출전에변경에대한반영을수행해야하나이는전체환경에너무많은부담을초래하므로이를제한하기로하였다. 3.3 자바메소드의호출 네이티브함수에서자바객체의메소드를호출하는

128 한국콘텐츠학회논문지 '10 Vol. 10 No. 7 call-back에대해알아보도록하자. 네이티브언어환경에존재하는네이티브함수에서자바메소드를호출하기위해서는다음과정이필요하다. 첫째 GetObjectClass 와 GetStaticMethodID 를호출하여메소드식별자를얻어야한다. 그다음반환자료형이 Type인메소드를호출하기위해서는 Call<Type>Method 를사용하여호출하게된다. 이때네이티브함수에서자바메소드로전달하는자료와자바메소드에서반환받는자료의변환이필요하다. 자료의변환과자바메소드의호출을함께모아처리하여주는프락시함수개념을도입하여처리하도록하였다. 프락시함수는매개변수로전달된자료의변화, 자바메소드호출, 반환된자료의변환이란 3가지작업을수행하게된다. 첫단계는프락시함수가전달받은매개변수를자바메소드가접근할수있는자바객체로변환하는전처리과정이다. 기본자료형은 [ 표 2] 의자료형매핑테이블에따라단순형변환으로직접전달가능하다. 그러나구조자료형에대해서는자바객체를생성하는과정을수행해야한다. C 스트링의경우는자바스트링으로변환하기위해 NewStringUTF를사용해야되며, 배열의경우는 New<Type>Array를사용하여새로운자바배열객체를생성하여야한다. 이때 C 언어에서배열은배열원소의개수에대한정보를가지고있지않다. 따라서 call-back에의해호출가능한메소드의매개변수가배열을포함하고있다면 methodname_arrayname_length 형태의미리정의된정적외부변수를가지고있어야하며, 자바메소드호출전에네이티브함수에서초기화해주어야한다. 두번째단계는 Call<Type>Method 를사용하여호출하고반환값이있으면이를반환받는단계이다. 마지막후처리단계는반환받은값을네이티브함수에서접근가능한형태로변환한후, 프락시함수를호출한네이티브함수로값을되돌려보내는작업으로네이티브메소드구현의전처리단계와유사하다. 이상에서설명한내용을네이티브함수에서자바메소드의호출과정을 [ 그림 7] 에서보여주고있다. 자바클래스 자바메소드 2 자바메소드 1 2 3 네이티브메소드프레임 i 프락시함수 전처리 후처리 네이티브메소드구현 1 4 그림 7. 자바메소드의호출 Ⅳ. JNIEditor 의구현과사용사례 static int f1; static double f2; 네이티브함수 // call 메소드 2 자바객체와 C/C++ 함수간에 JNI를의식하지않고자유로이상호접근하기위해서는네이티브메소드프레임이어떠한구조를가져야하는지 3장에서살펴보았다. 본장에서는 JNIEditor의구성과실제사용사례를통해본시스템의이해와필요성, 그리고방법의옳음을보이고자한다. 이시스템에서네이티브메소드프레임을생성하기위해서는클래스파일로부터필드, 메소드, 매개변수등의주요정보를얻어야한다. 이를위해 Apache Jakarta Project 중에하나인 BCEL(Byte Code Engineering Library)[2] 을사용하였다. BCEL 라이브러리를사용하여얻어진클래스정보를바탕으로 3장에서언급한네이티브메소드프레임을생성한다. 주변환경은 GUI 패키지인 swing 을사용하여자바로구현하였으며전체구조는 [ 그림 8] 과같다. [ 그림 8] 에서막대인간이지시하는자바클래스와네이티브함수틀부분을제외하면나머지부분은자동으로지원되는부분이다. 사용자는네이티브메소드선언을포함한자바클래스를작성하고네이티브함수프레임내부에위치한네이티브함수틀에 C/C++ 를사용하여코드를작성한다. 완성된네이티브함수를포함한각각의네이티브메소드프레임들은생성되어파일로만들어진다. 이파일들은 C/C++ 컴파일러에의해한개의동적라이브러리로구성된다. 마지막으로자바클래스파일과라이브러리는 JVM에함께적재되어실행된

자바네이티브메소드를위한통합개발환경 129 다. 이상의과정은 JNIEditor에의해자동으로이루어진다. 1 4 자바클래스자바컴파일러 코딩 BCEL 네이티브메소드프레임생성기 외부선언생성 필드코드생성 네이티브메소드구현생성 2 5 6 클래스파일 코딩 프락시함수생성 네이티브함수틀 3 7 자바가상기계실행결과 javah 헤더파일 동적라이브러리 네이티브메소드 1 네이티브메소드 2... 네이티브메소드 n 그림 8. JNIEditor 의구조 C/C++ 컴파일러 public class NTester { int jdata[] = {3, 5, 7, 9; String errormsg; 그림 9. JNIEditor 의실행 public native static int sumarray(int[] data); public native void printfield(); public native void calljm(); 네이티브메소드선언을포함한자바클래스를예제로하여본도구를사용하는방법과생성된프로그램을살펴보도록하자. [ 그림 9] 는 [ 그림 10] 의 class NTester 의번역된클래스파일을읽어들인상태이다. 영역 1 은필드선택창으로자바클래스의필드를보여주고, 영역 2는자바클래스의메소드를보여주고있다. 영역 3은명령어라인매개변수를직접입력할수있는창이있다. 영역 4 리스트박스는자바클래스에포함된네이티브메소드선언을가지고있다. 사용자가리스트박스에서네이티브메소드선언을선택하면영역 6에그에해당하는네이티브메소드프레임이나타나며, 그내부에 C/C++ 코드를작성할수있는네이티브함수틀인영역 5가포함되어있다영역 7은표준출력또는표준오류를출력하기위한윈도우를가지고있다. public String getmsg() {... int getvalue(short index){... public static void main(string[] args) { int data[] = {3, 5, 7, 9; NTester nt = new NTester(); System.out.println(sumArray(data)); nt.printfield(); nt.calljm(); System.out.print("In Java: "); for(int val: nt.jdata) System.out.print(val + ","); System.out.println(); static { System.loadLibrary("NTester"); 그림 10. Class NTester [ 그림 10] 의첫번째네이티브메소드인 sumarray는매개변수로넘어온정수형배열의내용을합하여결과를반환하는함수라가정하자. C 언어에서배열은원소의개수를포함하고있지않다. 따라서배열의길이에대한정보가변수 sumarray_arg0_length에유지하고있다. 이변수의값은네이티브메소드구현의전처리단계에서초기화된다. 배열의길이정보를이용하여구현된네이티브함수는 [ 그림 11] 과같다.

130 한국콘텐츠학회논문지 '10 Vol. 10 No. 7 long sumarray(long* arg0){ long sum = 0; int i = 0; for(i = 0; i < sumarray_arg0_length; i++) sum += arg0[i]; return sum; 그림 11. sumarray() 함수의구현 다음으로자바필드를접근하는예를알아보자. [ 그림 10] 의두번째네이티브메소드에서필드 jdata 의내용을그대로출력하고값을변경하여주는네이티브함수를작성하여보자. 불필요한전처리부담을경감하기위해필드선택창에서접근할필드를사용자가선택하여야한다. 이는 [ 그림 12] 의 1과같이네이티브환경으로이동된배열과배열길이선언한코드의생성을야기시킨다. 선택을해제한다면 1 코드부분을자동으로삭제될것이다. 필드또한매개변수처리와마찬가지로네이티브메소드구현의전처리부분에서초기화되고변경사항은후처리부분에의해반영될것이다. 1 2 3 그림 12. 네이티브메소드 printfield() [ 그림 13] 은필드의값을모두출력하고각원소에 10 을더하는프로그램이다. 네이티브함수 printfield() 의실행결과인 In C: array 3 5 7 9 와배열을갱신한내 용을자바에서출력한결과인 In Java:13,15,17,19, 를 [ 그림 12] 의 3에서확인할수있다. void printfield(){ // TODO: Insert a code for the Native method! printf("in C: array "); for(int i = 0; i < jdata_length; i++) { printf("%d ", jdata[i]); jdata[i] += 10; printf("\n"); 그림 13. printfield() 함수의구현 void calljm(){ // TODO: Insert a code for the Native method! printf("in C => %s\n", getmsg()); 그림 14. calljm() 함수의구현 마지막으로네이티브함수에서자바메소드를호출하는 Call-back 에대해알아보도록하자. [ 그림 12] 의 2는일반자바메소드에해당하는프락시함수선언이다. 이메소드의존재는 [ 그림 9] 의 2와 [ 그림 10] 에서각각확인할수있다. 이프락시함수선언은정적네이티브메소드 sumarray의프레임영역에서나타나지않는다. 정적네이티브메소드에서는인스턴스메소드를호출할수없기때문이다. 그러나 printfield() 는인스턴스네이티브메소드이므로프락시함수선언부가필요하고, 또한프락시함수정의가네이티브메소드프레임하단에포함되어있다. 네이티브함수에서자바메소드를호출하여문자열자료를얻어출력하는프로그램은 [ 그림 14] 와같다. 프로그램의실행결과는 [ 그림 12] 의 3에서 "In C:=>Hello" 로알수있다. 이와같 이자바메소드를대리로호출하여주는프락시함수를두어네이티브함수에서일반 C 함수를호출하는방법과동일하게자바함수를호출할수있음을보여주었다. 이상에서설명한방법으로각네이티브메소드선언당한개의네이티브메소드프레임이생성되며이는파일형태로저장되어진다. 자바클래스 NTester 는 3

자바네이티브메소드를위한통합개발환경 131 개의네이티브메소드프레임파일이생성되어지며공유라이브러리형태로번역되고링크되어 JVM에의해사용된다. [ 그림 15] 는 JNIEditor 에의해자동으로생성된네이티브메소드프레임파일중 "public native void printfield()" 를위한프레임파일이다. /* NTester_printField.cpp */ #include"ntester.h" // Field declaration,cnt:1 static long* jdata; static jsize jdata_length; static JNIEnv* _env;... 중략... static long getvalue(short); void printfield(){ // TODO: Insert a code for the Native method!... 중략... //Don't edit the following statements. JNIEXPORT void JNICALL Java_NTester_printField(JNIEnv *_env, jobject _obj){ jclass _cls = _env->getobjectclass(_obj); jfieldid _fid_jdata, _fid_errormsg; jintarray _jarr_jdata; jstring _jstr_errormsg; _envobjcopy(_env, _obj); //s,f,0,4 _fid_jdata = _env->getfieldid(_cls, "jdata", "[I");... 중략... //<printfield(); //-> //e,f,0,1 _env->releaseintarrayelements(_jarr_jdata, jdata, 0); const char * getmsg(){ jstring _retval; const char * _nretval; _cls = _env->getobjectclass(_obj); _mid = _env->getmethodid(_cls, "getmsg", "()Ljava/lang/String;"); _retval = static_cast<jstring>(_env->callobjectmethod(_obj, _mid)); _nretval = _env->getstringutfchars(_retval, NULL); return _nretval; long getvalue(short arg1){... 중략... Ⅴ. 평가및결론플랫폼이다양해짐에자바의사용분야가급속히증가하고있는추세이다. 그러나플랫폼의존적인작업의한계를극복하기위해 JNI을사용해야한다. JNI 기술을이용하기위해서는부가적지식과수많은 JNI 함수의사용으로인하여프로그램개발생산성과품질의저하를초래하고있다. 이러한문제점은기존의통합개발환경에서해결하지못한다. C++ template class에 JNI 전처리및후처리캡슐화를시도한연구에서는이상의문제점은어느정도완화시키고있다. 그러나 template class의사용으로인하여 C 컴파일러의사용이불가능하고또한 template class의사용법습득이란부담이발생한다. HawtJNI, GlueGen, JNA 등은자바환경에서네이티브함수로의호출에중점을두고있어 C 환경에서자바객체의필드와메소드접근이어려움을가진다. 이에비해본 JNIEditor은두언어의양방향접근이가능하며추가적지식습득의부담이없음을 4장에있는 [ 그림 11][ 그림 13][ 그림 14] 의사용자작성네이티브코드를보면확인할수있다. 본아이디어의옳음을확인하기위해 4장에서실제구현된 JNIEditor 를사용하여얻어진실행결과를보여주었다. 본도구가지원하는자료형은기본자료형과배열, 그리고스트링으로제한된다. JNI의일반적사용은기존코드의재사용, 실행속도향상, 플랫폼의존적인작업의수행이다. 우선네이티브코드로작성된코드의재사용은자바클래스제작이전에존재하는코드이므로해당객체의내부를접근하는코드는존재하지않는다. 두번째로실행속도향상을위해네이티브메소드를사용하는경우이다. 복잡한객체의잦은내부접근은오히려실행속도의저하요인으로등장한다. 이는이전연구에서실험을통하여입증하였다. 마지막은플랫폼의존적인작업을하고자네이티브메소드를사용한경우이다. 이는대부분하드웨어나운영체제를직접제어하거나또는자료를교환하는경우이므로기본자료형또는단순배열로작업이가능하다. 그림 15. 자동생성된메소드프레임

132 한국콘텐츠학회논문지 '10 Vol. 10 No. 7 참고문헌 [1] Amit Kumar Saha, "Beginning JNI with NetBeans C/C++ Pack 6.0, Linux," http://cnd.netbeans.org/docs/jni/nb6-linux/beg inning-jni-linux.html [2] BCEL. http://jakarta.apache.org/bcel/index.html [3] Eclipse. http://www.eclipse.org [4] Evgeniy Gabrilovich, Lev Finkelstein, "JNI - C++ integration made easy", C/C++ Users Journal, Vol.19, Issue 1. 10-21 CMP Media, Inc. 2001. [5] HawtJNI, http://fusesource.org/forge/projects/hawtjni [6] GlueGen, https//gluegen.dev.java.net [7] Java Native Interface Specification. http://java.sun.com/javase/6/docs/technotes/ guides/jni/spec/jnitoc.html [8] JNA, http://jna.dev.java.net [9] Ken Arnold, James Gosling, and David Holmes, The Java Programming Language Fourth Edition, Addition Wesley, 2005. [10] Tim Lindholm and Frank Yellin, The Java Virtual Machine Specification Second Edition, Addison Wesley, 1999. 저자소개 김상훈 (Sang-Hoon Kim) 정회원 1989년 2월 : 동국대학교컴퓨터공학과 ( 공학석사 ) 1996년 8월 : 동국대학교컴퓨터공학과 ( 공학박사 ) 1997년 3월 ~ 현재 : 세명대학교컴퓨터학부부교수 < 관심분야 > : 프로그래밍언어, 컴파일러, 소프트웨어공학