AndroidJNI入門第三篇——jni標頭檔案分析

技術小胖子發表於2017-11-08

一、 首先寫了java檔案:


  1. public class HeaderFile {  
  2.     private native void  doVoid();  
  3.     native int doShort();  
  4.     native void doArray(Object[] o );  
  5.     native int doInt(int i);      //byte ,short ,int,long,float,double ,boolean,char        
  6.     native int doInt(double d);    //byte ,short ,int,long,float,double ,boolean,char  
  7.     native int doInt(Object o);      
  8.     native int doInt(double d1,double d2);  
  9.     static native int doInt(double d1 ,double d2,double d3);  
  10.     static native int doInt(double d1 ,float f,boolean b ,char[] c );    
  11.      
  12.     native int doInt(int[] i);  
  13.     native int doInt(int[] i1,double[] i2 );      
  14.     static native int doInt(int[] i1,double[] i2 ,Object[] o );  
  15.      
  16.     public native String doString(String s);  
  17.     public native Object doObject(Object o );  
  18.     public native Enumeration doInterface(Iterator it);  
  19.     public native Student doStudent(Student s);  
  20.      
  21. //  native int[] doInt(int[] i);  //byte ,short ,int,long,float,double ,boolean,char  
  22.     public native String[] doString(String[] s);  
  23.     public native Object[] doObjects(Object[] o );  
  24.     public native Enumeration[] doInterface(Iterator[] it);  
  25.     public native Student[] doStudent(Student[] s);  
  26.             
  27.     public native static Object doAll(int[] i , String[] s , Student[] student );               

java檔案中包含了private、public、protect等型別的方法,static 方法和非static 方法,返回型別有基礎型別、物件等。

           二、下面看一下生成的標頭檔案:


  1. /* DO NOT EDIT THIS FILE – it is machine generated */ 
  2. #include <jni.h>  
  3. /* Header for class com_nedu_jni_helloword_HeaderFile */ 
  4.  
  5. #ifndef _Included_com_nedu_jni_helloword_HeaderFile  
  6. #define _Included_com_nedu_jni_helloword_HeaderFile  
  7. #ifdef __cplusplus  
  8. extern “C” {  
  9. #endif  
  10. /*  
  11.  * Class:     com_nedu_jni_helloword_HeaderFile  
  12.  * Method:    doVoid  
  13.  * Signature: ()V  
  14.  */ 
  15. JNIEXPORT void JNICALL Java_com_nedu_jni_helloword_HeaderFile_doVoid  
  16.   (JNIEnv *, jobject);  
  17.  
  18. /*  
  19.  * Class:     com_nedu_jni_helloword_HeaderFile  
  20.  * Method:    doShort  
  21.  * Signature: ()I  
  22.  */ 
  23. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doShort  
  24.   (JNIEnv *, jobject);  
  25.  
  26. /*  
  27.  * Class:     com_nedu_jni_helloword_HeaderFile  
  28.  * Method:    doArray  
  29.  * Signature: ([Ljava/lang/Object;)V  
  30.  */ 
  31. JNIEXPORT void JNICALL Java_com_nedu_jni_helloword_HeaderFile_doArray  
  32.   (JNIEnv *, jobject, jobjectArray);  
  33.  
  34. /*  
  35.  * Class:     com_nedu_jni_helloword_HeaderFile  
  36.  * Method:    doInt  
  37.  * Signature: (I)I  
  38.  */ 
  39. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__I  
  40.   (JNIEnv *, jobject, jint);  
  41.  
  42. /*  
  43.  * Class:     com_nedu_jni_helloword_HeaderFile  
  44.  * Method:    doInt  
  45.  * Signature: (D)I  
  46.  */ 
  47. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__D  
  48.   (JNIEnv *, jobject, jdouble);  
  49.  
  50. /*  
  51.  * Class:     com_nedu_jni_helloword_HeaderFile  
  52.  * Method:    doInt  
  53.  * Signature: (Ljava/lang/Object;)I  
  54.  */ 
  55. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__Ljava_lang_Object_2  
  56.   (JNIEnv *, jobject, jobject);  
  57.  
  58. /*  
  59.  * Class:     com_nedu_jni_helloword_HeaderFile  
  60.  * Method:    doInt  
  61.  * Signature: (DD)I  
  62.  */ 
  63. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DD  
  64.   (JNIEnv *, jobject, jdouble, jdouble);  
  65.  
  66. /*  
  67.  * Class:     com_nedu_jni_helloword_HeaderFile  
  68.  * Method:    doInt  
  69.  * Signature: (DDD)I  
  70.  */ 
  71. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DDD  
  72.   (JNIEnv *, jclass, jdouble, jdouble, jdouble);  
  73.  
  74. /*  
  75.  * Class:     com_nedu_jni_helloword_HeaderFile  
  76.  * Method:    doInt  
  77.  * Signature: (DFZ[C)I  
  78.  */ 
  79. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DFZ_3C  
  80.   (JNIEnv *, jclass, jdouble, jfloat, jboolean, jcharArray);  
  81.  
  82. /*  
  83.  * Class:     com_nedu_jni_helloword_HeaderFile  
  84.  * Method:    doInt  
  85.  * Signature: ([I)I  
  86.  */ 
  87. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt___3I  
  88.   (JNIEnv *, jobject, jintArray);  
  89.  
  90. /*  
  91.  * Class:     com_nedu_jni_helloword_HeaderFile  
  92.  * Method:    doInt  
  93.  * Signature: ([I[D)I  
  94.  */ 
  95. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt___3I_3D  
  96.   (JNIEnv *, jobject, jintArray, jdoubleArray);  
  97.  
  98. /*  
  99.  * Class:     com_nedu_jni_helloword_HeaderFile  
  100.  * Method:    doInt  
  101.  * Signature: ([I[D[Ljava/lang/Object;)I  
  102.  */ 
  103. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt___3I_3D_3Ljava_lang_Object_2  
  104.   (JNIEnv *, jclass, jintArray, jdoubleArray, jobjectArray);  
  105.  
  106. /*  
  107.  * Class:     com_nedu_jni_helloword_HeaderFile  
  108.  * Method:    doString  
  109.  * Signature: (Ljava/lang/String;)Ljava/lang/String;  
  110.  */ 
  111. JNIEXPORT jstring JNICALL Java_com_nedu_jni_helloword_HeaderFile_doString__Ljava_lang_String_2  
  112.   (JNIEnv *, jobject, jstring);  
  113.  
  114. /*  
  115.  * Class:     com_nedu_jni_helloword_HeaderFile  
  116.  * Method:    doObject  
  117.  * Signature: (Ljava/lang/Object;)Ljava/lang/Object;  
  118.  */ 
  119. JNIEXPORT jobject JNICALL Java_com_nedu_jni_helloword_HeaderFile_doObject  
  120.   (JNIEnv *, jobject, jobject);  
  121.  
  122. /*  
  123.  * Class:     com_nedu_jni_helloword_HeaderFile  
  124.  * Method:    doInterface  
  125.  * Signature: (Ljava/util/Iterator;)Ljava/util/Enumeration;  
  126.  */ 
  127. JNIEXPORT jobject JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInterface__Ljava_util_Iterator_2  
  128.   (JNIEnv *, jobject, jobject);  
  129.  
  130. /*  
  131.  * Class:     com_nedu_jni_helloword_HeaderFile  
  132.  * Method:    doStudent  
  133.  * Signature: (Lcom/nedu/jni/helloword/Student;)Lcom/nedu/jni/helloword/Student;  
  134.  */ 
  135. JNIEXPORT jobject JNICALL Java_com_nedu_jni_helloword_HeaderFile_doStudent__Lcom_nedu_jni_helloword_Student_2  
  136.   (JNIEnv *, jobject, jobject);  
  137.  
  138. /*  
  139.  * Class:     com_nedu_jni_helloword_HeaderFile  
  140.  * Method:    doString  
  141.  * Signature: ([Ljava/lang/String;)[Ljava/lang/String;  
  142.  */ 
  143. JNIEXPORT jobjectArray JNICALL Java_com_nedu_jni_helloword_HeaderFile_doString___3Ljava_lang_String_2  
  144.   (JNIEnv *, jobject, jobjectArray);  
  145.  
  146. /*  
  147.  * Class:     com_nedu_jni_helloword_HeaderFile  
  148.  * Method:    doObjects  
  149.  * Signature: ([Ljava/lang/Object;)[Ljava/lang/Object;  
  150.  */ 
  151. JNIEXPORT jobjectArray JNICALL Java_com_nedu_jni_helloword_HeaderFile_doObjects  
  152.   (JNIEnv *, jobject, jobjectArray);  
  153.  
  154. /*  
  155.  * Class:     com_nedu_jni_helloword_HeaderFile  
  156.  * Method:    doInterface  
  157.  * Signature: ([Ljava/util/Iterator;)[Ljava/util/Enumeration;  
  158.  */ 
  159. JNIEXPORT jobjectArray JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInterface___3Ljava_util_Iterator_2  
  160.   (JNIEnv *, jobject, jobjectArray);  
  161.  
  162. /*  
  163.  * Class:     com_nedu_jni_helloword_HeaderFile  
  164.  * Method:    doStudent  
  165.  * Signature: ([Lcom/nedu/jni/helloword/Student;)[Lcom/nedu/jni/helloword/Student;  
  166.  */ 
  167. JNIEXPORT jobjectArray JNICALL Java_com_nedu_jni_helloword_HeaderFile_doStudent___3Lcom_nedu_jni_helloword_Student_2  
  168.   (JNIEnv *, jobject, jobjectArray);  
  169.  
  170. /*  
  171.  * Class:     com_nedu_jni_helloword_HeaderFile  
  172.  * Method:    doAll  
  173.  * Signature: ([I[Ljava/lang/String;[Lcom/nedu/jni/helloword/Student;)Ljava/lang/Object;  
  174.  */ 
  175. JNIEXPORT jobject JNICALL Java_com_nedu_jni_helloword_HeaderFile_doAll  
  176.   (JNIEnv *, jclass, jintArray, jobjectArray, jobjectArray);  
  177.  
  178. #ifdef __cplusplus  
  179. }  
  180. #endif  
  181. #endif  

三、標頭檔案分析如下:

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

          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,引數為doublefloatchar[]   
  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-co

  8. lor: rgb(255, 0, 0);”>jobject</span>, jdouble, jdouble);  
  9.  
  10. /*  
  11.  * Class:     com_nedu_jni_helloword_HeaderFile  
  12.  * Method:    doInt  
  13.  * Signature: (DDD)I  
  14.  */ 
  15. JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DDD  
  16.   (JNIEnv *, <span style=“color:#000000;background-color: rgb(255, 0, 0);”>jclass</span>, jdouble, jdouble, jdouble); 

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

2、 privatefriendlyprotected以及public這些方法限制符不會在JNI的標頭檔案中出現。這些訪問修飾符只有在其它類

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


  1. /**  
  2. * @author 張興業  
  3. * 郵箱:xy-zhang@163.com  
  4. * qq:363302850  
  5. */ 


本文轉自xyz_lmn51CTO部落格,原文連結:http://blog.51cto.com/xyzlmn/817213,如需轉載請自行聯絡原作者


相關文章