JNI注册调用完整过程-安卓4.4

时间:2022-03-05 19:42:43
在Android系统中,JNI方法是以C/C++语言来实现的,然后编译在一个so文件里面,以我之前的例子为例Android Studio使用JNI,调用之前要加载到当前应用程序的进程的地址空间中:
static{
System.loadLibrary("JniTest");
}
private native int Add(double num1,double num2);
private native int Sub(double num1,double num2);
private native int Mul(double num1,double num2);
private native int Div(double num1,double num2);
上述方法假设类com.example.caculate有4个方法Add,Sub,Mul,Div是现在libJniTest.so文件中,因此JNI方法被调用之前我们首先要将它加载到当前的应用程序进程中来,通过调用System类的静态成员函数loadLibrary来实现的。
JNI方法的注册我们查看动态注册的代码:
#include <jni.h>
#include <stdio.h>
//#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> JNIEXPORT jint JNICALL native_Add
(JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
return (jint)(num1 + num2 +);
} JNIEXPORT jint JNICALL native_Sub
(JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
return (jint)(num1 - num2 +);
} JNIEXPORT jint JNICALL native_Mul
(JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
return (jint)(num1 * num2 +);
} JNIEXPORT jint JNICALL native_Div
(JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
if (num2 == ) return ;
return (jint)(num1 / num2 +);
} //Java和JNI函数的绑定表
static JNINativeMethod gMethods[] = {
{"Add", "(DD)I", (void *)native_Add},
{"Sub", "(DD)I", (void *)native_Sub},
{"Mul", "(DD)I", (void *)native_Mul},
{"Div", "(DD)I", (void *)native_Div},
}; //注册native方法到java中
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, clazz, gMethods,numMethods) < ){
return JNI_FALSE;
} return JNI_TRUE;
} int register_ndk_load(JNIEnv *env)
{ return registerNativeMethods(env, "com/example/caculate/MainActivity",
gMethods,sizeof(gMethods) / sizeof(gMethods[]));
//NELEM(gMethods));
} JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -; if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) { //获得env
return result;
} register_ndk_load(env); // 返回jni的版本
return JNI_VERSION_1_4;
}
经过上述的编码,编译就能生成libJniTest.so文件。
当libJniTest.so文件被加载的时候,函数JNI_OnLoad就会被调用。在函数JNI_Onload中,参数vm是当前进程中的Dalvik虚拟机,通过调用它的成员函数GetEnv就可以获得一个JNIEnv对象。其中JNIEnv是Dalvik虚拟机实例中的一个JNI环境列表,JNIEnv中有个成员变量指向本地接口表JNINativeInterface,当我们在C/C++代码中调用Java函数,就需要用到这个本地接口表,例如调用FindClass找到指定的Java类;调用GetMethodId可以获得一个Java类成员函数,并且可以通过类似CallObjectMethod函数来设置它的值;调用函数RegisterNatives和UnregisterNatives可以注册和反注册JNI方法到一个Java类中,便可以在Java函数中调用;调用GetJavaVM可以获得当前进程中的Dalvik虚拟机实例。每一个关联有JNI环境的线程都有一个对应的JNIEnv对象,JNIEnv是一个双向链表结构,其中第一个是主线程的JNIEnv对象。
之后我们便通过调用JNIEnv对象中接口函数FindClass函数获得当前JNIEnv对象关联的类名
clazz = (*env)->FindClass(env, className);
然后通过JNIEnv对象中接口函数RegisterNatives注册我们的4个方法。
(*env)->RegisterNatives(env, clazz, gMethods,numMethods)
以下分析在Android 4.4源码中
一、我们重点分析JNI的注册过程:
1.我们通过System.loadLibrary()函数加载我们的动态库。我们查看loadLibrary函数。
得到调用过程为
JNI注册调用完整过程-安卓4.4
System.loadlibrary() //在System.java中,Java检查是否能被加载,调用Runtime.loadLibrary
|_Runtime.loadLibrary() //在Runtime.java中,检查路径,获得so绝对路径,路径合法,调用Runtime.nativeLoad
|_Runtime.nativeLoad() //JNI方法,Dalvik虚拟机在启动过程中注册的Java核心类操作
           ||                     //在java_lang_Runtime.c中
Dalvik_java_lang_Runtime_nativeLoad()//将java层的String对象转换成C++层字符串,再调用 dvmLoadNativeCode来执行so文件的加载操作
|_dvmLoadNativeCode()
dvmLoadNativeCode()函数检查so文件是否已经加载过了,就直接返回so文件的加载信息,如果没有加载,调用dlopen加载到进程中,创建SharedLib对象pNewEntry来描述加载信息,调用dlsym获得JNI_OnLoad函数在so文件中的函数指针,然后调用这个函数指针,传入JavaVM对象,这个JAVAVM对象描述了当前进程中运行的Dalvik虚拟机。
这样在调用System.loadLibrary()函数,so文件中的JNI_Onload函数就执行了,并且第一个参数描述了当前进程的Dalvik虚拟机对象。
2.JNI_Onload函数注册JNI函数。
JNI注册调用完整过程-安卓4.4
(*vm)->GetEnv() //获得Dalvik虚拟机关联的JNIEnv对象(当前线程的JNI环境)
(*env)->FindClass() //JNIEnv结构体中的本地接口表中函数
(*env)->RegisterNatives() //JNIEnv结构体中的本地接口表中函数
                 ||
       RegisterNatives()
       |_dvmDecodeIndirectRef() //获得要注册JNI方法的类的对象引用clazz
       |_dvmRegisterJNIMethod() //通过循环调用此函数,注册methods描述的每一个JNI方法
                 |_dvmFindDirectMethodByDescriptor //检查method方法是否是clazz的的非虚成员函数
                 |_dvmFindVirtualMethodByDescriptor //检查method方法是否是clazz的虚成员函数
                 |_dvmInNativeMethod  //确保clazz的成员函数method声明为JNI方法
                 |_dvmIsSynchronizedMethod //是否是同步的
                 |_dvmIsStaticMethod //是否是静态方法
                 |_dvmResolveNativeMethod //检查Dalvik虚拟机内部以及当前所有加载的共享库中是否存在对应的JNI方法
                 |_dvmUseJNIBridge
                        |_Bridge=dvmCheckCallJNIMethod  /  dvmCallJNIMethod //根据虚拟机设置,设置Bridge函数
                        |_dvmSetNativeFunc 将bridge函数地址和JNI函数地址放入需要注册的JNI的method中
                              |_method->insns = insns;                                    //JNI方法的函数地址
                              |_android_atomic_release_store((int32_t) func,
                                                 (volatile int32_t*)(void*) &method->nativeFunc);  //将dvmCallMethodV函数放入method->nativeFunc中,后面直接通过该函数调用JNI方法的函数地址
   参数method表示要注册JNI方法的Java类成员函数,参数func表示JNI方法的Bridge函数(dvmCallJNIMethod或者dvmCheckCallJNIMethod),参数insns表示要注册的JNI方法的函数地址。
       当参数insns的值不等于NULL的时候,函数dvmSetNativeFunc就分别将参数insns和func的值分别保存在参数method所指向的一个Method对象的成员变量insns和nativeFunc中,而当insns的值等于NULL的时候,函数dvmSetNativeFunc就只将参数func的值保存在参数method所指向的一个Method对象成员变量nativeFunc中。
到此注册过程已经完成。
二、我们再看看函数的调用过程:
JNI注册调用完整过程-安卓4.4
我们通过CallVoidMethodV系列函数调用其他方法,这些函数是JNIEnv结构体中本地接口表中的函数。
CallVoidMethodV
|_dvmCallMethodV  (stack.c中)
        |_dvmIsNativeMethod() 是JNI方法
        |             |_(*method->nativeFunc)((u4*)self->interpSave.curFrame, pResult,method, self); //使用之前注册是的bridge函数:dvmCallJNIMethod函数
        |_dvmInterpret (Interp.c中) 是Java方法
      |_dvmMterpStd JIT和fast模式
      |_dvmInterpretPortable Portable可移植模式 (在InterpC-portstd.c中)
          |_1.初始化当前要解释的类(methodClassDex)及其成员变量函数(curMethod)、栈帧(fp)、程序计数器(pc)和返回值(retval),这些值都可以从参数interpState获得。
          |_2.再一个无限while循环中,通过FETCH宏依次获得当前程序计数器(pc)的指令,并通过宏INST_INST获得指令inst的类型,最后就switch到对应的分支去解释指令inst。
其中dvmCheckCallJNIMethod检查JNI之后调用dvmCallJNIMethod函数(jni.c中)
调用之前注册JNI时指定的dvmCallJNIMethod函数,通过这个函数执行JNI方法
dvmCallJNIMethod
|_addLocalReference(thread,method->clazz) 增加线程对java类对象的引用
|_dvmChangeStatus(thread,THREAD_NATIVE) 更改线程状态为native模式
|_dvmPlatformInvoke() //函数通过libffi库来调用对应的JNI方法,来屏蔽Dalvik虚拟机运行在不同目标平台的细节
|_dvmChangeStatus() 恢复线程状态
JNI环境对象结构体:
struct JNIEnvExt {          //JNI环境对象
const struct JNINativeInterface* funcTable; /* must be first */
const struct JNINativeInterface* baseFuncTable;
u4 envThreadId;
Thread* self;
/* if nonzero, we are in a "critical" JNI call */
int critical;
struct JNIEnvExt* prev;
struct JNIEnvExt* next;
};

JNINativeInterface: JNIEnv的回调函数表

 struct JNINativeInterface {
void* reserved0;
void* reserved1;
void* reserved2;
void* reserved3; 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, ...);
jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
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, ...);
jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
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);
jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID); 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);
void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble); 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, ...);
jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);
jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
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);
jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID); 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);
void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble); 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);
}; /*
* C++ object wrapper.
*
* This is usually overlaid on a C struct whose first element is a
* JNINativeInterface*. We rely somewhat on compiler behavior.
*/
struct _JNIEnv {
/* do not rename this; it does not seem to be entirely opaque */
const struct JNINativeInterface* functions; #if defined(__cplusplus) jint GetVersion()
{ return functions->GetVersion(this); } jclass DefineClass(const char *name, jobject loader, const jbyte* buf,
jsize bufLen)
{ return functions->DefineClass(this, name, loader, buf, bufLen); } jclass FindClass(const char* name)
{ return functions->FindClass(this, name); } jmethodID FromReflectedMethod(jobject method)
{ return functions->FromReflectedMethod(this, method); } jfieldID FromReflectedField(jobject field)
{ return functions->FromReflectedField(this, field); } jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic)
{ return functions->ToReflectedMethod(this, cls, methodID, isStatic); } jclass GetSuperclass(jclass clazz)
{ return functions->GetSuperclass(this, clazz); } jboolean IsAssignableFrom(jclass clazz1, jclass clazz2)
{ return functions->IsAssignableFrom(this, clazz1, clazz2); } jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic)
{ return functions->ToReflectedField(this, cls, fieldID, isStatic); } jint Throw(jthrowable obj)
{ return functions->Throw(this, obj); } jint ThrowNew(jclass clazz, const char* message)
{ return functions->ThrowNew(this, clazz, message); } jthrowable ExceptionOccurred()
{ return functions->ExceptionOccurred(this); } void ExceptionDescribe()
{ functions->ExceptionDescribe(this); } void ExceptionClear()
{ functions->ExceptionClear(this); } void FatalError(const char* msg)
{ functions->FatalError(this, msg); } jint PushLocalFrame(jint capacity)
{ return functions->PushLocalFrame(this, capacity); } jobject PopLocalFrame(jobject result)
{ return functions->PopLocalFrame(this, result); } jobject NewGlobalRef(jobject obj)
{ return functions->NewGlobalRef(this, obj); } void DeleteGlobalRef(jobject globalRef)
{ functions->DeleteGlobalRef(this, globalRef); } void DeleteLocalRef(jobject localRef)
{ functions->DeleteLocalRef(this, localRef); } jboolean IsSameObject(jobject ref1, jobject ref2)
{ return functions->IsSameObject(this, ref1, ref2); } jobject NewLocalRef(jobject ref)
{ return functions->NewLocalRef(this, ref); } jint EnsureLocalCapacity(jint capacity)
{ return functions->EnsureLocalCapacity(this, capacity); } jobject AllocObject(jclass clazz)
{ return functions->AllocObject(this, clazz); } jobject NewObject(jclass clazz, jmethodID methodID, ...)
{
va_list args;
va_start(args, methodID);
jobject result = functions->NewObjectV(this, clazz, methodID, args);
va_end(args);
return result;
} jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args)
{ return functions->NewObjectV(this, clazz, methodID, args); } jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args)
{ return functions->NewObjectA(this, clazz, methodID, args); } jclass GetObjectClass(jobject obj)
{ return functions->GetObjectClass(this, obj); } jboolean IsInstanceOf(jobject obj, jclass clazz)
{ return functions->IsInstanceOf(this, obj, clazz); } jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
{ return functions->GetMethodID(this, clazz, name, sig); } #define CALL_TYPE_METHOD(_jtype, _jname) \
_jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) \
{ \
_jtype result; \
va_list args; \
va_start(args, methodID); \
result = functions->Call##_jname##MethodV(this, obj, methodID, \
args); \
va_end(args); \
return result; \
}
#define CALL_TYPE_METHODV(_jtype, _jname) \
_jtype Call##_jname##MethodV(jobject obj, jmethodID methodID, \
va_list args) \
{ return functions->Call##_jname##MethodV(this, obj, methodID, args); }
#define CALL_TYPE_METHODA(_jtype, _jname) \
_jtype Call##_jname##MethodA(jobject obj, jmethodID methodID, \
jvalue* args) \
{ return functions->Call##_jname##MethodA(this, obj, methodID, args); } #define CALL_TYPE(_jtype, _jname) \
CALL_TYPE_METHOD(_jtype, _jname) \
CALL_TYPE_METHODV(_jtype, _jname) \
CALL_TYPE_METHODA(_jtype, _jname) CALL_TYPE(jobject, Object)
CALL_TYPE(jboolean, Boolean)
CALL_TYPE(jbyte, Byte)
CALL_TYPE(jchar, Char)
CALL_TYPE(jshort, Short)
CALL_TYPE(jint, Int)
CALL_TYPE(jlong, Long)
CALL_TYPE(jfloat, Float)
CALL_TYPE(jdouble, Double) void CallVoidMethod(jobject obj, jmethodID methodID, ...)
{
va_list args;
va_start(args, methodID);
functions->CallVoidMethodV(this, obj, methodID, args);
va_end(args);
}
void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)
{ functions->CallVoidMethodV(this, obj, methodID, args); }
void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)
{ functions->CallVoidMethodA(this, obj, methodID, args); } #define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \
_jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz, \
jmethodID methodID, ...) \
{ \
_jtype result; \
va_list args; \
va_start(args, methodID); \
result = functions->CallNonvirtual##_jname##MethodV(this, obj, \
clazz, methodID, args); \
va_end(args); \
return result; \
}
#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \
_jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz, \
jmethodID methodID, va_list args) \
{ return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz, \
methodID, args); }
#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) \
_jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz, \
jmethodID methodID, jvalue* args) \
{ return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz, \
methodID, args); } #define CALL_NONVIRT_TYPE(_jtype, _jname) \
CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \
CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \
CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) CALL_NONVIRT_TYPE(jobject, Object)
CALL_NONVIRT_TYPE(jboolean, Boolean)
CALL_NONVIRT_TYPE(jbyte, Byte)
CALL_NONVIRT_TYPE(jchar, Char)
CALL_NONVIRT_TYPE(jshort, Short)
CALL_NONVIRT_TYPE(jint, Int)
CALL_NONVIRT_TYPE(jlong, Long)
CALL_NONVIRT_TYPE(jfloat, Float)
CALL_NONVIRT_TYPE(jdouble, Double) void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
jmethodID methodID, ...)
{
va_list args;
va_start(args, methodID);
functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args);
va_end(args);
}
void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
jmethodID methodID, va_list args)
{ functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); }
void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
jmethodID methodID, jvalue* args)
{ functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); } jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
{ return functions->GetFieldID(this, clazz, name, sig); } jobject GetObjectField(jobject obj, jfieldID fieldID)
{ return functions->GetObjectField(this, obj, fieldID); }
jboolean GetBooleanField(jobject obj, jfieldID fieldID)
{ return functions->GetBooleanField(this, obj, fieldID); }
jbyte GetByteField(jobject obj, jfieldID fieldID)
{ return functions->GetByteField(this, obj, fieldID); }
jchar GetCharField(jobject obj, jfieldID fieldID)
{ return functions->GetCharField(this, obj, fieldID); }
jshort GetShortField(jobject obj, jfieldID fieldID)
{ return functions->GetShortField(this, obj, fieldID); }
jint GetIntField(jobject obj, jfieldID fieldID)
{ return functions->GetIntField(this, obj, fieldID); }
jlong GetLongField(jobject obj, jfieldID fieldID)
{ return functions->GetLongField(this, obj, fieldID); }
jfloat GetFloatField(jobject obj, jfieldID fieldID)
{ return functions->GetFloatField(this, obj, fieldID); }
jdouble GetDoubleField(jobject obj, jfieldID fieldID)
{ return functions->GetDoubleField(this, obj, fieldID); } void SetObjectField(jobject obj, jfieldID fieldID, jobject value)
{ functions->SetObjectField(this, obj, fieldID, value); }
void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
{ functions->SetBooleanField(this, obj, fieldID, value); }
void SetByteField(jobject obj, jfieldID fieldID, jbyte value)
{ functions->SetByteField(this, obj, fieldID, value); }
void SetCharField(jobject obj, jfieldID fieldID, jchar value)
{ functions->SetCharField(this, obj, fieldID, value); }
void SetShortField(jobject obj, jfieldID fieldID, jshort value)
{ functions->SetShortField(this, obj, fieldID, value); }
void SetIntField(jobject obj, jfieldID fieldID, jint value)
{ functions->SetIntField(this, obj, fieldID, value); }
void SetLongField(jobject obj, jfieldID fieldID, jlong value)
{ functions->SetLongField(this, obj, fieldID, value); }
void SetFloatField(jobject obj, jfieldID fieldID, jfloat value)
{ functions->SetFloatField(this, obj, fieldID, value); }
void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value)
{ functions->SetDoubleField(this, obj, fieldID, value); } jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)
{ return functions->GetStaticMethodID(this, clazz, name, sig); } #define CALL_STATIC_TYPE_METHOD(_jtype, _jname) \
_jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID, \
...) \
{ \
_jtype result; \
va_list args; \
va_start(args, methodID); \
result = functions->CallStatic##_jname##MethodV(this, clazz, \
methodID, args); \
va_end(args); \
return result; \
}
#define CALL_STATIC_TYPE_METHODV(_jtype, _jname) \
_jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID, \
va_list args) \
{ return functions->CallStatic##_jname##MethodV(this, clazz, methodID, \
args); }
#define CALL_STATIC_TYPE_METHODA(_jtype, _jname) \
_jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID, \
jvalue* args) \
{ return functions->CallStatic##_jname##MethodA(this, clazz, methodID, \
args); } #define CALL_STATIC_TYPE(_jtype, _jname) \
CALL_STATIC_TYPE_METHOD(_jtype, _jname) \
CALL_STATIC_TYPE_METHODV(_jtype, _jname) \
CALL_STATIC_TYPE_METHODA(_jtype, _jname) CALL_STATIC_TYPE(jobject, Object)
CALL_STATIC_TYPE(jboolean, Boolean)
CALL_STATIC_TYPE(jbyte, Byte)
CALL_STATIC_TYPE(jchar, Char)
CALL_STATIC_TYPE(jshort, Short)
CALL_STATIC_TYPE(jint, Int)
CALL_STATIC_TYPE(jlong, Long)
CALL_STATIC_TYPE(jfloat, Float)
CALL_STATIC_TYPE(jdouble, Double) void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)
{
va_list args;
va_start(args, methodID);
functions->CallStaticVoidMethodV(this, clazz, methodID, args);
va_end(args);
}
void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args)
{ functions->CallStaticVoidMethodV(this, clazz, methodID, args); }
void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args)
{ functions->CallStaticVoidMethodA(this, clazz, methodID, args); } jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
{ return functions->GetStaticFieldID(this, clazz, name, sig); } jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticObjectField(this, clazz, fieldID); }
jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticBooleanField(this, clazz, fieldID); }
jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticByteField(this, clazz, fieldID); }
jchar GetStaticCharField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticCharField(this, clazz, fieldID); }
jshort GetStaticShortField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticShortField(this, clazz, fieldID); }
jint GetStaticIntField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticIntField(this, clazz, fieldID); }
jlong GetStaticLongField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticLongField(this, clazz, fieldID); }
jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticFloatField(this, clazz, fieldID); }
jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)
{ return functions->GetStaticDoubleField(this, clazz, fieldID); } void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value)
{ functions->SetStaticObjectField(this, clazz, fieldID, value); }
void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value)
{ functions->SetStaticBooleanField(this, clazz, fieldID, value); }
void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value)
{ functions->SetStaticByteField(this, clazz, fieldID, value); }
void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value)
{ functions->SetStaticCharField(this, clazz, fieldID, value); }
void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value)
{ functions->SetStaticShortField(this, clazz, fieldID, value); }
void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value)
{ functions->SetStaticIntField(this, clazz, fieldID, value); }
void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value)
{ functions->SetStaticLongField(this, clazz, fieldID, value); }
void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value)
{ functions->SetStaticFloatField(this, clazz, fieldID, value); }
void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value)
{ functions->SetStaticDoubleField(this, clazz, fieldID, value); } jstring NewString(const jchar* unicodeChars, jsize len)
{ return functions->NewString(this, unicodeChars, len); } jsize GetStringLength(jstring string)
{ return functions->GetStringLength(this, string); } const jchar* GetStringChars(jstring string, jboolean* isCopy)
{ return functions->GetStringChars(this, string, isCopy); } void ReleaseStringChars(jstring string, const jchar* chars)
{ functions->ReleaseStringChars(this, string, chars); } jstring NewStringUTF(const char* bytes)
{ return functions->NewStringUTF(this, bytes); } jsize GetStringUTFLength(jstring string)
{ return functions->GetStringUTFLength(this, string); } const char* GetStringUTFChars(jstring string, jboolean* isCopy)
{ return functions->GetStringUTFChars(this, string, isCopy); } void ReleaseStringUTFChars(jstring string, const char* utf)
{ functions->ReleaseStringUTFChars(this, string, utf); } jsize GetArrayLength(jarray array)
{ return functions->GetArrayLength(this, array); } jobjectArray NewObjectArray(jsize length, jclass elementClass,
jobject initialElement)
{ return functions->NewObjectArray(this, length, elementClass,
initialElement); } jobject GetObjectArrayElement(jobjectArray array, jsize index)
{ return functions->GetObjectArrayElement(this, array, index); } void SetObjectArrayElement(jobjectArray array, jsize index, jobject value)
{ functions->SetObjectArrayElement(this, array, index, value); } jbooleanArray NewBooleanArray(jsize length)
{ return functions->NewBooleanArray(this, length); }
jbyteArray NewByteArray(jsize length)
{ return functions->NewByteArray(this, length); }
jcharArray NewCharArray(jsize length)
{ return functions->NewCharArray(this, length); }
jshortArray NewShortArray(jsize length)
{ return functions->NewShortArray(this, length); }
jintArray NewIntArray(jsize length)
{ return functions->NewIntArray(this, length); }
jlongArray NewLongArray(jsize length)
{ return functions->NewLongArray(this, length); }
jfloatArray NewFloatArray(jsize length)
{ return functions->NewFloatArray(this, length); }
jdoubleArray NewDoubleArray(jsize length)
{ return functions->NewDoubleArray(this, length); } jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy)
{ return functions->GetBooleanArrayElements(this, array, isCopy); }
jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy)
{ return functions->GetByteArrayElements(this, array, isCopy); }
jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy)
{ return functions->GetCharArrayElements(this, array, isCopy); }
jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy)
{ return functions->GetShortArrayElements(this, array, isCopy); }
jint* GetIntArrayElements(jintArray array, jboolean* isCopy)
{ return functions->GetIntArrayElements(this, array, isCopy); }
jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy)
{ return functions->GetLongArrayElements(this, array, isCopy); }
jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy)
{ return functions->GetFloatArrayElements(this, array, isCopy); }
jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy)
{ return functions->GetDoubleArrayElements(this, array, isCopy); } void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems,
jint mode)
{ functions->ReleaseBooleanArrayElements(this, array, elems, mode); }
void ReleaseByteArrayElements(jbyteArray array, jbyte* elems,
jint mode)
{ functions->ReleaseByteArrayElements(this, array, elems, mode); }
void ReleaseCharArrayElements(jcharArray array, jchar* elems,
jint mode)
{ functions->ReleaseCharArrayElements(this, array, elems, mode); }
void ReleaseShortArrayElements(jshortArray array, jshort* elems,
jint mode)
{ functions->ReleaseShortArrayElements(this, array, elems, mode); }
void ReleaseIntArrayElements(jintArray array, jint* elems,
jint mode)
{ functions->ReleaseIntArrayElements(this, array, elems, mode); }
void ReleaseLongArrayElements(jlongArray array, jlong* elems,
jint mode)
{ functions->ReleaseLongArrayElements(this, array, elems, mode); }
void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems,
jint mode)
{ functions->ReleaseFloatArrayElements(this, array, elems, mode); }
void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems,
jint mode)
{ functions->ReleaseDoubleArrayElements(this, array, elems, mode); } void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
jboolean* buf)
{ functions->GetBooleanArrayRegion(this, array, start, len, buf); }
void GetByteArrayRegion(jbyteArray array, jsize start, jsize len,
jbyte* buf)
{ functions->GetByteArrayRegion(this, array, start, len, buf); }
void GetCharArrayRegion(jcharArray array, jsize start, jsize len,
jchar* buf)
{ functions->GetCharArrayRegion(this, array, start, len, buf); }
void GetShortArrayRegion(jshortArray array, jsize start, jsize len,
jshort* buf)
{ functions->GetShortArrayRegion(this, array, start, len, buf); }
void GetIntArrayRegion(jintArray array, jsize start, jsize len,
jint* buf)
{ functions->GetIntArrayRegion(this, array, start, len, buf); }
void GetLongArrayRegion(jlongArray array, jsize start, jsize len,
jlong* buf)
{ functions->GetLongArrayRegion(this, array, start, len, buf); }
void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
jfloat* buf)
{ functions->GetFloatArrayRegion(this, array, start, len, buf); }
void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
jdouble* buf)
{ functions->GetDoubleArrayRegion(this, array, start, len, buf); } void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
const jboolean* buf)
{ functions->SetBooleanArrayRegion(this, array, start, len, buf); }
void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
const jbyte* buf)
{ functions->SetByteArrayRegion(this, array, start, len, buf); }
void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
const jchar* buf)
{ functions->SetCharArrayRegion(this, array, start, len, buf); }
void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
const jshort* buf)
{ functions->SetShortArrayRegion(this, array, start, len, buf); }
void SetIntArrayRegion(jintArray array, jsize start, jsize len,
const jint* buf)
{ functions->SetIntArrayRegion(this, array, start, len, buf); }
void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
const jlong* buf)
{ functions->SetLongArrayRegion(this, array, start, len, buf); }
void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
const jfloat* buf)
{ functions->SetFloatArrayRegion(this, array, start, len, buf); }
void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
const jdouble* buf)
{ functions->SetDoubleArrayRegion(this, array, start, len, buf); } jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,
jint nMethods)
{ return functions->RegisterNatives(this, clazz, methods, nMethods); } jint UnregisterNatives(jclass clazz)
{ return functions->UnregisterNatives(this, clazz); } jint MonitorEnter(jobject obj)
{ return functions->MonitorEnter(this, obj); } jint MonitorExit(jobject obj)
{ return functions->MonitorExit(this, obj); } jint GetJavaVM(JavaVM** vm)
{ return functions->GetJavaVM(this, vm); } void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf)
{ functions->GetStringRegion(this, str, start, len, buf); } void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf)
{ return functions->GetStringUTFRegion(this, str, start, len, buf); } void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)
{ return functions->GetPrimitiveArrayCritical(this, array, isCopy); } void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode)
{ functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); } const jchar* GetStringCritical(jstring string, jboolean* isCopy)
{ return functions->GetStringCritical(this, string, isCopy); } void ReleaseStringCritical(jstring string, const jchar* carray)
{ functions->ReleaseStringCritical(this, string, carray); } jweak NewWeakGlobalRef(jobject obj)
{ return functions->NewWeakGlobalRef(this, obj); } void DeleteWeakGlobalRef(jweak obj)
{ functions->DeleteWeakGlobalRef(this, obj); } jboolean ExceptionCheck()
{ return functions->ExceptionCheck(this); } jobject NewDirectByteBuffer(void* address, jlong capacity)
{ return functions->NewDirectByteBuffer(this, address, capacity); } void* GetDirectBufferAddress(jobject buf)
{ return functions->GetDirectBufferAddress(this, buf); } jlong GetDirectBufferCapacity(jobject buf)
{ return functions->GetDirectBufferCapacity(this, buf); } /* added in JNI 1.6 */
jobjectRefType GetObjectRefType(jobject obj)
{ return functions->GetObjectRefType(this, obj); }
#endif /*__cplusplus*/
};

总结一下:

系统注册或者自己注册的JNI,通过JNIEnv对象中的本地接口表函数RegisterNative注册JNI方法,使用其中的CallVoidMethod系列函数调用JNI方法。

此文为学习JNI注册、调用过程,有错误的地方请大家指出谢谢!