1. 자바 코드 작성
  2. 자바 가상 머신 생성
  3. 클래스 참조 얻기 (Class reference)
  4. Static method 호출 방법
    1. 메소드 구분자 얻기 (method identifier)
    2. 메소드 호출
  5. 객체 method 호출 방법
    1. 자바 언어 클래스의 인스턴스 생성
    2. 메소드 구분자 얻기(method identifier)
    3. 메소드 호출

1. 자바 코드 작성

*간단한 예제 소스

class FirsJavaEx{
     int AddFunc(int n1, int n2) {
          return (n1+n2);
     }

     static int staticAdd(int n1, int n2) {
     return (n1+n2);
     }
}

* 도스창에서 javac 명령어를 사용하여 FirstJavaEx.class 파일을 만든다.
* Visual Studio project 위치에 FirstJavaEx.class 파일을 넣는다.



2. 자바 가상 머신(JVM) 생성
* 환경 설정
- JNI를 사용하기 위해 환경 변수 설정하는 법(for Windows XP) 참고

* Visual Stuio
- project setting -> Link 탭 -> Ojbect/library modules:jvm.lib 추가
- 메뉴 -> Tools -> Options -> Directories 탭 : Java가 깔린 폴더를 추가해준다.
   * JDK1.6.0_02가 현재 최신 버전
   * Inculde files
     - C:\PROGRAM FILES\JAVA\SDK1.6.0_02\INCLUDE
     - C:\PROGRAM FILES\JAVA\SDK1.6.0_02\INCLUDE\WIN32
   * Library files
     - C:\PROGRAM FILES\JAVA\SDK1.6.0_02\LIB
   * Executable files (* 환경 변수 설정을 제대로 했다면 여기엔 이미 추가되어 있어야 함)
     - C:\PROGRAM FILES\JAVA\SDK1.6.0_02\BIN
     - C:\PROGRAM FILES\JAVA\SDK1.6.0_02\jre\bin\client

* jint JNI_CreateVM(JavaVM **jvm, void **env, void *vm_args)
- JavaVM **jvm  : An interface pointer, to the newly created Java Virtual machine.
- void **env : JNIEnv interface pointer env for the current thread. Recall that native code accesses JNI functions through the env interface pointer.
- void *vm_args: JavaVMInitArgs structure. It uses symbolic name/value pairs to encode arbitrary virtual machine start-up options.

예제 소스 (InvokeExFirst.cpp)
void main(){

     // JavaVM create & JVM environment setting start
     JavaVMOption options[1];
    
JavaVMInitArgs vm_args;
    JNIEnv *env;
    JavaVM *jvm;
     long status;
 
     options[0].optionString = "-Djava.class.path=.";
     memset(&vm_args, 0, sizeof(vm_args));
     vm_args.version = JNI_VERSION_1_6;
     vm_args.nOptions = 1;
     vm_args.options = options;
     status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
// JavaVM create & JVM environment setting end
   
...



3. 클래스 참조 얻기(Class reference)
* 사용하고자 하는 메소드를 포함하는 클래스에 대한 참조를 얻는다.
* FindClass("class_Name")

예제 소스 (InvokeExFirst.cpp)
     ...
     // JavaVM 생성
    ...
    jclass cls = env->FindClass("FirstEx");
     ...



4-1/5-2. 메소드 구분자 얻기(method identifier)
* 자바 언어는 메소드 중첩을 지원하기 때문에 호출하기를 원하는 특정 메소드 서명을 명시한다.

* static 메소드의 메소드 ID를 얻는 함수
- GetStaticMethodID(class_reference, "method_name","(parameter)return_Type");

* 객체 메소드의 메소드 ID를 얻는 함수
- GetMethodID(class_reference, "method_name","(parameter)return_Type");

예제 소스 (InvokeExFirst.cpp)
     ...
     jmethodID mid1 = env->GetStaticMethodID(cls, "staticAdd", "(II)I");
     ...
     jmethodID mid2 = env->GetStaticMethodID(cls, "AddFunc", "(II)I");
     ...



4-2/5-3. 메소드 호출
* return 형에 따른 type 종류
- Object, Boolean, Byte, Char, Short, Void, Int, Long, Float, Double

* Static 메소드를 호출해 주는 함수
-CallStatic<type>Method(class_reference, method_id, parameter1, parameter2, ...);

* 객체 메소드를 호출해 주는 함수
- Call<type>Method(object_reference, method_id, parameter1, parameter2, ...);

예제 소스 (InvokeExFirst.cpp)
     ...
     jint staticresult = env->CallStaticIntMethod(cls, mid, 10, 20);
     ...
     jint result = env->CallIntMethod(obj, mid, 10, 20);
     ...



5-1. 자바 클래스의 인스턴스 생성
* 클래스 참조로부터 생성자의 메소드 구분자(methodID)를 얻어 생성자를 호출한다.

* 생성자의 구분자 얻기
- jmethodId cls_constructor = env->GetMethodID(cls, "<init>", "()V")
- 생성자일 경우 메소드 이름을 써줄 필요 없이 <init> 로 넣는다.

* 생성자 호출 -> 인스턴스 생성
- jobject obj = env->NewObject(cls, cls_constructor, "()V");



실행 모습

사용자 삽입 이미지



























댓글 부탁드립니다아-