下面是一个测试方法
public native void test(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 JNICALL Java_com_kltz88_car_jnidemo_Test_test(JNIEnv *env, jobject instance, jbyte by, jchar c, jshort s, jint i, jlong l, jfloat f, jdouble d, jboolean b, jstring str_, jobject o, jobject t, jintArray arr);
我们会发现基本数据类型直接会有一种对应关系
其实只是使用了typedef重新定义了一下
typedef unsigned char jboolean; /* unsigned 8 bits */ typedef signed char jbyte; /* signed 8 bits */ typedef unsigned short jchar; /* unsigned 16 bits */ typedef short jshort; /* signed 16 bits */ typedef int jint; /* signed 32 bits */ typedef long long jlong; /* signed 64 bits */ typedef float jfloat; /* 32-bit IEEE 754 */ typedef double jdouble; /* 64-bit IEEE 754 */
进一步还会发现,引用类型也存在一定的对应关系
也是通过typedef重新定义了一下,都是一个指针
typedef void* jobject; typedef jobject jclass; typedef jobject jstring; typedef jobject jarray; typedef jarray jobjectArray; typedef jarray jbooleanArray; typedef jarray jbyteArray; typedef jarray jcharArray; typedef jarray jshortArray; typedef jarray jintArray; typedef jarray jlongArray; typedef jarray jfloatArray; typedef jarray jdoubleArray; typedef jobject jthrowable; typedef jobject jweak;
方法签名
字段描述
值得注意的是
- 类是使用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实例变量与静态变量
由于JNI函数是直接操作JVM中的数据结构,不受Java访问修饰符的限制。即,在本地代码中可以调用JNI函数可以访问Java对象中的非public属性和方法
访问和修改实例变量操作步聚
- 调用GetObjectClass函数获取实例对象的Class引用
- 调用GetFieldID函数获取Class引用中某个实例变量的ID
- 调用GetXXXField(如GetObjectField)函数获取变量的值,需要传入实例变量所属对象和变量ID
- 调用SetXXXField(如SetObjectField)函数修改变量的值,需要传入实例变量所属对象、变量ID和变量的值
访问和修改静态变量操作步聚
- 调用FindClass函数获取类的Class引用
- 调用GetStaticFieldID函数获取Class引用中某个静态变量ID
- 调用GetStaticXXXField(如GetStaticIntField)函数获取静态变量的值,需要传入变量所属Class的引用和变量ID
- 调用SetStaticXXXField(SetStaticIntField)函数设置静态变量的值,需要传入变量所属Class的引用、变量ID和变量的值
JNI层访问和修改JAVA实例方法与静态方法
调用静态方法使用CallStaticXXXMethod/V/A函数,XXX代表返回值的数据类型。如:CallStaticIntMethod
void (JNICALL *CallStaticVoidMethod) (JNIEnv *env, jclass cls, jmethodID methodID, ...); void (JNICALL *CallStaticVoidMethodV) (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); void (JNICALL *CallStaticVoidMethodA) (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args);
调用实例方法使用CallXXXMethod/V/A函数,XXX代表返回的数据类型,如:CallIntMethod
void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list); void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
获取一个实例方法的ID,使用GetMethodID函数,传入方法名称和方法签名
jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
获以一个静态方法的ID,使用GetStaticMethodID函数,传入方法名称和方法签名
jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
获取构造方法ID,方法名称使用”<init>”,比如获取默认构造方法
(*env)->GetMethodID(env,clazz, "<init>","()V");
获取一个类的Class实例,使用FindClass函数,传入类描述符。JVM会从classpath目录下开始搜索。
jclass (*FindClass)(JNIEnv*, const char*);
创建一个类的实例,使用NewObject函数,传入Class引用和构造方法ID
jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...); jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);
删除局部变量引用,使用DeleteLocalRef,传入引用变量
void DeleteLocalRef(jobject localRef) { functions->DeleteLocalRef(this, localRef); }
方法签名格式:(形参参数列表)返回值类型。注意:形参参数列表之间不需要用空格或其它字符分隔
类描述符格式:L包名路径/类名;,包名之间用/分隔。如:Ljava/lang/String;
调用GetMethodID获取方法ID和调用FindClass获取Class实例后,要做异常判断,判断返回值是否为NULL