26
JNI 使使使使 使使 2016.09.29 Android Taipei

JNI 使用淺談

Embed Size (px)

Citation preview

Page 1: JNI 使用淺談

JNI 使用淺談 阿胖 2016.09.29

Android Taipei

Page 2: JNI 使用淺談

Outline1. Java call c

2. c call java

3. c vs cpp

4. Data Type Mapping

5. Data Type Convert

6. JNIEnv

Page 3: JNI 使用淺談

Java call c

HelloJni.java

hello-jni.c

Page 4: JNI 使用淺談

HelloJni.java

public native String stringFromJNI();

static {

System.loadLibrary("hello-jni");

}

Page 5: JNI 使用淺談

hello-jni.c

jtype Java_PATH_NAME_CLASSNAME_FUNCTIONNAME(

JNIEnv* env, jobject thiz [,… jparams] )

Page 6: JNI 使用淺談

hello-jni.c

jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ){ char msg[] = "Hello World from JNI !"; jstring jMsg = (*env)->NewStringUTF(env, msg);

return jMsg;}

Page 7: JNI 使用淺談

c call java

HelloJni.java

hello-jni.c

Page 8: JNI 使用淺談

HelloJni.java

private void callFromJni(String msg) {

Log.i(TAG,"123 "+msg);

}

Page 9: JNI 使用淺談

hello-jni.cNativeType Call<type>Method(JNIEnv *env, jobject obj, jmethodID methodID, ...);NativeType Call<type>MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);NativeType Call<type>MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);

jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);

jclass GetObjectClass(JNIEnv *env, jobject obj);

Page 10: JNI 使用淺談

hello-jni.cpp

jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) { char msg[] = "Hello World from JNI !"; jstring jMsg = env->NewStringUTF(msg);

return jMsg;}

jclass jClass = env->GetObjectClass(thiz); jmethodID mid = env->GetMethodID(jClass, "callFromJni", "(Ljava/lang/String;)V" ); env->CallVoidMethod(thiz, mid, jMsg);

Page 11: JNI 使用淺談

c vs cpp

jstring jMsg = (*env)->NewStringUTF(env, msg);

jstring jMsg = env->NewStringUTF(msg);

#ifdef __cplusplusextern "C" {#endif

#ifdef __cplusplus}#endif

Page 12: JNI 使用淺談

Data Type Mapping

Java primitive data type Native primitive data type Description

void void None

byte jbyte 8-bit signed. Range is -2^7 to 2^7 - 1

int jint 32-bit signed. Range is -2^31 to 2^31 - 1

float jfloat 32 bits. Represent a real number as small as 1.4 x 10-45 and as big as 3.4 x 1038 (approx.), positive or negative

double jdouble 64 bits. Represent a real number as small as 4.9 x 10-324 and as big as 1.7 x 10308 (approx.), positive or negative

char jchar 16-bit unsigned. Range is 0 to 65535

long jlong 64-bit signed. Range -2^63 to 2^63 - 1

short jshort 16-bit signed. Range is -2^15 to 2^15 - 1

boolean jboolean Unsigned 8 bits. true and false

Page 13: JNI 使用淺談

Data Type Mapping

Java Reference type JNI type Description

java.lang.object jobject Any Java object

java.lang.String jstring String representation

java.lang.Class jclass Java class object

java.lang.Throwable jthrowable Java throwable object

Page 14: JNI 使用淺談

Data Type MappingType Signature Java TypeZ boolean

B byte

C char

S short

I int

J long

F float

D double

V void

[ []

L<packet>/object; object

Page 15: JNI 使用淺談

Data Type Mapping

Function in java signature

int foo() “()I”

void foo(byte[] arg) “([B)V”

boolean foo(String arg) “(Ljava/lang/String;)Z”

"(parameterFieldDescriptor)returnFieldDescriptor"

Page 16: JNI 使用淺談

Data Type Convert

NewStringUTFjstring NewStringUTF(JNIEnv *env, const char *bytes);jstring jstr = (*env)->NewStringUTF(env, "This comes from jni.");

GetStringUTFCharsconst char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy);const char* str = (*env)->GetStringUTFChars(env, jstr , NULL);

ReleaseStringUTFCharsvoid ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf);

String

Page 17: JNI 使用淺談

Data Type Convert

New<PrimitiveType>Array RoutinesArrayType New<PrimitiveType>Array(JNIEnv *env, jsize length);

Set<PrimitiveType>ArrayRegion Routinesvoid Set<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, const NativeType *buf);

Array

Page 18: JNI 使用淺談

Data Type Convert

Get<PrimitiveType>ArrayElements RoutinesNativeType *Get<PrimitiveType>ArrayElements(JNIEnv *env,ArrayType array, jboolean *isCopy);

Release<PrimitiveType>ArrayElements Routinesvoid Release<PrimitiveType>ArrayElements(JNIEnv *env,ArrayType array, NativeType *elems, jint mode);

Get<PrimitiveType>ArrayRegion Routinesvoid Get<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, NativeType *buf);

Array

Page 19: JNI 使用淺談

Data Type Convert

struct{ char name[256]; int num;} Foo;

Object

class Foo { public String name; public int num;}

Page 20: JNI 使用淺談

Data Type Convert

FindClassjclass FindClass(JNIEnv *env, const char *name);“your/java/path/name/class_name$inner_class_name”

jmethodID mid = env->GetMethodID(msgClass, "<init>", "()V" );

NewObjectjobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...);

GetFieldIDjfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig);

Set<type>Field Routinesvoid Set<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID, NativeType value);

Get<type>Field RoutinesNativeType Get<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID);

Object

Page 21: JNI 使用淺談

Data Type Convert

NewGlobalRefjobject NewGlobalRef(JNIEnv *env, jobject obj);

DeleteGlobalRefvoid DeleteGlobalRef(JNIEnv *env, jobject globalRef);

DeleteLocalRefvoid DeleteLocalRef(JNIEnv *env, jobject localRef);

static_cast<type>

Page 22: JNI 使用淺談

JNIEnv

jint JNI_OnLoad(JavaVM* vm, void* reserved){ LOGI("JNI_OnLoad"); JNIEnv* env = NULL; jint result = -1; if(vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) { return result; }

jvm = vm; return JNI_VERSION_1_4;}

Page 23: JNI 使用淺談

JNIEnv* getJNIEnv() { JNIEnv* env = NULL; int res = jvm->GetEnv((void**)&env, JNI_VERSION_1_4);

if (res == JNI_EDETACHED) { //LOGI("GetEnv: not attached"); if (jvm->AttachCurrentThread(&env, NULL) != 0) { LOGI("Failed to attach"); return NULL; } } else if (res == JNI_OK) { // } else if (res == JNI_EVERSION) { LOGI("GetEnv: version not supported"); return NULL; } return env;}

Page 24: JNI 使用淺談

JNIEnv

JNIEnv* env = getJNIEnv();

/* do something */

jvm->DetachCurrentThread();

Page 25: JNI 使用淺談

Reference

http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html

http://www.developer.com/java/data/jni-data-type-mapping-to-cc.html

source code : https://github.com/kentpon/hello-jni

Page 26: JNI 使用淺談

QA