首页 > 技术文章 > JNI注册调用完整过程-安卓4.4

ciyze0101 2016-08-23 17:04 原文

在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 +1);
}


JNIEXPORT jint JNICALL native_Sub
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    return (jint)(num1 - num2 +1);
}


JNIEXPORT jint JNICALL native_Mul
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    return (jint)(num1 * num2 +1);
}

JNIEXPORT jint JNICALL native_Div
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    if (num2 == 0) return 0;
    return (jint)(num1 / num2 +1);
}

//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) < 0){ return JNI_FALSE; } return JNI_TRUE; } int register_ndk_load(JNIEnv *env) { return registerNativeMethods(env, "com/example/caculate/MainActivity", gMethods,sizeof(gMethods) / sizeof(gMethods[0])); //NELEM(gMethods)); } JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; 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函数来设置它的值;调用函数RegisterNativesUnregisterNatives可以注册和反注册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函数。
得到调用过程为
 
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函数。

 

(*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中。
到此注册过程已经完成。
 
二、我们再看看函数的调用过程:

 

我们通过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的回调函数表

  1 struct JNINativeInterface {
  2     void*       reserved0;
  3     void*       reserved1;
  4     void*       reserved2;
  5     void*       reserved3;
  6 
  7     jint        (*GetVersion)(JNIEnv *);
  8 
  9     jclass      (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,
 10                         jsize);
 11     jclass      (*FindClass)(JNIEnv*, const char*);
 12 
 13     jmethodID   (*FromReflectedMethod)(JNIEnv*, jobject);
 14     jfieldID    (*FromReflectedField)(JNIEnv*, jobject);
 15     /* spec doesn't show jboolean parameter */
 16     jobject     (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);
 17 
 18     jclass      (*GetSuperclass)(JNIEnv*, jclass);
 19     jboolean    (*IsAssignableFrom)(JNIEnv*, jclass, jclass);
 20 
 21     /* spec doesn't show jboolean parameter */
 22     jobject     (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);
 23 
 24     jint        (*Throw)(JNIEnv*, jthrowable);
 25     jint        (*ThrowNew)(JNIEnv *, jclass, const char *);
 26     jthrowable  (*ExceptionOccurred)(JNIEnv*);
 27     void        (*ExceptionDescribe)(JNIEnv*);
 28     void        (*ExceptionClear)(JNIEnv*);
 29     void        (*FatalError)(JNIEnv*, const char*);
 30 
 31     jint        (*PushLocalFrame)(JNIEnv*, jint);
 32     jobject     (*PopLocalFrame)(JNIEnv*, jobject);
 33 
 34     jobject     (*NewGlobalRef)(JNIEnv*, jobject);
 35     void        (*DeleteGlobalRef)(JNIEnv*, jobject);
 36     void        (*DeleteLocalRef)(JNIEnv*, jobject);
 37     jboolean    (*IsSameObject)(JNIEnv*, jobject, jobject);
 38 
 39     jobject     (*NewLocalRef)(JNIEnv*, jobject);
 40     jint        (*EnsureLocalCapacity)(JNIEnv*, jint);
 41 
 42     jobject     (*AllocObject)(JNIEnv*, jclass);
 43     jobject     (*NewObject)(JNIEnv*, jclass, jmethodID, ...);
 44     jobject     (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);
 45     jobject     (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);
 46 
 47     jclass      (*GetObjectClass)(JNIEnv*, jobject);
 48     jboolean    (*IsInstanceOf)(JNIEnv*, jobject, jclass);
 49     jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
 50 
 51     jobject     (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
 52     jobject     (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 53     jobject     (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 54     jboolean    (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
 55     jboolean    (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 56     jboolean    (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 57     jbyte       (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
 58     jbyte       (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 59     jbyte       (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 60     jchar       (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
 61     jchar       (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 62     jchar       (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 63     jshort      (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
 64     jshort      (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 65     jshort      (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 66     jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
 67     jint        (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 68     jint        (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 69     jlong       (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
 70     jlong       (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 71     jlong       (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 72     jfloat      (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);
 73     jfloat      (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 74     jfloat      (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 75     jdouble     (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
 76     jdouble     (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 77     jdouble     (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 78     void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
 79     void        (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
 80     void        (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
 81 
 82     jobject     (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,
 83                         jmethodID, ...);
 84     jobject     (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,
 85                         jmethodID, va_list);
 86     jobject     (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,
 87                         jmethodID, jvalue*);
 88     jboolean    (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,
 89                         jmethodID, ...);
 90     jboolean    (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,
 91                          jmethodID, va_list);
 92     jboolean    (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,
 93                          jmethodID, jvalue*);
 94     jbyte       (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,
 95                         jmethodID, ...);
 96     jbyte       (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,
 97                         jmethodID, va_list);
 98     jbyte       (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,
 99                         jmethodID, jvalue*);
100     jchar       (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,
101                         jmethodID, ...);
102     jchar       (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,
103                         jmethodID, va_list);
104     jchar       (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,
105                         jmethodID, jvalue*);
106     jshort      (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,
107                         jmethodID, ...);
108     jshort      (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,
109                         jmethodID, va_list);
110     jshort      (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,
111                         jmethodID, jvalue*);
112     jint        (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,
113                         jmethodID, ...);
114     jint        (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,
115                         jmethodID, va_list);
116     jint        (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,
117                         jmethodID, jvalue*);
118     jlong       (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,
119                         jmethodID, ...);
120     jlong       (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,
121                         jmethodID, va_list);
122     jlong       (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,
123                         jmethodID, jvalue*);
124     jfloat      (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,
125                         jmethodID, ...);
126     jfloat      (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,
127                         jmethodID, va_list);
128     jfloat      (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,
129                         jmethodID, jvalue*);
130     jdouble     (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,
131                         jmethodID, ...);
132     jdouble     (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,
133                         jmethodID, va_list);
134     jdouble     (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,
135                         jmethodID, jvalue*);
136     void        (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,
137                         jmethodID, ...);
138     void        (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,
139                         jmethodID, va_list);
140     void        (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,
141                         jmethodID, jvalue*);
142 
143     jfieldID    (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
144 
145     jobject     (*GetObjectField)(JNIEnv*, jobject, jfieldID);
146     jboolean    (*GetBooleanField)(JNIEnv*, jobject, jfieldID);
147     jbyte       (*GetByteField)(JNIEnv*, jobject, jfieldID);
148     jchar       (*GetCharField)(JNIEnv*, jobject, jfieldID);
149     jshort      (*GetShortField)(JNIEnv*, jobject, jfieldID);
150     jint        (*GetIntField)(JNIEnv*, jobject, jfieldID);
151     jlong       (*GetLongField)(JNIEnv*, jobject, jfieldID);
152     jfloat      (*GetFloatField)(JNIEnv*, jobject, jfieldID);
153     jdouble     (*GetDoubleField)(JNIEnv*, jobject, jfieldID);
154 
155     void        (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);
156     void        (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);
157     void        (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);
158     void        (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);
159     void        (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
160     void        (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
161     void        (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);
162     void        (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);
163     void        (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);
164 
165     jmethodID   (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
166 
167     jobject     (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
168     jobject     (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);
169     jobject     (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
170     jboolean    (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);
171     jboolean    (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,
172                         va_list);
173     jboolean    (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,
174                         jvalue*);
175     jbyte       (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);
176     jbyte       (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);
177     jbyte       (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
178     jchar       (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);
179     jchar       (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);
180     jchar       (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
181     jshort      (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);
182     jshort      (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);
183     jshort      (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
184     jint        (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);
185     jint        (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);
186     jint        (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
187     jlong       (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);
188     jlong       (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);
189     jlong       (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
190     jfloat      (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);
191     jfloat      (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
192     jfloat      (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
193     jdouble     (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);
194     jdouble     (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
195     jdouble     (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
196     void        (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
197     void        (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);
198     void        (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
199 
200     jfieldID    (*GetStaticFieldID)(JNIEnv*, jclass, const char*,
201                         const char*);
202 
203     jobject     (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);
204     jboolean    (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);
205     jbyte       (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);
206     jchar       (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);
207     jshort      (*GetStaticShortField)(JNIEnv*, jclass, jfieldID);
208     jint        (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);
209     jlong       (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);
210     jfloat      (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);
211     jdouble     (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID);
212 
213     void        (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);
214     void        (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);
215     void        (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);
216     void        (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);
217     void        (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);
218     void        (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);
219     void        (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);
220     void        (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);
221     void        (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble);
222 
223     jstring     (*NewString)(JNIEnv*, const jchar*, jsize);
224     jsize       (*GetStringLength)(JNIEnv*, jstring);
225     const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
226     void        (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
227     jstring     (*NewStringUTF)(JNIEnv*, const char*);
228     jsize       (*GetStringUTFLength)(JNIEnv*, jstring);
229     /* JNI spec says this returns const jbyte*, but that's inconsistent */
230     const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
231     void        (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);
232     jsize       (*GetArrayLength)(JNIEnv*, jarray);
233     jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);
234     jobject     (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);
235     void        (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);
236 
237     jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
238     jbyteArray    (*NewByteArray)(JNIEnv*, jsize);
239     jcharArray    (*NewCharArray)(JNIEnv*, jsize);
240     jshortArray   (*NewShortArray)(JNIEnv*, jsize);
241     jintArray     (*NewIntArray)(JNIEnv*, jsize);
242     jlongArray    (*NewLongArray)(JNIEnv*, jsize);
243     jfloatArray   (*NewFloatArray)(JNIEnv*, jsize);
244     jdoubleArray  (*NewDoubleArray)(JNIEnv*, jsize);
245 
246     jboolean*   (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
247     jbyte*      (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
248     jchar*      (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
249     jshort*     (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
250     jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
251     jlong*      (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
252     jfloat*     (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
253     jdouble*    (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);
254 
255     void        (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,
256                         jboolean*, jint);
257     void        (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,
258                         jbyte*, jint);
259     void        (*ReleaseCharArrayElements)(JNIEnv*, jcharArray,
260                         jchar*, jint);
261     void        (*ReleaseShortArrayElements)(JNIEnv*, jshortArray,
262                         jshort*, jint);
263     void        (*ReleaseIntArrayElements)(JNIEnv*, jintArray,
264                         jint*, jint);
265     void        (*ReleaseLongArrayElements)(JNIEnv*, jlongArray,
266                         jlong*, jint);
267     void        (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,
268                         jfloat*, jint);
269     void        (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,
270                         jdouble*, jint);
271 
272     void        (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
273                         jsize, jsize, jboolean*);
274     void        (*GetByteArrayRegion)(JNIEnv*, jbyteArray,
275                         jsize, jsize, jbyte*);
276     void        (*GetCharArrayRegion)(JNIEnv*, jcharArray,
277                         jsize, jsize, jchar*);
278     void        (*GetShortArrayRegion)(JNIEnv*, jshortArray,
279                         jsize, jsize, jshort*);
280     void        (*GetIntArrayRegion)(JNIEnv*, jintArray,
281                         jsize, jsize, jint*);
282     void        (*GetLongArrayRegion)(JNIEnv*, jlongArray,
283                         jsize, jsize, jlong*);
284     void        (*GetFloatArrayRegion)(JNIEnv*, jfloatArray,
285                         jsize, jsize, jfloat*);
286     void        (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
287                         jsize, jsize, jdouble*);
288 
289     /* spec shows these without const; some jni.h do, some don't */
290     void        (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
291                         jsize, jsize, const jboolean*);
292     void        (*SetByteArrayRegion)(JNIEnv*, jbyteArray,
293                         jsize, jsize, const jbyte*);
294     void        (*SetCharArrayRegion)(JNIEnv*, jcharArray,
295                         jsize, jsize, const jchar*);
296     void        (*SetShortArrayRegion)(JNIEnv*, jshortArray,
297                         jsize, jsize, const jshort*);
298     void        (*SetIntArrayRegion)(JNIEnv*, jintArray,
299                         jsize, jsize, const jint*);
300     void        (*SetLongArrayRegion)(JNIEnv*, jlongArray,
301                         jsize, jsize, const jlong*);
302     void        (*SetFloatArrayRegion)(JNIEnv*, jfloatArray,
303                         jsize, jsize, const jfloat*);
304     void        (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
305                         jsize, jsize, const jdouble*);
306 
307     jint        (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,
308                         jint);
309     jint        (*UnregisterNatives)(JNIEnv*, jclass);
310     jint        (*MonitorEnter)(JNIEnv*, jobject);
311     jint        (*MonitorExit)(JNIEnv*, jobject);
312     jint        (*GetJavaVM)(JNIEnv*, JavaVM**);
313 
314     void        (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);
315     void        (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*);
316 
317     void*       (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);
318     void        (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint);
319 
320     const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);
321     void        (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*);
322 
323     jweak       (*NewWeakGlobalRef)(JNIEnv*, jobject);
324     void        (*DeleteWeakGlobalRef)(JNIEnv*, jweak);
325 
326     jboolean    (*ExceptionCheck)(JNIEnv*);
327 
328     jobject     (*NewDirectByteBuffer)(JNIEnv*, void*, jlong);
329     void*       (*GetDirectBufferAddress)(JNIEnv*, jobject);
330     jlong       (*GetDirectBufferCapacity)(JNIEnv*, jobject);
331 
332     /* added in JNI 1.6 */
333     jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
334 };
335 
336 /*
337  * C++ object wrapper.
338  *
339  * This is usually overlaid on a C struct whose first element is a
340  * JNINativeInterface*.  We rely somewhat on compiler behavior.
341  */
342 struct _JNIEnv {
343     /* do not rename this; it does not seem to be entirely opaque */
344     const struct JNINativeInterface* functions;
345 
346 #if defined(__cplusplus)
347 
348     jint GetVersion()
349     { return functions->GetVersion(this); }
350 
351     jclass DefineClass(const char *name, jobject loader, const jbyte* buf,
352         jsize bufLen)
353     { return functions->DefineClass(this, name, loader, buf, bufLen); }
354 
355     jclass FindClass(const char* name)
356     { return functions->FindClass(this, name); }
357 
358     jmethodID FromReflectedMethod(jobject method)
359     { return functions->FromReflectedMethod(this, method); }
360 
361     jfieldID FromReflectedField(jobject field)
362     { return functions->FromReflectedField(this, field); }
363 
364     jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic)
365     { return functions->ToReflectedMethod(this, cls, methodID, isStatic); }
366 
367     jclass GetSuperclass(jclass clazz)
368     { return functions->GetSuperclass(this, clazz); }
369 
370     jboolean IsAssignableFrom(jclass clazz1, jclass clazz2)
371     { return functions->IsAssignableFrom(this, clazz1, clazz2); }
372 
373     jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic)
374     { return functions->ToReflectedField(this, cls, fieldID, isStatic); }
375 
376     jint Throw(jthrowable obj)
377     { return functions->Throw(this, obj); }
378 
379     jint ThrowNew(jclass clazz, const char* message)
380     { return functions->ThrowNew(this, clazz, message); }
381 
382     jthrowable ExceptionOccurred()
383     { return functions->ExceptionOccurred(this); }
384 
385     void ExceptionDescribe()
386     { functions->ExceptionDescribe(this); }
387 
388     void ExceptionClear()
389     { functions->ExceptionClear(this); }
390 
391     void FatalError(const char* msg)
392     { functions->FatalError(this, msg); }
393 
394     jint PushLocalFrame(jint capacity)
395     { return functions->PushLocalFrame(this, capacity); }
396 
397     jobject PopLocalFrame(jobject result)
398     { return functions->PopLocalFrame(this, result); }
399 
400     jobject NewGlobalRef(jobject obj)
401     { return functions->NewGlobalRef(this, obj); }
402 
403     void DeleteGlobalRef(jobject globalRef)
404     { functions->DeleteGlobalRef(this, globalRef); }
405 
406     void DeleteLocalRef(jobject localRef)
407     { functions->DeleteLocalRef(this, localRef); }
408 
409     jboolean IsSameObject(jobject ref1, jobject ref2)
410     { return functions->IsSameObject(this, ref1, ref2); }
411 
412     jobject NewLocalRef(jobject ref)
413     { return functions->NewLocalRef(this, ref); }
414 
415     jint EnsureLocalCapacity(jint capacity)
416     { return functions->EnsureLocalCapacity(this, capacity); }
417 
418     jobject AllocObject(jclass clazz)
419     { return functions->AllocObject(this, clazz); }
420 
421     jobject NewObject(jclass clazz, jmethodID methodID, ...)
422     {
423         va_list args;
424         va_start(args, methodID);
425         jobject result = functions->NewObjectV(this, clazz, methodID, args);
426         va_end(args);
427         return result;
428     }
429 
430     jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args)
431     { return functions->NewObjectV(this, clazz, methodID, args); }
432 
433     jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args)
434     { return functions->NewObjectA(this, clazz, methodID, args); }
435 
436     jclass GetObjectClass(jobject obj)
437     { return functions->GetObjectClass(this, obj); }
438 
439     jboolean IsInstanceOf(jobject obj, jclass clazz)
440     { return functions->IsInstanceOf(this, obj, clazz); }
441 
442     jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
443     { return functions->GetMethodID(this, clazz, name, sig); }
444 
445 #define CALL_TYPE_METHOD(_jtype, _jname)                                    \
446     _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...)       \
447     {                                                                       \
448         _jtype result;                                                      \
449         va_list args;                                                       \
450         va_start(args, methodID);                                           \
451         result = functions->Call##_jname##MethodV(this, obj, methodID,      \
452                     args);                                                  \
453         va_end(args);                                                       \
454         return result;                                                      \
455     }
456 #define CALL_TYPE_METHODV(_jtype, _jname)                                   \
457     _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID,           \
458         va_list args)                                                       \
459     { return functions->Call##_jname##MethodV(this, obj, methodID, args); }
460 #define CALL_TYPE_METHODA(_jtype, _jname)                                   \
461     _jtype Call##_jname##MethodA(jobject obj, jmethodID methodID,           \
462         jvalue* args)                                                       \
463     { return functions->Call##_jname##MethodA(this, obj, methodID, args); }
464 
465 #define CALL_TYPE(_jtype, _jname)                                           \
466     CALL_TYPE_METHOD(_jtype, _jname)                                        \
467     CALL_TYPE_METHODV(_jtype, _jname)                                       \
468     CALL_TYPE_METHODA(_jtype, _jname)
469 
470     CALL_TYPE(jobject, Object)
471     CALL_TYPE(jboolean, Boolean)
472     CALL_TYPE(jbyte, Byte)
473     CALL_TYPE(jchar, Char)
474     CALL_TYPE(jshort, Short)
475     CALL_TYPE(jint, Int)
476     CALL_TYPE(jlong, Long)
477     CALL_TYPE(jfloat, Float)
478     CALL_TYPE(jdouble, Double)
479 
480     void CallVoidMethod(jobject obj, jmethodID methodID, ...)
481     {
482         va_list args;
483         va_start(args, methodID);
484         functions->CallVoidMethodV(this, obj, methodID, args);
485         va_end(args);
486     }
487     void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)
488     { functions->CallVoidMethodV(this, obj, methodID, args); }
489     void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)
490     { functions->CallVoidMethodA(this, obj, methodID, args); }
491 
492 #define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)                            \
493     _jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz,        \
494         jmethodID methodID, ...)                                            \
495     {                                                                       \
496         _jtype result;                                                      \
497         va_list args;                                                       \
498         va_start(args, methodID);                                           \
499         result = functions->CallNonvirtual##_jname##MethodV(this, obj,      \
500                     clazz, methodID, args);                                 \
501         va_end(args);                                                       \
502         return result;                                                      \
503     }
504 #define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname)                           \
505     _jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz,       \
506         jmethodID methodID, va_list args)                                   \
507     { return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz,   \
508         methodID, args); }
509 #define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)                           \
510     _jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz,       \
511         jmethodID methodID, jvalue* args)                                   \
512     { return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz,   \
513         methodID, args); }
514 
515 #define CALL_NONVIRT_TYPE(_jtype, _jname)                                   \
516     CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)                                \
517     CALL_NONVIRT_TYPE_METHODV(_jtype, _jname)                               \
518     CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)
519 
520     CALL_NONVIRT_TYPE(jobject, Object)
521     CALL_NONVIRT_TYPE(jboolean, Boolean)
522     CALL_NONVIRT_TYPE(jbyte, Byte)
523     CALL_NONVIRT_TYPE(jchar, Char)
524     CALL_NONVIRT_TYPE(jshort, Short)
525     CALL_NONVIRT_TYPE(jint, Int)
526     CALL_NONVIRT_TYPE(jlong, Long)
527     CALL_NONVIRT_TYPE(jfloat, Float)
528     CALL_NONVIRT_TYPE(jdouble, Double)
529 
530     void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
531         jmethodID methodID, ...)
532     {
533         va_list args;
534         va_start(args, methodID);
535         functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args);
536         va_end(args);
537     }
538     void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
539         jmethodID methodID, va_list args)
540     { functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); }
541     void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
542         jmethodID methodID, jvalue* args)
543     { functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); }
544 
545     jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
546     { return functions->GetFieldID(this, clazz, name, sig); }
547 
548     jobject GetObjectField(jobject obj, jfieldID fieldID)
549     { return functions->GetObjectField(this, obj, fieldID); }
550     jboolean GetBooleanField(jobject obj, jfieldID fieldID)
551     { return functions->GetBooleanField(this, obj, fieldID); }
552     jbyte GetByteField(jobject obj, jfieldID fieldID)
553     { return functions->GetByteField(this, obj, fieldID); }
554     jchar GetCharField(jobject obj, jfieldID fieldID)
555     { return functions->GetCharField(this, obj, fieldID); }
556     jshort GetShortField(jobject obj, jfieldID fieldID)
557     { return functions->GetShortField(this, obj, fieldID); }
558     jint GetIntField(jobject obj, jfieldID fieldID)
559     { return functions->GetIntField(this, obj, fieldID); }
560     jlong GetLongField(jobject obj, jfieldID fieldID)
561     { return functions->GetLongField(this, obj, fieldID); }
562     jfloat GetFloatField(jobject obj, jfieldID fieldID)
563     { return functions->GetFloatField(this, obj, fieldID); }
564     jdouble GetDoubleField(jobject obj, jfieldID fieldID)
565     { return functions->GetDoubleField(this, obj, fieldID); }
566 
567     void SetObjectField(jobject obj, jfieldID fieldID, jobject value)
568     { functions->SetObjectField(this, obj, fieldID, value); }
569     void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
570     { functions->SetBooleanField(this, obj, fieldID, value); }
571     void SetByteField(jobject obj, jfieldID fieldID, jbyte value)
572     { functions->SetByteField(this, obj, fieldID, value); }
573     void SetCharField(jobject obj, jfieldID fieldID, jchar value)
574     { functions->SetCharField(this, obj, fieldID, value); }
575     void SetShortField(jobject obj, jfieldID fieldID, jshort value)
576     { functions->SetShortField(this, obj, fieldID, value); }
577     void SetIntField(jobject obj, jfieldID fieldID, jint value)
578     { functions->SetIntField(this, obj, fieldID, value); }
579     void SetLongField(jobject obj, jfieldID fieldID, jlong value)
580     { functions->SetLongField(this, obj, fieldID, value); }
581     void SetFloatField(jobject obj, jfieldID fieldID, jfloat value)
582     { functions->SetFloatField(this, obj, fieldID, value); }
583     void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value)
584     { functions->SetDoubleField(this, obj, fieldID, value); }
585 
586     jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)
587     { return functions->GetStaticMethodID(this, clazz, name, sig); }
588 
589 #define CALL_STATIC_TYPE_METHOD(_jtype, _jname)                             \
590     _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID,     \
591         ...)                                                                \
592     {                                                                       \
593         _jtype result;                                                      \
594         va_list args;                                                       \
595         va_start(args, methodID);                                           \
596         result = functions->CallStatic##_jname##MethodV(this, clazz,        \
597                     methodID, args);                                        \
598         va_end(args);                                                       \
599         return result;                                                      \
600     }
601 #define CALL_STATIC_TYPE_METHODV(_jtype, _jname)                            \
602     _jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID,    \
603         va_list args)                                                       \
604     { return functions->CallStatic##_jname##MethodV(this, clazz, methodID,  \
605         args); }
606 #define CALL_STATIC_TYPE_METHODA(_jtype, _jname)                            \
607     _jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID,    \
608         jvalue* args)                                                       \
609     { return functions->CallStatic##_jname##MethodA(this, clazz, methodID,  \
610         args); }
611 
612 #define CALL_STATIC_TYPE(_jtype, _jname)                                    \
613     CALL_STATIC_TYPE_METHOD(_jtype, _jname)                                 \
614     CALL_STATIC_TYPE_METHODV(_jtype, _jname)                                \
615     CALL_STATIC_TYPE_METHODA(_jtype, _jname)
616 
617     CALL_STATIC_TYPE(jobject, Object)
618     CALL_STATIC_TYPE(jboolean, Boolean)
619     CALL_STATIC_TYPE(jbyte, Byte)
620     CALL_STATIC_TYPE(jchar, Char)
621     CALL_STATIC_TYPE(jshort, Short)
622     CALL_STATIC_TYPE(jint, Int)
623     CALL_STATIC_TYPE(jlong, Long)
624     CALL_STATIC_TYPE(jfloat, Float)
625     CALL_STATIC_TYPE(jdouble, Double)
626 
627     void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)
628     {
629         va_list args;
630         va_start(args, methodID);
631         functions->CallStaticVoidMethodV(this, clazz, methodID, args);
632         va_end(args);
633     }
634     void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args)
635     { functions->CallStaticVoidMethodV(this, clazz, methodID, args); }
636     void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args)
637     { functions->CallStaticVoidMethodA(this, clazz, methodID, args); }
638 
639     jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
640     { return functions->GetStaticFieldID(this, clazz, name, sig); }
641 
642     jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)
643     { return functions->GetStaticObjectField(this, clazz, fieldID); }
644     jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)
645     { return functions->GetStaticBooleanField(this, clazz, fieldID); }
646     jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)
647     { return functions->GetStaticByteField(this, clazz, fieldID); }
648     jchar GetStaticCharField(jclass clazz, jfieldID fieldID)
649     { return functions->GetStaticCharField(this, clazz, fieldID); }
650     jshort GetStaticShortField(jclass clazz, jfieldID fieldID)
651     { return functions->GetStaticShortField(this, clazz, fieldID); }
652     jint GetStaticIntField(jclass clazz, jfieldID fieldID)
653     { return functions->GetStaticIntField(this, clazz, fieldID); }
654     jlong GetStaticLongField(jclass clazz, jfieldID fieldID)
655     { return functions->GetStaticLongField(this, clazz, fieldID); }
656     jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)
657     { return functions->GetStaticFloatField(this, clazz, fieldID); }
658     jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)
659     { return functions->GetStaticDoubleField(this, clazz, fieldID); }
660 
661     void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value)
662     { functions->SetStaticObjectField(this, clazz, fieldID, value); }
663     void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value)
664     { functions->SetStaticBooleanField(this, clazz, fieldID, value); }
665     void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value)
666     { functions->SetStaticByteField(this, clazz, fieldID, value); }
667     void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value)
668     { functions->SetStaticCharField(this, clazz, fieldID, value); }
669     void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value)
670     { functions->SetStaticShortField(this, clazz, fieldID, value); }
671     void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value)
672     { functions->SetStaticIntField(this, clazz, fieldID, value); }
673     void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value)
674     { functions->SetStaticLongField(this, clazz, fieldID, value); }
675     void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value)
676     { functions->SetStaticFloatField(this, clazz, fieldID, value); }
677     void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value)
678     { functions->SetStaticDoubleField(this, clazz, fieldID, value); }
679 
680     jstring NewString(const jchar* unicodeChars, jsize len)
681     { return functions->NewString(this, unicodeChars, len); }
682 
683     jsize GetStringLength(jstring string)
684     { return functions->GetStringLength(this, string); }
685 
686     const jchar* GetStringChars(jstring string, jboolean* isCopy)
687     { return functions->GetStringChars(this, string, isCopy); }
688 
689     void ReleaseStringChars(jstring string, const jchar* chars)
690     { functions->ReleaseStringChars(this, string, chars); }
691 
692     jstring NewStringUTF(const char* bytes)
693     { return functions->NewStringUTF(this, bytes); }
694 
695     jsize GetStringUTFLength(jstring string)
696     { return functions->GetStringUTFLength(this, string); }
697 
698     const char* GetStringUTFChars(jstring string, jboolean* isCopy)
699     { return functions->GetStringUTFChars(this, string, isCopy); }
700 
701     void ReleaseStringUTFChars(jstring string, const char* utf)
702     { functions->ReleaseStringUTFChars(this, string, utf); }
703 
704     jsize GetArrayLength(jarray array)
705     { return functions->GetArrayLength(this, array); }
706 
707     jobjectArray NewObjectArray(jsize length, jclass elementClass,
708         jobject initialElement)
709     { return functions->NewObjectArray(this, length, elementClass,
710         initialElement); }
711 
712     jobject GetObjectArrayElement(jobjectArray array, jsize index)
713     { return functions->GetObjectArrayElement(this, array, index); }
714 
715     void SetObjectArrayElement(jobjectArray array, jsize index, jobject value)
716     { functions->SetObjectArrayElement(this, array, index, value); }
717 
718     jbooleanArray NewBooleanArray(jsize length)
719     { return functions->NewBooleanArray(this, length); }
720     jbyteArray NewByteArray(jsize length)
721     { return functions->NewByteArray(this, length); }
722     jcharArray NewCharArray(jsize length)
723     { return functions->NewCharArray(this, length); }
724     jshortArray NewShortArray(jsize length)
725     { return functions->NewShortArray(this, length); }
726     jintArray NewIntArray(jsize length)
727     { return functions->NewIntArray(this, length); }
728     jlongArray NewLongArray(jsize length)
729     { return functions->NewLongArray(this, length); }
730     jfloatArray NewFloatArray(jsize length)
731     { return functions->NewFloatArray(this, length); }
732     jdoubleArray NewDoubleArray(jsize length)
733     { return functions->NewDoubleArray(this, length); }
734 
735     jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy)
736     { return functions->GetBooleanArrayElements(this, array, isCopy); }
737     jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy)
738     { return functions->GetByteArrayElements(this, array, isCopy); }
739     jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy)
740     { return functions->GetCharArrayElements(this, array, isCopy); }
741     jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy)
742     { return functions->GetShortArrayElements(this, array, isCopy); }
743     jint* GetIntArrayElements(jintArray array, jboolean* isCopy)
744     { return functions->GetIntArrayElements(this, array, isCopy); }
745     jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy)
746     { return functions->GetLongArrayElements(this, array, isCopy); }
747     jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy)
748     { return functions->GetFloatArrayElements(this, array, isCopy); }
749     jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy)
750     { return functions->GetDoubleArrayElements(this, array, isCopy); }
751 
752     void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems,
753         jint mode)
754     { functions->ReleaseBooleanArrayElements(this, array, elems, mode); }
755     void ReleaseByteArrayElements(jbyteArray array, jbyte* elems,
756         jint mode)
757     { functions->ReleaseByteArrayElements(this, array, elems, mode); }
758     void ReleaseCharArrayElements(jcharArray array, jchar* elems,
759         jint mode)
760     { functions->ReleaseCharArrayElements(this, array, elems, mode); }
761     void ReleaseShortArrayElements(jshortArray array, jshort* elems,
762         jint mode)
763     { functions->ReleaseShortArrayElements(this, array, elems, mode); }
764     void ReleaseIntArrayElements(jintArray array, jint* elems,
765         jint mode)
766     { functions->ReleaseIntArrayElements(this, array, elems, mode); }
767     void ReleaseLongArrayElements(jlongArray array, jlong* elems,
768         jint mode)
769     { functions->ReleaseLongArrayElements(this, array, elems, mode); }
770     void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems,
771         jint mode)
772     { functions->ReleaseFloatArrayElements(this, array, elems, mode); }
773     void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems,
774         jint mode)
775     { functions->ReleaseDoubleArrayElements(this, array, elems, mode); }
776 
777     void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
778         jboolean* buf)
779     { functions->GetBooleanArrayRegion(this, array, start, len, buf); }
780     void GetByteArrayRegion(jbyteArray array, jsize start, jsize len,
781         jbyte* buf)
782     { functions->GetByteArrayRegion(this, array, start, len, buf); }
783     void GetCharArrayRegion(jcharArray array, jsize start, jsize len,
784         jchar* buf)
785     { functions->GetCharArrayRegion(this, array, start, len, buf); }
786     void GetShortArrayRegion(jshortArray array, jsize start, jsize len,
787         jshort* buf)
788     { functions->GetShortArrayRegion(this, array, start, len, buf); }
789     void GetIntArrayRegion(jintArray array, jsize start, jsize len,
790         jint* buf)
791     { functions->GetIntArrayRegion(this, array, start, len, buf); }
792     void GetLongArrayRegion(jlongArray array, jsize start, jsize len,
793         jlong* buf)
794     { functions->GetLongArrayRegion(this, array, start, len, buf); }
795     void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
796         jfloat* buf)
797     { functions->GetFloatArrayRegion(this, array, start, len, buf); }
798     void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
799         jdouble* buf)
800     { functions->GetDoubleArrayRegion(this, array, start, len, buf); }
801 
802     void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
803         const jboolean* buf)
804     { functions->SetBooleanArrayRegion(this, array, start, len, buf); }
805     void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
806         const jbyte* buf)
807     { functions->SetByteArrayRegion(this, array, start, len, buf); }
808     void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
809         const jchar* buf)
810     { functions->SetCharArrayRegion(this, array, start, len, buf); }
811     void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
812         const jshort* buf)
813     { functions->SetShortArrayRegion(this, array, start, len, buf); }
814     void SetIntArrayRegion(jintArray array, jsize start, jsize len,
815         const jint* buf)
816     { functions->SetIntArrayRegion(this, array, start, len, buf); }
817     void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
818         const jlong* buf)
819     { functions->SetLongArrayRegion(this, array, start, len, buf); }
820     void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
821         const jfloat* buf)
822     { functions->SetFloatArrayRegion(this, array, start, len, buf); }
823     void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
824         const jdouble* buf)
825     { functions->SetDoubleArrayRegion(this, array, start, len, buf); }
826 
827     jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,
828         jint nMethods)
829     { return functions->RegisterNatives(this, clazz, methods, nMethods); }
830 
831     jint UnregisterNatives(jclass clazz)
832     { return functions->UnregisterNatives(this, clazz); }
833 
834     jint MonitorEnter(jobject obj)
835     { return functions->MonitorEnter(this, obj); }
836 
837     jint MonitorExit(jobject obj)
838     { return functions->MonitorExit(this, obj); }
839 
840     jint GetJavaVM(JavaVM** vm)
841     { return functions->GetJavaVM(this, vm); }
842 
843     void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf)
844     { functions->GetStringRegion(this, str, start, len, buf); }
845 
846     void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf)
847     { return functions->GetStringUTFRegion(this, str, start, len, buf); }
848 
849     void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)
850     { return functions->GetPrimitiveArrayCritical(this, array, isCopy); }
851 
852     void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode)
853     { functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); }
854 
855     const jchar* GetStringCritical(jstring string, jboolean* isCopy)
856     { return functions->GetStringCritical(this, string, isCopy); }
857 
858     void ReleaseStringCritical(jstring string, const jchar* carray)
859     { functions->ReleaseStringCritical(this, string, carray); }
860 
861     jweak NewWeakGlobalRef(jobject obj)
862     { return functions->NewWeakGlobalRef(this, obj); }
863 
864     void DeleteWeakGlobalRef(jweak obj)
865     { functions->DeleteWeakGlobalRef(this, obj); }
866 
867     jboolean ExceptionCheck()
868     { return functions->ExceptionCheck(this); }
869 
870     jobject NewDirectByteBuffer(void* address, jlong capacity)
871     { return functions->NewDirectByteBuffer(this, address, capacity); }
872 
873     void* GetDirectBufferAddress(jobject buf)
874     { return functions->GetDirectBufferAddress(this, buf); }
875 
876     jlong GetDirectBufferCapacity(jobject buf)
877     { return functions->GetDirectBufferCapacity(this, buf); }
878 
879     /* added in JNI 1.6 */
880     jobjectRefType GetObjectRefType(jobject obj)
881     { return functions->GetObjectRefType(this, obj); }
882 #endif /*__cplusplus*/
883 };
View Code

 

总结一下:

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

 

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

 

推荐阅读