Android JNI 개요

JNI(Java Native Interface)자바 로 컬 인터페이스,자바 코드 는 JNI 를 사용 하여 외부 로 컬 C/C+코드 를 호출 합 니 다.마찬가지 로 외부 C/C+코드 는 자바 코드 를 호출 할 수 있 습 니 다.
NDK 와 JNI 의 차이 :  (1)NDK:NDK 는 Google 이 개발 한 개발 및 컴 파일 도구 모음 으로 Android 의 JNI 개발 에 주로 사 용 됩 니 다.(2)JNI:JNI 는 프로 그래 밍 인터페이스 로 자바 코드 와 로 컬 C/C+코드 의 상호작용 을 실현 합 니 다.
1.JNI 프로 그래 밍 절차:(1)native 방법 설명:자바 코드 에서 native method()방법 설명 하기;(2)JNI 를 실현 하 는 C/C+방법:JNI 층 에서 자바 에서 설명 하 는 native 방법 을 실현 하고 JNI 층 에서 C/C+코드 를 동적 라 이브 러 리 로 컴 파일 합 니 다.(3)동적 라 이브 러 리 불 러 오기 : 자바 코드 의 정적 코드 블록 에 JNI 컴 파일 된 동적 공유 라 이브 러 리 를 불 러 옵 니 다.
2.JNI 개발 방식 비교
정적 등록
(1)쓰기 가 불편 하고 JNI 층 함수 명 이 특히 길다.(2)네 이 티 브 함 수 를 처음 호출 할 때 함수 명 에 따라 대응 하 는 JNI 층 함 수 를 검색 하여 관련 관 계 를 맺 어야 효율 에 영향 을 줍 니 다.
동적 등록
(1)쓰기 가 편리 하 다.(2)함수 매 핑 표를 사용 하여 해당 함 수 를 호출 하여 효율 이 높다.
동적 등록
1.관건 인터페이스 소개
(1)System.loadLibrary()함수
          자바 프로그램 은 System.loadLibrary 를 통 해 JNI 동적 라 이브 러 리 를 불 러 와 C+함수 호출 을 완료 합 니 다.
	static{
		System.loadLibrary("HelloJNI");
	}

(2)JNI_OnLoad()함수
        JNI_OnLoad()함 수 는 VM 에서 System.loadlLibrary(xxx)함 수 를 실행 할 때 호출 되 며 두 가지 중요 한 역할 을 합 니 다.
        a.JNI 버 전 지정:VM 에 이 구성 요소 가 JNI 버 전 을 사용 하 는 것 을 알려 줍 니 다(JNI 가 제공 되 지 않 으 면OnLoad()함수,VM 은 기본 값 으로 가장 오래된 JNI 1.1 버 전 을 사용 합 니 다.JNI 1.4 버 전 같은 새 버 전의 JNI 를 사용 하려 면 JNI 를 사용 해 야 합 니 다.OnLoad()함수 반환 상수 JNIVERSION_1_4(이 상수 정 의 는 jni.h 에서)VM 에 게 알려 줍 니 다.
        b.설정 을 초기 화 합 니 다.VM 이 System.loadLibrary()함수 에 실 행 될 때 바로 JNI 를 호출 합 니 다.OnLoad()방법 은 이 방법 에서 각종 자원 의 초기 화 작업 을 하 는 것 이 가장 적절 하 며,동적 등록 작업 은 여기에서 이 루어 집 니 다.
(3)JNINativeMethod 구조 체
JNINativeMethod 구조 체 는 자바 와 C+함수 의 관 계 를 구축 하고 jni.h 에서 다음 과 같이 정의 된다.
typedef struct {
const char* name;
const char* signature;
void* fnPtr;
} JNINativeMethod;
첫 번 째 변 수 는 자바 함수 의 이름 입 니 다.
두 번 째 변수 signature 는 함수 의 인자 와 반환 값 을 문자열 로 설명 합 니 다.
세 번 째 변수 fnPtr 는 함수 포인터 로 C+함 수 를 가리킨다.
(4)RegisterNatives()와 registerNativeMethods()
RegisterNatives()는 registerNativeMethods()와 JNINativeMethod 구조 체 를 호출 하여 c/c++의 방법 을 자바 공간 에 투사 합 니 다.
다음은 핵심 코드 를 보고 모든 코드 를 다운로드 합 니 다.
static JNINativeMethod methods[] = {
	{"hello", "()Ljava/lang/String;", (void*) hello_jni },
};

static int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;

    clazz = env->FindClass(className);
    if (clazz == NULL) {
        fprintf(stderr, "Native registration unable to find class '%s'", className);
        return JNI_FALSE;
    }
    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
        fprintf(stderr, "RegisterNatives failed for '%s'", className);
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

static const char* classPathName = "com/example/hellojni/MainActivity";
static int registerNatives(JNIEnv* env)
{
  if (!registerNativeMethods(env, classPathName,
                 methods, sizeof(methods) / sizeof(methods[0]))) {
    return JNI_FALSE;
  }

  return JNI_TRUE;
}

typedef union {
    JNIEnv* env;
    void* venv;
} UnionJNIEnvToVoid;


jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    UnionJNIEnvToVoid uenv;
    uenv.venv = NULL;
    jint result = -1;
    JNIEnv* env = NULL;

    printf("JNI_OnLoad");

    if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
        fprintf(stderr, "GetEnv failed");
        goto bail;
    }
    env = uenv.env;

    if (!registerNatives(env)) {
        fprintf(stderr, "registerNatives failed");
    }

    result = JNI_VERSION_1_4;

bail:
    return result;
}

2.JNI 타 입 맵
Java 형식
네 이 티 브 타 입
유형 설명
Field descriptor
boolean
jboolean
C/C++8 비트 정형
Z
byte
jbyte
C/C++기호 가 있 는 8 비트 정형
B
char
jchar
C/C++기호 없 는 16 비트 정형
C
short
jshort
C/C++기호 가 있 는 16 비트 정형
S
int
jint
C/C++기호 가 있 는 32 비트 정형
I
long
jlong
C/C++기호 가 있 는 64 비트 정형
J
float
jfloat
C/C++32 비트 부동 소수점 형
F
double
jdouble
C/C++64 비트 부동 소수점 형
D
Object
jobject
자바 대상 이 없 거나 자바 형식 에 대응 하 는 대상 이 없습니다.
Ljava/lang/Object;
Class
jclass
클래스 대상
Ljava/lang/Object;
String
jstring
문자열 개체
Ljava/lang/String;
Object[]
jobjectArray
모든 대상 의 배열
[Ljava/lang/Object;
boolean[]
jbooleanArray
불 형 배열
[Z
byte[]
jbyteArray
비트 배열
[B
char[]
jcharArray
문자 배열
[C
short[]
jshortArray
짧 은 정형 배열
[S
int[]
jintArray
정형 수조
[I
long[]
jlongArray
긴 정형 배열
[J
float[]
jfloatArray
부동 소수점 배열
[F
double[]
jdoubleArray
더 블 부동 소수점 배열
[D
Void
Void
비다
V
3.JNI 디 버 깅
(1)헤더 파일 JNIlog.h 추가,링크 다운로드;(2)Android.mk 에 가입:     LOCAL_LDLIBS:=-log(3)호출     LOGD("%s:%u, static_hello", __func__, __LINE__);
4.정적 과 비정 상 원생 함수 의 차이     그 차이 점 은 두 번 째 매개 변 수 는 로 컬 방법 이 정적 인지 비 정적 인지 에 따라 다르다 는 것 이다.(1)비 정적 로 컬 방법의 두 번 째 매개 변 수 는 대상 에 대한 참조 이다.(2)정적 로 컬 방법의 두 번 째 매개 변 수 는 자바 류 에 대한 참조 이다.     나머지 매개 변 수 는 일반적인 자바 방법의 매개 변수 에 대응 하고 매개 변수 유형 은 일정한 규칙 에 따라 매 핑 해 야 합 니 다.

좋은 웹페이지 즐겨찾기