zoukankan      html  css  js  c++  java
  • Java基础知识——JNI入门介绍

    Java类型和本地类型对应  
      在如下情况下,需 要在本地方法中应用java对象的引用,就会用到类型之间的转换:
      1)java方法里面将参数传入本地方法;
      2)在本地方法里面创建java对象;
      3)在本地方法里面return结果给java程序。
      分为如下两种情况:
      Java原始类型
      像 booleans、integers、floats等从Java程序中传到本地方法中的原始类型可以直接使用,下面是java中的原始类型和本地方法中的 类型的对应:
      Java类型  本地类型  字节(bit)
      boolean    jboolean   8, unsigned
      byte    jbyte    8
      char    jchar    16, unsigned
      short    jshort    16
      int     jint     32
      long    jlong    64
      float    jfloat    32
      double   jdouble   64
      void    void     n/a
      也就是说如果我在方法中传进去了一个boolean的参数的话,那么我在本地方法中就有jboolean类型与之对应。同理,如果在本 地方法中return一个jint的话,那么在java中就返回一个int类型。
      Java对象
      Java对象做为引用被传递到本地方法中,所有这些Java对象的引用都有一个共同的父类型jobject(相当于java中的 Object类是所有类的父类一样)。下面是JNI实现的一些jobject的子类:
      4.本地方法中访 问java程序中的内容
      1)访问String对象:
       从java程序中传过去的String对象在本地方法中对应的是jstring类型,jstring类型和c中的char*不同,所以如果你直接当做 char*使用的话,就会出错。因此在使用之前需要将jstring转换成为c/c++中的char*,这里使用JNIEnv的方法转换。下面是一个例 子:
      代码3:
      JNIEXPORT jstring JNICALL Java_Prompt_getLine
      (JNIEnv *env, jobject obj, jstring prompt)
      {
      char buf[128];
      const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
      printf("%s", str);
       (*env)->ReleaseStringUTFChars(env, prompt, str);
      这里使用GetStringUTFChars方法将传进来的prompt(jstring类型)转换成为UTF-8的格式,就能够在本 地方法中使用了。
      注意:在使用完你所转换之后的对象之后,需要显示调用 ReleaseStringUTFChars方法,让JVM释放转换成UTF-8的string的对象的空间,如果不显示的调用的话,JVM中会一直保存 该对象,不会被垃圾回收器回收,因此就会导致内存溢出。
      下面是访问String的一些方法:
      ◆GetStringUTFChars将jstring转换成为UTF-8格式的char*
      ◆GetStringChars将jstring转换成为Unicode格式的char*
      ◆ReleaseStringUTFChars释放指向UTF-8格式的char*的指针
      ◆ReleaseStringChars释放指向Unicode格式的char*的指针
      ◆NewStringUTF创建一个UTF-8格式的String对象
       ◆NewString创建一个Unicode格式的String对象
      ◆GetStringUTFLengt获取 UTF-8格式的char*的长度 
      ◆GetStringLength获取Unicode格式的char*的长 度
      2) 访问Array对象:
      和String对象一样,在本地方法 中不能直接访问jarray对象,而是使用JNIEnv指针指向的一些方法来是用。
      
      访问Java原始类型数组:
      1)获取数组的长度:
      代码4:
      JNIEXPORT jint JNICALL Java_IntArray_sumArray
      (JNIEnv *env, jobject obj, jintArray arr)
      {
      int i, sum = 0;
      jsize len = (*env)->GetArrayLength(env, arr);
      如代码4所示,这里获取数组的长度和普通的c语言中的获取数组长度不一样,这里使用JNIEvn的一个函数 GetArrayLength。
      
      2)获取一个指向数组元素的指针:
      代码4:
      jint *body = (*env)->GetIntArrayElements(env, arr, 0);
      使用 GetIntArrayElements方法获取指向arr数组元素的指针,注意该函数的参数,第一个是JNIEnv,第二个是数组,第三个是数组里面第 三个是数组里面开始的元素
      
      3)使用指针取出Array中的元素
      
      代码5:
      for (i=0; i<len; i++) {
      sum += body[i];
      }
      这里使用就和普通的c中的数组使用没有什么不同了
      4)释放数组元素的引用
      代码6: 
       (*env)->ReleaseIntArrayElements(env, arr, body, 0);
      和操作String中的释放String的引用是一样的,提醒JVM回收arr数组元素的引用。
      这里举的例子是使用int数组的,同样还有boolean、float等对应的数组。
      获取数组元素指针的对应关系:
      函数            数组类型
      GetBooleanArrayElements   boolean
       GetByteArrayElements    byte
      GetCharArrayElements     char
      GetShortArrayElements    short
      GetIntArrayElements     int
       GetLongArrayElements    long
      GetFloatArrayElements     float
      GetDoubleArrayElements   double
      
      释放数组元素指针的对应关系:
      Function            Array Type
       ReleaseBooleanArrayElements   boolean
       ReleaseByteArrayElements    byte
       ReleaseCharArrayElements    char
       ReleaseShortArrayElements    short
       ReleaseIntArrayElements     int
       ReleaseLongArrayElements    long
       ReleaseFloatArrayElements    float
       ReleaseDoubleArrayElements   double
      
      访问自定义Java对象数组
      
       The JNI provides a separate set of functions to access elements of object arrays. You can use these functions to get and set individual object array elements.
      
      Note: You cannot get all the object array elements at once.
      
      GetObjectArrayElement returns the object element at a given index.
      
      SetObjectArrayElement updates the object element at a given index.
      
      3) 访问Java对象的方法:
      
      在本地方法中调用Java对象的方法的步骤:
      
      ①.获取你需要访问的Java对象的类:
      
      jclass cls = (*env)->GetObjectClass(env, obj);
      
      使用GetObjectClass方法获取obj对应的jclass。
      
      ②.获取MethodID:
      
      jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
      
      使用GetMethdoID方法获取你要使用的方法的MethdoID。其 参数的意义:
      
      env??>JNIEnv
      
      cls??>第一步获取的jclass
      
      "callback"??>要调用的方法名
      
      "(I)V"??>方法的Signature
      
      ③.调用方法:
      
      (*env)->CallVoidMethod(env, obj, mid, depth);
      
      使用CallVoidMethod方法调用方法。参数的意义:
      
      env??>JNIEnv
      
      obj??>通过本地方法穿过来的jobject
      
      mid??>要调用的MethodID(即第二步获得的 MethodID)
      
      depth??>方法需要的参 数(对应方法的需求,添加相应的参数)
      
      注:这里使用的是 CallVoidMethod方法调用,因为没有返回值,如果有返回值的话使用对应的方法,在后面会提到。
      
      方法的Signature
      
      方法的Signature是由方法的参数和返回值的类型共同构成的,下面是 他们的结构:
      
      "(argument-types)return-type"
      
      其中Java程序中参数类型和其对应的值如下:
      
       Signature  Java中的类型
      Z        boolean
      B       byte
      C       char
      S        short
      I       int
      J       long
      F        float
      D       double
      L fully-qualified-class;   fully-qualified-class
      
      [ type  type[]
      
      ( arg-types ) ret-type  method type
      一个Java类的方法的Signature可以通过javap命令获取:
      javap -s -p Java类名
      给调用的函数传参数:
      通常我们直接在 methodID后面将要传的参数添加在后面,但是还有其他的方法也可以传参数:
      CallVoidMethodV可以 获取一个数量可变的列表作为参数;
      CallVoidMethodA可以获取一个union。
      调用静态方法:
      就是将第二步和第三步调用的方法改为对应的:
      GetStaticMethodID获取对应的静态方法的ID
       CallStaticIntMethod调用静态方法
      调用超类的方法:
      用的比较少,自己 看啦。^_^。
      4)访问Java对象的属性:
      访问Java对象的属性和访问 Java对象的方法基本上一样,只需要将函数里面的Method改为Field即可

  • 相关阅读:
    自定义组件要加@click方法
    绑定样式
    647. Palindromic Substrings
    215. Kth Largest Element in an Array
    448. Find All Numbers Disappeared in an Array
    287. Find the Duplicate Number
    283. Move Zeroes
    234. Palindrome Linked List
    202. Happy Number
    217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/hoys/p/2196290.html
Copyright © 2011-2022 走看看