技術轉載:Jni學習三:jni使用java對象詳解

一、 首先寫了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、文件的前九行就不用說了,他們是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-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、 privatefriendlyprotected以及public這些方法限制符不會在JNI的頭文件中出現。這些訪問修飾符只有在其它類

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章