• Android JNI入门第三篇——jni头文件分析


     一、 首先写了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 );               
    28. }  

                             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、文件的前九行就不用说了,他们是是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,没有参数。  
    1. (DFZ[C)I 返回为int,参数为double、float、char[]  
    1. (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中不关心此修饰符!

    /**
    * @author 张兴业
    * 邮箱:xy-zhang#163.com
    * android开发进阶群:278401545
    *
    */

  • 相关阅读:
    每月碎碎念 | 2019.7
    聊聊HTML5中的Web Notification桌面通知
    Python的海龟绘图法小知识
    面向对象是什么意思?通俗易懂
    HTML实体
    gcc错误[Error] ld returned 1 exit status
    Markdown怎么使用制表符TAB键?为什么TAB失灵了?
    力扣题解——2的幂
    Jquery中的Ajax
    7个你可能不认识的CSS单位
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4500229.html
Copyright © 2020-2023  润新知