Android NDK开发之JNI基础知识

JNI层方法命名规范

在java层对应的native方法的声明,test方法是一个本地方法,其参数是字符串类型,返回值是字符串类型。

package com.kltz88.jnidemo;{static {System.loadLibrary(“test”);}public native String test(String name);}

由android studio自动生成的native层的方法如下。

#include <jni.h>JNIEXPORT jstring JNICALLJava_com_kltz88_car_jnidemo_Test_test(JNIEnv *env, jobject instance, jstring name_) {const char *name = (*env)->GetStringUTFChars(env, name_, 0);// TODO(*env)->ReleaseStringUTFChars(env, name_, name);return (*env)->NewStringUTF(env, returnValue);}函数的命名规则

函数命名规则为:Java_类全路径方法名。如Java_com_kltz88_jnidemo_Test_test,其中Java是函数的前缀,com_kltz88_jnidemo_Test是类名,test是方法名,它们之间用 _(下划线) 连接。

函数参数

JNIEXPORT jstring JNICALL Java_com_kltz88_jnidemo_Test_test(JNIEnv *, jclass, jstring ); – 第一个参数:JNIEnv* 是定义任意native函数的第一个参数(包括调用JNI的RegisterNatives函数注册的函数),指向JVM函数表的指针,函数表中的每一个入口指向一个JNI函数,每个函数用于访问JVM中特定的数据结构。 – 第二个参数:调用java中native方法的实例或Class对象,如果这个native方法是实例方法,则该参数是jobject,如果是静态方法,则是jclass – 第三个参数:Java对应JNI中的数据类型,Java中String类型对应JNI的jstring 类型。

函数返回值类型

夹在JNIEXPORT和JNICALL宏中间的jstring ,表示函数的返回值类型,对应Java的void类型

JAVA层与JNI层数据类型的对应

下面是一个测试方法

(char c,short s,byte by,int i,long l,float f,double d,boolean b,String str,Object o,Test t,int[] arr);

jni层面生成的函数原型

JNIEXPORT void JNICALLJava_com_kltz88_car_jnidemo_Test_test(JNIEnv *env, j, , jint i,jlong l, jfloat f, jdouble d, jboolean b, jstring str_,j, jintArray arr);

我们会发现基本数据类型直接会有一种对应关系

其实只是使用了typedef重新定义了一下

jboolean;jbyte;jchar;jshort;jint;jlong;jfloat;jdouble;/* 64-bit IEEE 754 */

进一步还会发现,引用类型也存在一定的对应关系

也是通过typedef重新定义了一下,都是一个指针

typedef void*jobject;typedef jobjectjclass;typedef jobjectjstring;typedef jobjectjarray;typedef jarrayjobjectArray;typedef jarrayjbooleanArray;typedef jarrayjbyteArray;typedef jarrayjcharArray;typedef jarrayjshortArray;typedef jarrayjintArray;typedef jarrayjlongArray;typedef jarrayjfloatArray;typedef jarrayjdoubleArray;typedef jobjectjthrowable;typedef jobjectjweak;方法签名字段描述

值得注意的是 – 类是使用L全限定名;,比如String, 其签名为Ljava/lang/util/String; – 数组是使用[类型签名, 比如 [B

方法描述

JNI层暴露的方法 jint(*GetVersion)(JNIEnv *);jclass(*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,jsize);jclass(*FindClass)(JNIEnv*, const char*);jmethodID (*FromReflectedMethod)(JNIEnv*, jobject);jfieldID (*FromReflectedField)(JNIEnv*, jobject);/* spec doesn’t show jboolean parameter */jobject(*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);jclass(*GetSuperclass)(JNIEnv*, jclass);jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass);/* spec doesn’t show jboolean parameter */jobject(*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);jint(*Throw)(JNIEnv*, jthrowable);jint(*ThrowNew)(JNIEnv *, jclass, const char *);jthrowable (*ExceptionOccurred)(JNIEnv*);void(*ExceptionDescribe)(JNIEnv*);void(*ExceptionClear)(JNIEnv*);void(*FatalError)(JNIEnv*, const char*);jint(*PushLocalFrame)(JNIEnv*, jint);jobject(*PopLocalFrame)(JNIEnv*, jobject);jobject(*NewGlobalRef)(JNIEnv*, jobject);void(*DeleteGlobalRef)(JNIEnv*, jobject);void(*DeleteLocalRef)(JNIEnv*, jobject);jboolean (*IsSameObject)(JNIEnv*, jobject, jobject);jobject(*NewLocalRef)(JNIEnv*, jobject);jint(*EnsureLocalCapacity)(JNIEnv*, jint);jobject(*AllocObject)(JNIEnv*, jclass);jobject(*NewObject)(JNIEnv*, jclass, jmethodID, …);jobject(*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);jobject(*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);jclass(*GetObjectClass)(JNIEnv*, jobject);jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass);jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);jobject(*CallObjectMethod)(JNIEnv*, jobject, jmethodID, …);jobject(*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);jobject(*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, …);jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jbyte(*CallByteMethod)(JNIEnv*, jobject, jmethodID, …);jbyte(*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);jbyte(*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jchar(*CallCharMethod)(JNIEnv*, jobject, jmethodID, …);jchar(*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);jchar(*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jshort(*CallShortMethod)(JNIEnv*, jobject, jmethodID, …);jshort(*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);jshort(*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jint(*CallIntMethod)(JNIEnv*, jobject, jmethodID, …);jint(*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);jint(*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jlong(*CallLongMethod)(JNIEnv*, jobject, jmethodID, …);jlong(*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);jlong(*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jfloat(*CallFloatMethod)(JNIEnv*, jobject, jmethodID, …) __NDK_FPABI__;jfloat(*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;jfloat(*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;jdouble(*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, …) __NDK_FPABI__;jdouble(*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;jdouble(*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;void(*CallVoidMethod)(JNIEnv*, jobject, jmethodID, …);void(*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);void(*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);jobject(*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,jmethodID, …);jobject(*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jobject(*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,jmethodID, …);jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jbyte(*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,jmethodID, …);jbyte(*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jbyte(*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jchar(*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,jmethodID, …);jchar(*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jchar(*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jshort(*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,jmethodID, …);jshort(*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jshort(*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jint(*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,jmethodID, …);jint(*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jint(*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jlong(*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,jmethodID, …);jlong(*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);jlong(*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jfloat(*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,jmethodID, …) __NDK_FPABI__;jfloat(*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list) __NDK_FPABI__;jfloat(*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*) __NDK_FPABI__;jdouble(*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,jmethodID, …) __NDK_FPABI__;jdouble(*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list) __NDK_FPABI__;jdouble(*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*) __NDK_FPABI__;void(*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,jmethodID, …);void(*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,jmethodID, va_list);void(*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,jmethodID, jvalue*);jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);jobject(*GetObjectField)(JNIEnv*, jobject, jfieldID);jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID);jbyte(*GetByteField)(JNIEnv*, jobject, jfieldID);jchar(*GetCharField)(JNIEnv*, jobject, jfieldID);jshort(*GetShortField)(JNIEnv*, jobject, jfieldID);jint(*GetIntField)(JNIEnv*, jobject, jfieldID);jlong(*GetLongField)(JNIEnv*, jobject, jfieldID);jfloat(*GetFloatField)(JNIEnv*, jobject, jfieldID) __NDK_FPABI__;jdouble(*GetDoubleField)(JNIEnv*, jobject, jfieldID) __NDK_FPABI__;void(*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);void(*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);void(*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);void(*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);void(*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);void(*SetIntField)(JNIEnv*, jobject, jfieldID, jint);void(*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);void(*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat) __NDK_FPABI__;void(*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble) __NDK_FPABI__;jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);jobject(*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, …);jobject(*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);jobject(*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, …);jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,va_list);jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,jvalue*);jbyte(*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, …);jbyte(*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);jbyte(*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jchar(*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, …);jchar(*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);jchar(*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jshort(*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, …);jshort(*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);jshort(*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jint(*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, …);jint(*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);jint(*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jlong(*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, …);jlong(*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);jlong(*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jfloat(*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, …) __NDK_FPABI__;jfloat(*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list) __NDK_FPABI__;jfloat(*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*) __NDK_FPABI__;jdouble(*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, …) __NDK_FPABI__;jdouble(*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list) __NDK_FPABI__;jdouble(*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*) __NDK_FPABI__;void(*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, …);void(*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);void(*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*,const char*);jobject(*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);jbyte(*GetStaticByteField)(JNIEnv*, jclass, jfieldID);jchar(*GetStaticCharField)(JNIEnv*, jclass, jfieldID);jshort(*GetStaticShortField)(JNIEnv*, jclass, jfieldID);jint(*GetStaticIntField)(JNIEnv*, jclass, jfieldID);jlong(*GetStaticLongField)(JNIEnv*, jclass, jfieldID);jfloat(*GetStaticFloatField)(JNIEnv*, jclass, jfieldID) __NDK_FPABI__;jdouble(*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID) __NDK_FPABI__;void(*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);void(*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);void(*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);void(*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);void(*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);void(*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);void(*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);void(*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat) __NDK_FPABI__;void(*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble) __NDK_FPABI__;jstring(*NewString)(JNIEnv*, const jchar*, jsize);jsize(*GetStringLength)(JNIEnv*, jstring);const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);void(*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);jstring(*NewStringUTF)(JNIEnv*, const char*);jsize(*GetStringUTFLength)(JNIEnv*, jstring);/* JNI spec says this returns const jbyte*, but that’s inconsistent */const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);void(*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);jsize(*GetArrayLength)(JNIEnv*, jarray);jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);jobject(*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);void(*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);jbyteArray (*NewByteArray)(JNIEnv*, jsize);jcharArray (*NewCharArray)(JNIEnv*, jsize);jshortArray (*NewShortArray)(JNIEnv*, jsize);jintArray(*NewIntArray)(JNIEnv*, jsize);jlongArray (*NewLongArray)(JNIEnv*, jsize);jfloatArray (*NewFloatArray)(JNIEnv*, jsize);jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize);jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);jbyte*(*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);jchar*(*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);jshort*(*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);jint*(*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);jlong*(*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);jfloat*(*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);void(*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,jboolean*, jint);void(*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,jbyte*, jint);void(*ReleaseCharArrayElements)(JNIEnv*, jcharArray,jchar*, jint);void(*ReleaseShortArrayElements)(JNIEnv*, jshortArray,jshort*, jint);void(*ReleaseIntArrayElements)(JNIEnv*, jintArray,jint*, jint);void(*ReleaseLongArrayElements)(JNIEnv*, jlongArray,jlong*, jint);void(*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,jfloat*, jint);void(*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,jdouble*, jint);void(*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray,jsize, jsize, jboolean*);void(*GetByteArrayRegion)(JNIEnv*, jbyteArray,jsize, jsize, jbyte*);void(*GetCharArrayRegion)(JNIEnv*, jcharArray,jsize, jsize, jchar*);void(*GetShortArrayRegion)(JNIEnv*, jshortArray,jsize, jsize, jshort*);void(*GetIntArrayRegion)(JNIEnv*, jintArray,jsize, jsize, jint*);void(*GetLongArrayRegion)(JNIEnv*, jlongArray,jsize, jsize, jlong*);void(*GetFloatArrayRegion)(JNIEnv*, jfloatArray,jsize, jsize, jfloat*);void(*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray,jsize, jsize, jdouble*);/* spec shows these without const; some jni.h do, some don’t */void(*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,jsize, jsize, const jboolean*);void(*SetByteArrayRegion)(JNIEnv*, jbyteArray,jsize, jsize, const jbyte*);void(*SetCharArrayRegion)(JNIEnv*, jcharArray,jsize, jsize, const jchar*);void(*SetShortArrayRegion)(JNIEnv*, jshortArray,jsize, jsize, const jshort*);void(*SetIntArrayRegion)(JNIEnv*, jintArray,jsize, jsize, const jint*);void(*SetLongArrayRegion)(JNIEnv*, jlongArray,jsize, jsize, const jlong*);void(*SetFloatArrayRegion)(JNIEnv*, jfloatArray,jsize, jsize, const jfloat*);void(*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray,jsize, jsize, const jdouble*);jint(*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,jint);jint(*UnregisterNatives)(JNIEnv*, jclass);jint(*MonitorEnter)(JNIEnv*, jobject);jint(*MonitorExit)(JNIEnv*, jobject);jint(*GetJavaVM)(JNIEnv*, JavaVM**);void(*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);void(*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*);void*(*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);void(*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint);const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);void(*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*);jweak(*NewWeakGlobalRef)(JNIEnv*, jobject);void(*DeleteWeakGlobalRef)(JNIEnv*, jweak);jboolean (*ExceptionCheck)(JNIEnv*);jobject(*NewDirectByteBuffer)(JNIEnv*, void*, jlong);void*(*GetDirectBufferAddress)(JNIEnv*, jobject);jlong(*GetDirectBufferCapacity)(JNIEnv*, jobject);/* added in JNI 1.6 */jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);JNI层访问和修改JAVA实例变量与静态变量没有什么可留恋,只有抑制不住的梦想,没有什么可凭仗,

Android NDK开发之JNI基础知识

相关文章:

你感兴趣的文章:

标签云: