JNI 로 자바 프로 그래 밍 하기 (3)
개술
JNI 는 이 컴퓨터 코드 에서 자바 류 방법 을 호출 할 수 있 습 니 다.이 를 위해 서 는 보통 Invocation API 를 사용 하여 이 컴퓨터 코드 에서 JVM 을 만 들 고 초기 화 해 야 합 니 다.다음은 C / C + 코드 에서 자바 코드 를 호출 하기 로 결정 할 수 있 는 전형 적 인 상황 입 니 다.
C / C + + 프로그램 에서 자바 코드 를 호출 하 는 네 단계
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 이다.당신 은 또
int
와 CallStaticXXXMethod()
같은 방법 을 만 날 수 있 습 니 다.이러한 방법 은 정적 방법 과 구성원 방법 을 각각 호출 하고 방법의 반환 유형 (예 를 들 어 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()
을 사 용 했 는 지 확인 하 십시오.종결 어
C 에서 자바 를 호출 하 는 방법 은 상당히 고 급 스 러 운 '클래스 대상 프로 그래 밍' 기술 이 필요 하지만 경험 이 풍부 한 C 프로그래머 에 게 는 상대 적 으로 간단 하 다.JNI 는 C 와 C + + 를 지원 하지만 C + + 인 터 페 이 스 는 C 인터페이스 보다 더 뚜렷 해 야 합 니 다.
중요 한 것 은 하나의 JVM 으로 여러 종류 와 방법 을 불 러 오고 실행 할 수 있다 는 것 을 기억 해 야 한다.이 컴퓨터 코드 와 자바 의 상호작용 을 통 해 JVM 을 만 들 고 없 앨 때마다 자원 을 낭비 하고 성능 을 떨 어 뜨 린 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.