본문 바로가기

개발 언어/JAVA

[jni]객체의 메서드 실행하기


-Native Method 내부에서 자바의 메서드를 호출하는 방법은 바로 앞 절에서 언급한 객체의 변수에 접근하는 방법과 매우 유사한 단계를 거칩니다.

-1단계: 자바 객체의 타입 알아오기

-2단계: 자바 객체의 타입에서 부터, 호출하려는 메서드의 식별 정보를 알 오기

-3단계: 메서드의 식별 정보를 사용해서 메서드를 호출하기

2단계와 3단계에서 변수의 식별 정보 대신, 메서드의 식별 정보를 사용하는 것만이 달라졌다. 메서드의 식별정보는 jimethodID라는 JNI가 미리 정의해 놓은 타입을 사용한다.

한가지 주의할 점이 있다면 메서드의 경우 매개 변수와 값을 가지기 때문에, 이런 매개변수와 반환값을 Native Method가 이해할 수 있도록 특수한 처리를 해주어 한다.

MethodControl.java(두개의 int 형 데이터를 받아서 곱을 구한 후 반환해 주는 메서드)

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();

   }

}

C:\JavaExample\20> javac JavaObject.java

C:\JavaExample\20> javah JavaObject

 

20.5절의[표20.2]를 보면, 메서드의 매개변수와 반환형은 다음과 같이 표현이 된다. 앞이 매개변수의 데이터 타입이고 뒤가 반환되는 데이터의 타입이다.

==>(arg-types)ret-type

int add(int a, int b) 메서드의 매개변수와 반환형을 위 방식대로 표현하면, 다음과 같다.

==>(II)I

int형 매개 변수가 두개이기 때문에, 이를 나타내는 "I"문자가 특별한 구분자 없이 연속으로 쓰여져 있고, 리턴 타입역시 int이므로 "I"라고 표현되었다.

그러면, 실제로 MethodControl객체의 multi()메서드를 호출하는 Native Method의 코드를 작성해 보겠습니다.

MethodControl.c(MethodControl의 multi()메서드를 호출하는 Native 코드)

#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 a, b, c;

   a = 5;

   b = 10;

 

   c = (*env)->CallIntMethod(env, obj, m_id, a, b);

   printf("c = %d \n", c);

}

C:\JavaExample\method>cl -Ic:\jdk1.3.1\include -Ic:\jdk1.3.1\include\win32 -LD M

ethodControl.c -Fecontrol.dll

……

MethodControl.c

……

/dll

/implib:control.lib

/out:control.dll

MethodControl.obj

   Creating library control.lib and object control.exp

 

C:\JavaExample\method>java MethodControl

c = 50

 다른 코드들은 앞과 같고, 메서드의 참조값을 받는 부분만 살펴보면 될 것 같습니다.

 

n        jmethodID m_id = (*env)->GetMethodID(env, class_methodcontrol, "multi", "(II)I");

 

 여기서 인자로 쓰인 ‘multi’는 자바에서의 메서드 이름이고, ‘(II)I’은 메서드의 데이터 타입을 나타냅니다. 앞의 ‘(II)’는 메서드에 쓰인 매개변수의 데이터 타입이고, 뒤의 ‘I’는 반환되는 결과값의 데이터 타입입니다.

 

 다음은 CallIntMethod()메서드를 사용해서, 자바의 메서드를 C에서 호출해 결과값을 뽑아내는 코드입니다.

 

n        c = (*env)->CallIntMethod(env, obj, m_id, a, b);

 

 자바의 multi()메서드를 호출하기 위해, 앞에서 GetMethodID()메서드로 구한 메서드의 참조값을 인자로 주었습니다. 그리고 ‘a’와 ‘b’는 C에서 사용할 변수이름 입니다.

 

 JNI가 제공하는 메서드 호출 함수들은 다음과 같습니다. 데이터 타입에 적절하게 사용하시면 됩니다.

 

Call<returntype>Method

 

CallBooleanMethod

 

CallByteMethod

 

CallCharMethod

 

CallDoubleMethod

 

CallFloatMethod

 

CallIntMethod

 

CallLongMethod

 

CallObjectMethod

 

CallShortMethod

 

CallVoidMethod

 

20-4 JNI에서 제공하는 메서드 호출 함수

출처: http://blog.naver.com/kittenjun/10003051683

'개발 언어 > JAVA' 카테고리의 다른 글

Java Native Interface 설명서  (0) 2011.07.22
[JNI] 배열혈 아규먼트  (0) 2011.07.22
[jni]객체 필드에 접근하기  (0) 2011.07.22
[jni]문자열 전달 인자  (2) 2011.07.22
[jni] 숫자 인자와 변환값  (0) 2011.07.22