Jni學習三:jni使用java對象詳解

來源:互聯網
上載者:User
一、 首先寫了java檔案:
public class HeaderFile {      private native void  doVoid();      native int doShort();      native void doArray(Object[] o );      native int doInt(int i);      //byte ,short ,int,long,float,double ,boolean,char            native int doInt(double d);    //byte ,short ,int,long,float,double ,boolean,char      native int doInt(Object o);          native int doInt(double d1,double d2);      static native int doInt(double d1 ,double d2,double d3);      static native int doInt(double d1 ,float f,boolean b ,char[] c );             native int doInt(int[] i);      native int doInt(int[] i1,double[] i2 );          static native int doInt(int[] i1,double[] i2 ,Object[] o );           public native String doString(String s);      public native Object doObject(Object o );      public native Enumeration doInterface(Iterator it);      public native Student doStudent(Student s);       //  native int[] doInt(int[] i);  //byte ,short ,int,long,float,double ,boolean,char      public native String[] doString(String[] s);      public native Object[] doObjects(Object[] o );      public native Enumeration[] doInterface(Iterator[] it);      public native Student[] doStudent(Student[] s);                  public native static Object doAll(int[] i , String[] s , Student[] student );               }

java檔案中包含了private、public、protect等類型的方法,static 方法和非static 方法,傳回型別有基礎類型、對象等。

二、下面看一下產生的標頭檔:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h>  /* Header for class com_nedu_jni_helloword_HeaderFile */  #ifndef _Included_com_nedu_jni_helloword_HeaderFile  #define _Included_com_nedu_jni_helloword_HeaderFile  #ifdef __cplusplus  extern "C" {  #endif  /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doVoid   * Signature: ()V   */ JNIEXPORT void JNICALL Java_com_nedu_jni_helloword_HeaderFile_doVoid    (JNIEnv *, jobject);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doShort   * Signature: ()I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doShort    (JNIEnv *, jobject);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doArray   * Signature: ([Ljava/lang/Object;)V   */ JNIEXPORT void JNICALL Java_com_nedu_jni_helloword_HeaderFile_doArray    (JNIEnv *, jobject, jobjectArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: (I)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__I    (JNIEnv *, jobject, jint);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: (D)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__D    (JNIEnv *, jobject, jdouble);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: (Ljava/lang/Object;)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__Ljava_lang_Object_2    (JNIEnv *, jobject, jobject);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: (DD)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DD    (JNIEnv *, jobject, jdouble, jdouble);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: (DDD)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DDD    (JNIEnv *, jclass, jdouble, jdouble, jdouble);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: (DFZ[C)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DFZ_3C    (JNIEnv *, jclass, jdouble, jfloat, jboolean, jcharArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: ([I)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt___3I    (JNIEnv *, jobject, jintArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: ([I[D)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt___3I_3D    (JNIEnv *, jobject, jintArray, jdoubleArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInt   * Signature: ([I[D[Ljava/lang/Object;)I   */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt___3I_3D_3Ljava_lang_Object_2    (JNIEnv *, jclass, jintArray, jdoubleArray, jobjectArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doString   * Signature: (Ljava/lang/String;)Ljava/lang/String;   */ JNIEXPORT jstring JNICALL Java_com_nedu_jni_helloword_HeaderFile_doString__Ljava_lang_String_2    (JNIEnv *, jobject, jstring);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doObject   * Signature: (Ljava/lang/Object;)Ljava/lang/Object;   */ JNIEXPORT jobject JNICALL Java_com_nedu_jni_helloword_HeaderFile_doObject    (JNIEnv *, jobject, jobject);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInterface   * Signature: (Ljava/util/Iterator;)Ljava/util/Enumeration;   */ JNIEXPORT jobject JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInterface__Ljava_util_Iterator_2    (JNIEnv *, jobject, jobject);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doStudent   * Signature: (Lcom/nedu/jni/helloword/Student;)Lcom/nedu/jni/helloword/Student;   */ JNIEXPORT jobject JNICALL Java_com_nedu_jni_helloword_HeaderFile_doStudent__Lcom_nedu_jni_helloword_Student_2    (JNIEnv *, jobject, jobject);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doString   * Signature: ([Ljava/lang/String;)[Ljava/lang/String;   */ JNIEXPORT jobjectArray JNICALL Java_com_nedu_jni_helloword_HeaderFile_doString___3Ljava_lang_String_2    (JNIEnv *, jobject, jobjectArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doObjects   * Signature: ([Ljava/lang/Object;)[Ljava/lang/Object;   */ JNIEXPORT jobjectArray JNICALL Java_com_nedu_jni_helloword_HeaderFile_doObjects    (JNIEnv *, jobject, jobjectArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doInterface   * Signature: ([Ljava/util/Iterator;)[Ljava/util/Enumeration;   */ JNIEXPORT jobjectArray JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInterface___3Ljava_util_Iterator_2    (JNIEnv *, jobject, jobjectArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doStudent   * Signature: ([Lcom/nedu/jni/helloword/Student;)[Lcom/nedu/jni/helloword/Student;   */ JNIEXPORT jobjectArray JNICALL Java_com_nedu_jni_helloword_HeaderFile_doStudent___3Lcom_nedu_jni_helloword_Student_2    (JNIEnv *, jobject, jobjectArray);   /*   * Class:     com_nedu_jni_helloword_HeaderFile   * Method:    doAll   * Signature: ([I[Ljava/lang/String;[Lcom/nedu/jni/helloword/Student;)Ljava/lang/Object;   */ JNIEXPORT jobject JNICALL Java_com_nedu_jni_helloword_HeaderFile_doAll    (JNIEnv *, jclass, jintArray, jobjectArray, jobjectArray);   #ifdef __cplusplus  }  #endif  #endif
三、標頭檔分析如下:

                       1、檔案的前九行就不用說了,他們是是C、C++的頭,應該很好理解。

       2、方法的注釋部分,每個方法都有它的注釋部分,這些都是相似的,對其中一個分析:

 
  1. /*  
  2.  * Class:     com_nedu_jni_helloword_HeaderFile  
  3.  * Method:    doVoid  
  4.  * Signature: ()V  
  5.  */ 

注釋部分分為三部分Class、Method、Signature。

Class:表示Native方法的類名稱。

Method:表示方法名稱

Signature:是方法的標識,它是一個標識符,主要供我們在JNI操作java對象的方法使用的。

Signature一般是兩部分構成,一個方法的參數,另一個是傳回型別。方法參數在括弧裡面,傳回型別在後面,

例如

 
  1. ()V 返回為void,沒有參數。  
  2. (DFZ[C)I 返回為int,參數為double、float、char[]   
  3. (Ljava/lang/String;)Ljava/lang/String;返回String,參數為String   

如果不清楚其中的字元含義,就不能知道其中的意思,其中字元對應有基本類型、物件類型、數群組類型。分析如下

1)基本類型的對應關係如下:

2) 方法參數或者傳回值為java中的對象時,必須以“L”加上其路徑,不過此路徑必須以“/”分開,自訂的對象也使用本規則,不在包中時直接“L”加上類名稱。比如說java.lang.String為“java/lang/String”,com.nedu.jni.helloword.Student為"com/nedu/jni/helloword/Student"

3)方法參數或者傳回值為數組時類型前加上[,例如[I表示int[],[[[D表示
double[][][],即幾維數組就加幾個[。

看一下例子:

3、方法的聲明

 
  1. JNIEXPORT void JNICALL Java_com_nedu_jni_helloword_HeaderFile_doArray(JNIEnv *,jobject,jobjectArray); 

從上面的標頭檔可以看出方法基本有7部分組成。

1、3部分是都是JNI的關鍵字,表示此函數是要被JNI調用的。

2、表示方法的傳回型別

4、為JNI中標識此方法來源於java的標識頭

5、方法所在類的包名+類名

6、方法名

7、參數,它們有一個共同的特點,包含JNIEnv
*――它是一個介面指標,用於定位函數表中的函數!

    
在JNI規範中一般稱  為   “Interface Pointer”。看到這兒好像和程序呼叫很類似了!是的,JNI中

    
的操作過程,就是面向過程的!後面的jobject是  一個指向該類的指標,類似與C語言中的this。這個

    
第二個參數是變化的,當該方法為類的執行個體方法時該參數為jobject;當該方法為類方法(即靜態方法)

    
時該參數為jclass,指向該類的class。

 

根據不同方法首碼產生的標頭檔比較如下:

1、static與非static的比較:

 
  1. /*  
  2.  * Class:     com_nedu_jni_helloword_HeaderFile  
  3.  * Method:    doInt  
  4.  * Signature: (DD)I  
  5.  */ 
  6. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DD  
  7.   (JNIEnv *, <span style="background-color: rgb(255, 0, 0);">jobject</span>, jdouble, jdouble);  
  8.  
  9. /*  
  10.  * Class:     com_nedu_jni_helloword_HeaderFile  
  11.  * Method:    doInt  
  12.  * Signature: (DDD)I  
  13.  */ 
  14. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DDD  
  15.   (JNIEnv *, <span style="color:#000000;background-color: rgb(255, 0, 0);">jclass</span>, jdouble, jdouble, jdouble); 

第一個是非static方法,第二個是static方法,不同點如上紅色標記。其中的不同將在以後提到。

2、 private、friendly、protected以及public這些方法限制符不會在JNI的標頭檔中出現。這些存取修飾詞只有在其它類

       使用這些方法時有效!JNI中不關心此修飾符!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.