zoukankan      html  css  js  c++  java
  • JNI注册调用完整过程-安卓4.4

    在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注册、调用过程,有错误的地方请大家指出谢谢!

     
  • 相关阅读:
    滑动最小值 /// 单调队列
    Largest Rectangle in a Histogram /// 单调栈 oj23906
    能量项链 /// oj23800
    Traveling by Stagecoach /// 状压DP oj22914
    Hamilton回路 旅行商TSP问题 /// dp oj1964
    最难的工作 /// SPFA模板 oj1396
    次短路 /// dijkstra oj1597
    USACO 2006 November Gold Fence Repair /// 贪心(有意思)(优先队列) oj23940
    石子合并问题 /// 区间DP oj2025
    多边形游戏 /// 区间DP oj1903
  • 原文地址:https://www.cnblogs.com/aliflycoris/p/5800116.html
Copyright © 2011-2022 走看看