Android JNI 개요
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)정적 로 컬 방법의 두 번 째 매개 변 수 는 자바 류 에 대한 참조 이다. 나머지 매개 변 수 는 일반적인 자바 방법의 매개 변수 에 대응 하고 매개 변수 유형 은 일정한 규칙 에 따라 매 핑 해 야 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.