1N5

1.Java访问Native的步骤
  * 在Java类中声明一个本地native方法。
  * 使用Javah命令生成包含native方法定义的C/C++头文件。
  * 按照生成的C/C++头文件来写C/C++源文件。
  * 将C/C++源文件编译成动态链接库。
  * 把DLL文件加入到PATH环境变量下。
  * Java类中加载DLL,然后调用声明的native方法。
    System.loadLibrary("nativeCode");  //如果找不到的话会抛出运行时异常。
(注:JNI会影响JavaApplication的跨平台特性。
     Java是强类型的语言而C/C++不是,所以容易出错。)

2. JNIEnv类型实际上代表了Java环境。通过这个JNIEnv*指针,就可以对Java端的
代码进行操作。例如,创建Java类的对象,调用Java对象的方法,获取Java对象的
属性等等。JNIEnv的指针会被JNI传入到本地方法的实现函数中来对Java端的代码进
行操作。
   NewObject/NewString/New<TYPE>Array
   Get/Set<TYPE>Field
   Get/SetStatic<TYPE>Field
   Call<TYPE>Method/CallStatic<TYPE>Method

3.Java类型映射
   int         long            jint/jsize      I
   long        _int64          jlong           L
   byte        signed char     jbyte           B
   boolean     unsigned char   jboolean        Z
   char        unsigned short  jchar           C
   short       short           jshort          S
   float       float           jfloat          F
   double      double          jdouble         D
   object      _jobject*       jobject         Ljava/lang/String;
   Array                                       [Ljava/lang/object;

4.JNIEnv类中有如下几个简单的函数可以取得jclass
  jclass FindClass(const char* clsName);
  jclass GetObjectClass(jobject obj);
  jclass GetSuperClass(jclass obj);
(注:FindClass会在classpath系统环境变量下寻找类。
     jclass cls_string = env->FindClass("java/lang/String");)

5.在C/C++本地代码中访问Java端的代码,一个常见的应用就是获取类的属性和调用类的方法。为了在C/C++中表示属性

和方法,JNI在Jni.h头文件中定义了jfieldID,jmethodID
类型来分别代表Java端的属性和方法。
  GetFieldID/GetMethodID
  GetStaticFieldID/GetStaticMethodID

6.引用Java层代码
  * jclass clazz_TestNative = env->FindClass("cn/itcast/TestNative");
    jmethodID id_func = env ->GetMethodID(clazz_TestNative,"toString","(I)V");
(注:最后一个参数是根据参数类型区分被重载的函数)
------------------------
  * jclass hello_clazz = env->GetObjectClass(obj);
    jfieldID fieldID_prop= env->GetFieldID(hello_clazz,"property","I");
    jmethodID methodID_func = env->GetMethodID(hello_clazz,"function","(ILjava/util/Date;[I)I");
    env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
------------------------
  * jclass clazz_TestNative = env->GetObjectClass(obj);
    jfieldID id_number = env_GetFieldID(clazz_TestNative,"number","I");
    jint number = env->GetIntField(obj,id_number);
    env->SetIntField(obj,id_number,100L);
------------------------
    boolean function(int i,double d,char c){...}
  * env->CallBooleanMethod(obj,id_function,100L,3.44,L'3');
  * jvalue *args = new jvlaue[3];
    args[0].i = 100L;
    args[1].d = 3.44;
    args[3].c = L'3';

7.在JNI中定义的CallNonvirtual<TYPE>Method就能够实现子类对象调用父类方法的功能。
如果想调用一个对象的父类的方法,而不是子类的这个方法的话,就可以使用CallNonvirtual<TYPE>Method。













你可能感兴趣的:(java,C++,c,jni,C#)