JNI 로 자바 프로 그래 밍 하기 (3)

11475 단어 자바jni
C / C + + 프로그램 에서 자바 코드 를 호출 합 니 다.
개술
JNI 는 이 컴퓨터 코드 에서 자바 류 방법 을 호출 할 수 있 습 니 다.이 를 위해 서 는 보통 Invocation API 를 사용 하여 이 컴퓨터 코드 에서 JVM 을 만 들 고 초기 화 해 야 합 니 다.다음은 C / C + 코드 에서 자바 코드 를 호출 하기 로 결정 할 수 있 는 전형 적 인 상황 입 니 다.
  • 실현 하고 자 하 는 이 부분 코드 는 플랫폼 과 무관 하고 다양한 플랫폼 에서 사용 하 는 기능 에 사 용 될 것 이다.
  • 이 컴퓨터 프로그램 에서 자바 언어 로 작 성 된 코드 나 코드 라 이브 러 리 를 방문 해 야 합 니 다.
  • 이 컴퓨터 코드 에서 표준 자바 라 이브 러 리 를 이용 하 기 를 희망 합 니 다.

  •  
    C / C + + 프로그램 에서 자바 코드 를 호출 하 는 네 단계
    C / C + + 에서 자바 방법 을 호출 하 는 네 가지 절 차 는 다음 과 같다.
  • 자바 코드 를 작성 합 니 다.이 단 계 는 하나 이상 의 자바 류 를 만 드 는 것 을 포함 합 니 다. 이 클래스 들 은 접근 하고 싶 은 기능 을 수행 합 니 다.
  • 자바 코드 를 컴 파일 합 니 다.이 자바 류 를 사용 할 수 있 기 전에 바이트 코드 로 컴 파일 하 는 데 성공 해 야 합 니 다.
  • C / C + 코드 를 작성 합 니 다.이 코드 는 JVM 을 만 들 고 예화 하 며 정확 한 자바 방법 을 호출 합 니 다.
  • 이 컴퓨터 의 C / C + + 응용 프로그램 을 실행 합 니 다.프로그램 이 정상적으로 작 동 하 는 지 확인 하기 위해 프로그램 을 실행 합 니 다.우 리 는 또 흔히 볼 수 있 는 오 류 를 처리 하 는 기교 에 대해 토론 할 것 이다.

  •  
    STEP 1: 자바 코드 작성
    우 리 는 하나 이상 의 자바 소스 코드 파일 을 작성 하 는 것 부터 시작 합 니 다. 이 파일 들 은 우리 가 이 컴퓨터 의 C / C + 코드 를 사용 하고 자 하 는 기능 을 실현 할 것 입 니 다.
    다음은 자바 코드 예제 Sample 2. java 를 보 여 줍 니 다.
    public class Sample2
    {
      public static int intMethod(int n) {
          return n*n;
      }
    
      public static boolean booleanMethod(boolean bool) {
          return !bool;
      }
    }

    주: Sample 2. 자바 는 두 가지 static 자바 방법 을 실현 했다. intMethod(int n)booleanMethod(boolean bool) (각각 세 번 째 줄 과 일곱 번 째 줄).static 방법 은 대상 실례 와 관련 이 없 는 클래스 방법 이다.호출 static 방법 은 실례 화 대상 이 필요 없 기 때문에 더욱 쉽다.
    STEP 2: 자바 코드 컴 파일
    다음 에 우 리 는 자바 코드 를 바이트 코드 로 컴 파일 할 것 이다.이 단 계 를 완성 하 는 방법 중 하 나 는 SDK 와 함께 제공 되 는 자바 컴 파일 러 javac 를 사용 하 는 것 이다.사용 하 는 명령 은:
    javac Sample1.java

    STEP 3: C / C + 코드 작성
    이 컴퓨터 프로그램 에서 실행 되 더 라 도 모든 자바 바이트 코드 는 JVM 에서 실행 되 어야 합 니 다.따라서 C / C + + 프로그램 은 JVM 을 만 들 고 초기 화 하 는 호출 을 포함해 야 합 니 다.SDK 는 우리 의 편 의 를 위해 공유 라 이브 러 리 파일 (jvm. dll 또는 jvm. so) 인 JVM 을 포함 하고 있 습 니 다. 이 라 이브 러 리 파일 은 이 컴퓨터 응용 프로그램 에 삽입 할 수 있 습 니 다.
    C 와 C + + 응용 프로그램의 전체 코드 를 탐색 한 다음 에 두 가 지 를 비교 합 시다.
    끼 워 넣 은 JVM 이 있 는 C 프로그램
    Sample2. c 는 끼 워 넣 은 JVM 을 가 진 간단 한 C 프로그램 입 니 다.
    #include <jni.h>
    
    #ifdef _WIN32
    #define PATH_SEPARATOR ';'
    #else
    #define PATH_SEPARATOR ':'
    #endif
    
    int main()
    {
      JavaVMOption options[1];
      JNIEnv *env;
      JavaVM *jvm;
      JavaVMInitArgs vm_args;
      long status;
      jclass cls;
      jmethodID mid;
      jint square;
      jboolean not;
    
      options[0].optionString = "-Djava.class.path=.";
      memset(&vm_args, 0, sizeof(vm_args));
      vm_args.version = JNI_VERSION_1_2;
      vm_args.nOptions = 1;
      vm_args.options = options;
      status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    
      if (status != JNI_ERR)
      {
         cls = (*env)->FindClass(env, "Sample2");
         if(cls !=0)
         { mid = (*env)->GetStaticMethodID(env, cls, "intMethod", "(I)I");
           if(mid !=0)
           { square = (*env)->CallStaticIntMethod(env, cls, mid, 5);
    				printf("Result of intMethod: %d
    ", square); } mid = (*env)->GetStaticMethodID(env, cls, "booleanMethod", "(Z)Z"); if(mid !=0) { not = (*env)->CallStaticBooleanMethod(env, cls, mid, 1); printf("Result of booleanMethod: %d
    ", not); } } (*jvm)->DestroyJavaVM(jvm); return 0; } else return -1; }

    끼 워 넣 은 JVM 이 있 는 C + + 프로그램
    Sample2. cpp 는 끼 워 넣 은 JVM 이 있 는 C + + 프로그램 입 니 다.
    #include <jni.h>
    
    #ifdef _WIN32
    #define PATH_SEPARATOR ';'
    #else
    #define PATH_SEPARATOR ':'
    #endif
    
    int main()
    {
    	  JavaVMOption options[1];
    	  JNIEnv *env;
    	  JavaVM *jvm;
    	  JavaVMInitArgs vm_args;
    	  long status;
    	  jclass cls;
    	  jmethodID mid;
    	  jint square;
    	  jboolean not;
    
    	  options[0].optionString = "-Djava.class.path=.";
    	  memset(&vm_args, 0, sizeof(vm_args));
    	  vm_args.version = JNI_VERSION_1_2;
    	  vm_args.nOptions = 1;
    	  vm_args.options = options;
    	  status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    
    	  if (status != JNI_ERR)
              {
    	    cls = (*env)->FindClass(env, "Sample2");
    	    if(cls !=0)
                {   mid = (*env)->GetStaticMethodID(env, cls, "intMethod", "(I)I");
                    if(mid !=0)
    	        {  square = (*env)->CallStaticIntMethod(env, cls, mid, 5);
    		       printf("Result of intMethod: %d
    ", square); } mid = (*env)->GetStaticMethodID(env, cls, "booleanMethod", "(Z)Z"); if(mid !=0) { not = (*env)->CallStaticBooleanMethod(env, cls, mid, 1); printf("Result of booleanMethod: %d
    ", not); } } (*jvm)->DestroyJavaVM(jvm); return 0; } else return -1; }

    C 와 C + + 의 비교
    C 와 C + 코드 는 거의 같다.유일한 차 이 는 JNI 함수 에 접근 하 는 방법 입 니 다.C 에 서 는 함수 포인터 가 인용 한 값 을 꺼 내기 위해 JNI 함수 호출 전에 접 두 사 를 추가 해 야 합 니 다 (*env)->.C + + 에서 JNIEnv 클래스 는 처리 함수 포인터 가 찾 는 내 연 구성원 함 수 를 가지 고 있 습 니 다.따라서 이 두 줄 의 코드 는 같은 함수 에 접근 하지만 모든 언어 는 각자 의 문법 이 있 습 니 다. 다음 과 같 습 니 다.
    C 문법:cls = (*env)->FindClass(env, "Sample2");
    C + + 문법:cls = env->FindClass("Sample2");
    C 응용 프로그램 에 대한 더욱 깊 은 연구
    우 리 는 방금 많은 코드 를 작 성 했 지만, 그것들 은 무엇 을 합 니까?절차 4 를 실행 하기 전에 C 응용 프로그램의 코드 를 더욱 깊이 연구 합 시다.자바 코드 를 처리 하고 JVM 을 이 컴퓨터 프로그램 에 끼 워 넣 은 다음 이 프로그램 에서 자바 방법 을 찾 아 호출 하 는 등 필요 한 절 차 를 먼저 탐색 할 것 입 니 다.
    jni. h 파일 포함
    저 희 는 C 응용 프로그램 에 포 함 된 jni. h C 헤더 파일 부터 시작 합 니 다. 아래 코드 샘플 에서 보 듯 이:
    #include <jni.h>

    jni. h 파일 은 C 코드 에 필요 한 JNI 의 모든 유형 과 함수 정 의 를 포함 합 니 다.
    선언 변수
    다음은 프로그램 에서 사용 하고 자 하 는 모든 변 수 를 설명 합 니 다.JavaVMOption options[] JVM 에 사용 할 다양한 옵션 설정 이 있 습 니 다.변 수 를 설명 할 때 원 하 는 모든 옵션 을 수용 할 수 있 도록 설명 한 JavaVMOption options[] 배열 이 충분 한 지 확인 하 십시오.이 예 에서 우리 가 사용 하 는 유일한 옵션 은 클래스 경로 옵션 입 니 다.이 예제 에서 모든 파일 이 같은 디 렉 터 리 에 있 기 때문에 클래스 경 로 를 현재 디 렉 터 리 로 설정 합 니 다.사용 하고 자 하 는 디 렉 터 리 구 조 를 가리 키 도록 클래스 경 로 를 설정 할 수 있 습 니 다.
    다음 코드 는 Sample 2. c 에 사용 할 변 수 를 설명 합 니 다.
    JavaVMOption options[1];
    JNIEnv *env;
    JavaVM *jvm;
    JavaVMInitArgs vm_args;

    주:
  • JNIEnv *env 는 JNI 의 실행 환경 을 나타 낸다.
  • JavaVM jvm 는 JVM 을 가리 키 는 지침 이다.우 리 는 주로 이 지침 을 사용 하여 JVM 을 만 들 고 초기 화 하 며 소각 합 니 다.
  • JavaVMInitArgs vm_args 는 JVM 의 각종 JVM 인 자 를 초기 화 할 수 있 음 을 나타 낸다.

  • 초기 화 매개 변수 설정JavaVMInitArgs 구 조 는 JVM 의 초기 화 매개 변 수 를 나타 낸다.자바 코드 를 실행 하기 전에 이 매개 변 수 를 사용 하여 실행 환경 을 맞 출 수 있 습 니 다.보시 다시 피 이 옵션 들 은 하나의 인자 이 고 자바 버 전 은 다른 인자 입 니 다.아래 와 같이 이 매개 변 수 를 설정 하 였 습 니 다.
    vm_args.version = JNI_VERSION_1_2;
    vm_args.nOptions = 1;
    vm_args.options = options;

    클래스 경로 설정
    다음은 JVM 에 필요 한 자바 류 를 찾 을 수 있 도록 클래스 경 로 를 설정 합 니 다.이 특정 예제 에 서 는 Sample2. class 와 Sample2. exe 가 같은 디 렉 터 리 에 있 기 때문에 클래스 경 로 를 현재 디 렉 터 리 로 설정 합 니 다.저 희 는 Sample 2. c 에 클래스 경 로 를 설정 하 는 코드 는 다음 과 같 습 니 다.
    options[0].optionString = "-Djava.class.path=."; 
    // same text as command-line options for the java.exe JVM

    위 vmargs 메모리
    사용 할 수 있 기 전에 메모리 가 남아 있어 야 합 니 다.메모리 가 설정 되면 버 전과 옵션 인 자 를 설정 할 수 있 습 니 다. 다음 과 같 습 니 다.
    memset(&vm_args, 0, sizeof(vm_args));  // set aside enough memory for vm_args
    vm_args.version = JNI_VERSION_1_2;         // version of Java platform
    vm_args.nOptions = 1;                      // same as size of options[1]
    vm_args.options = options;

    JVM 생 성
    모든 설정 을 처리 한 후 JVM 을 만 들 준 비 를 하고 있 습 니 다.호출 방법 부터 시작 합 니 다:
    JNI_CreateJavaVM(JavaVM **jvm, void** env, JavaVMInitArgs **vm_args)

    성공 하면 이 방법 은 0 을 되 돌려 줍 니 다. 그렇지 않 으 면 JVM 을 만 들 수 없 으 면 되 돌려 줍 니 다 vm_args.
    자바 클래스 찾기 및 불 러 오기
    JVM 을 만 들 면 이 컴퓨터 프로그램 에서 자바 코드 를 실행 할 준 비 를 할 수 있 습 니 다.우선, JNI_ERR 함 수 를 사용 하여 자바 류 를 찾 아 불 러 와 야 합 니 다. 다음 과 같 습 니 다.
    cls = (*env)->FindClass(env, "Sample2");
    FindClass() 변 수 는 실행 cls 함수 후의 결 과 를 저장 합 니 다.이 종 류 를 찾 으 면 FindClass() 변 수 는 자바 류 의 핸들 을 표시 합 니 다.이 종 류 를 찾 지 못 하면 cls 0 이 된다.
    자바 방법 찾기
    다음 에 우 리 는 cls 함수 로 이 클래스 에서 어떤 방법 을 찾 고 싶 습 니 다.우 리 는 방법 GetStaticMethodID() 을 찾 고 싶 습 니 다. 그것 은 하나의 intMethod 인 자 를 받 고 하나의 int 인 자 를 되 돌려 주 기 를 바 랍 니 다.다음은 찾기 int 의 코드 입 니 다.
    mid = (*env)->GetStaticMethodID(env, cls, "intMethod", "(I)I");
    intMethod 변 수 는 실행 mid 함수 후의 결 과 를 저장 합 니 다.이 방법 을 찾 으 면 GetStaticMethodID() 변 수 는 이 방법의 핸들 을 나타 낸다.이 방법 을 찾 지 못 하면 mid 0 이 된다.
    이 예제 에서 우 리 는 mid 자바 방법 을 호출 하고 있다 는 것 을 기억 하 세 요.그것 이 바로 우리 가 static 함 수 를 사용 하 는 원인 이다.GetStaticMethodID() 함 수 는 GetMethodID() 함수 의 기능 과 같 지만 인 스 턴 스 방법 을 찾 습 니 다.
    구조 기 를 호출 하고 있다 면 방법의 이름 은 'init' 입 니 다.호출 구조 기 에 대한 지식 을 더 알 고 싶 으 시 면 오류 처 리 를 참조 하 십시오.매개 변수 형식 을 지정 하 는 코드 와 JNI 형식 을 자바 의 원본 형식 에 어떻게 비 추 는 지 에 대한 지식 을 더 알 고 싶 으 시 면 부록 을 참조 하 십시오.
    자바 호출 방법
    마지막 으로, 우 리 는 자바 방법 을 호출 합 니 다. 다음 과 같 습 니 다.
    square = (*env)->CallStaticIntMethod(env, cls, mid, 5);
    GetStaticMethodID() 방법 수용 CallStaticIntMethod() (표시 류), cls (표시 방법) 및 이 방법 에 사용 되 는 하나 이상 의 매개 변수.이 예 에서 매개 변 수 는 mid 5 이다.
    당신 은 또 intCallStaticXXXMethod() 같은 방법 을 만 날 수 있 습 니 다.이러한 방법 은 정적 방법 과 구성원 방법 을 각각 호출 하고 방법의 반환 유형 (예 를 들 어 CallXXXMethod(), Object, Boolean, Byte, Char, Int 등) 대체 변수 Long 를 사용한다.
    STEP 4: 프로그램 실행
    현재 이 C 프로그램 을 실행 하고 코드 가 정상적으로 작 동 하도록 확보 하려 고 합 니 다.Sample2. exe 를 실행 할 때 다음 과 같은 결 과 를 얻 을 수 있 을 것 입 니 다.
    PROMPT>Sample2
    Result of intMethod: 25
    Result of booleanMethod: 0
    
    PROMPT>

    고장 제거
    JNI 의 Invocation API 는 C 언어 로 정의 되 어 있 으 며, C 언어 는 기본적으로 대상 을 대상 으로 프로 그래 밍 하 는 것 을 지원 하지 않 기 때문에 좀 번거롭다.결 과 는 문제 에 부 딪 히 기 쉽다 는 것 이다.다음은 검사 표 입 니 다. 일반적인 오 류 를 피 하 는 데 도움 이 될 수 있 습 니 다.
  • 인용 이 올 바 르 게 설정 되 어 있 는 지 항상 확인 하 십시오.예 를 들 어 XXX 방법 으로 JVM 을 만 들 때 0 으로 되 돌아 갈 수 있 도록 합 니 다.JNI_CreateJavaVM()FindClass() 방법 을 사용 하기 전에 인용 설정 이 0 이 아 닌 지 확인 하 십시오.
  • 방법 명 이 맞 춤 법 이 정확 한 지, 그리고 방법 설명 을 적 절 히 바 꾸 었 는 지 확인 하 세 요.정적 방법 GetMethodID() 과 구성원 방법 CallStaticXXXMethod() 을 사 용 했 는 지 확인 하 십시오.
  • 모든 자바 류 에 필요 한 특수 한 인자 나 옵션 을 사용 하여 JVM 을 초기 화 할 수 있 도록 확보 합 니 다.예 를 들 어 자바 류 에 많은 메모리 가 필요 하 다 면 최대 크기 옵션 을 추가 해 야 할 수도 있 습 니 다.
  • 클래스 경 로 를 정확하게 설 치 했 는 지 항상 확인 하 십시오.끼 워 넣 은 JVM 을 사용 하 는 이 컴퓨터 프로그램 은 jvm. dll 또는 jvm. so 공유 라 이브 러 리 를 찾 을 수 있어 야 합 니 다.

  • 종결 어
    C 에서 자바 를 호출 하 는 방법 은 상당히 고 급 스 러 운 '클래스 대상 프로 그래 밍' 기술 이 필요 하지만 경험 이 풍부 한 C 프로그래머 에 게 는 상대 적 으로 간단 하 다.JNI 는 C 와 C + + 를 지원 하지만 C + + 인 터 페 이 스 는 C 인터페이스 보다 더 뚜렷 해 야 합 니 다.
    중요 한 것 은 하나의 JVM 으로 여러 종류 와 방법 을 불 러 오고 실행 할 수 있다 는 것 을 기억 해 야 한다.이 컴퓨터 코드 와 자바 의 상호작용 을 통 해 JVM 을 만 들 고 없 앨 때마다 자원 을 낭비 하고 성능 을 떨 어 뜨 린 다.

    좋은 웹페이지 즐겨찾기