本地代碼訪問Java代碼

(一)本地代碼訪問Java代碼
1.在被調用的C/C++函數中也可以反過來訪問java程序中的類
2.javah工具生成的C/C++函數聲明中,可以看到兩個參數:
JNIEXPORT void JNICALL Java_cn_itcast_sayHello(JNIEnv*

env,jobject obj){
···
}
(二)JNIEnv類型
(1)其實際代表Java環境。通過這個JNIEnv*指針,就可以對Java端

的代碼進行操作。例如,創建Java類的對象,調用Java對象的方法,

獲取Java對象的屬性等等。JNIEnv的指針會被JNI傳入到本地方法的

實現函數中來對Java端的代碼進行操作。


(2)JNIEnv類中常用函數:
NewObject //創建一個java對象
NewString  //創建一個java的String對象
New<TYPE>Array //創建某一個類型的java數組
Get/Set<TYPE>Field  //獲取或設置某一個對象的屬性(需接收參數

GetStatic/SetStatic<TYPE>Field //獲取或設置某一個類的靜態屬性
(需接收表示類的參數)
Call<TYPE>Method  //調用某一類的方法
CallStatic<TYPE>Method  //調用某一個類的靜態方法

 

(三)Java的數據類型在C/C++中的映射關係
Java類型                        本地類型                           JNI定義的別名
int                                  long                                    jint/jsize
long                               _int64                                 jlong
byte                               signed char                        jbyte
boolean                         unsigned char                   jboolean
char                               unsigned short                  jchar
short                              short                                  jshort
float                               float                                   jfloat
double                           double                               jdouble
object                            _jobject*                            jobject


(四)jclass的取得
1.爲了能夠在C/C++中使用java類,JNI.h頭文件中專門定義了jclass

類型來表是Java中的class類
2.JNIEnv類中取得jclass的函數:
(1)jclass FindClass(const char* clsName);
FindClass會在classpath系統環境變量下尋找類。傳入完整類名,注

意包與包之間是用'/'而不是'.'來分隔
如:jclass cls_string=env->FindClass("java/lang/String");
(2)jclass GetObjectClass(jobject obj);
(3)jclass GetSuperClass(jclass obj);

 

(五)訪問java類中的屬性與方法
1.JNI在Jni.h頭文件中定義了jfieldID,jmethodID類型來分別代表Java

端的屬性和方法。
2.在訪問或設置java屬性時,需先在本地代碼取得代表Java屬性的

jfieldID;同理java方法亦然
3.獲取ID方法(JNIEnv):
(1)GetFieldID/GetMethodID
GetMethodID也能取得構造函數的jmethodID.創建一個java對象時

可以調用指定的構造方法
如:env->GetMethodID(data_Clazz,"<init>","()V");
(2)GetStaticFieldID/GetStaticMethodID
類似java的Reflect,需要指定類跟屬性/方法名來取得相應的jfieldID

跟jmethodID
(3)sign是什麼
例如TestNative類中有兩個重載方法:
package cn.itcast;
public class TestNative{
    public void function(int i){
        System.out.println("Integer:"+i);
    }
    public void function(double d){
        System.out.println("Double:"+d);
    }
}

然後在C/C++代碼中需要調用其中一個function方法的話···
//首先取得要調用的方法所在的類···
jclass clazz_TestNative=env->FindClass("cn/itcast/TestNative");
//取得jmethodID之後才能進行調用···
jmethodID id_func=env->GetMethodID

(clazz_TestNative,"function","??");
······

但是到底取得是
void function(int i)還是
void function(double d)的jmethodID呢?

這就是sign的作用了,它用於指定要取得的屬性/方法的類型
這裏的sign
如果指定爲"(I)V"則取回void function(int) 的jmethodID
如果指定爲"(D)V"則取回void function(double)的jmethodID

(4)sign簽名
用來表示要取得的屬性/方法的類型
類型                      相應的簽名
boolean                    Z
byte                          B
char                          C
short                         S
int                             I
long                          L
float                          F
double                      D
void                          V
object                      L用/分隔包的完整類名:   Ljava/lang/String;
Array                        [簽名          [I      [Ljava/lang/Object;
Method              (參數1類型簽名 參數2類型簽名···)返回值類型簽名

 

 

(五)使用簽名取得屬性/方法ID的例子
import java.util.Date;
public class Hello{
    public int property;
    public int function(int foo,Date date,int[] arr){
        System.out.println("function");
        return 0;
   }
   public native void test();
}

 

 

//test本地方法的實現:
JNIEXPORT void Java_Hello_test(JNIEnv* env,jobject obj){
    //因爲test不是靜態函數,所以傳進來的就是調用這個函數的對象
    //否則就傳入一個jclass對象表示native()方法所在的類
    jclass hello_clazz=env->GetObjectClass(obj);
    jfieldID filedID_prop=env->GetFieldID

(hello_calzz,"property","I");
    jmethodID methodID_func=env->GetMethodID

(hello_clazz,"function","(I Ljava/util/Date; [I)I");
    env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
}

 

 

(六)使用javap命令來產生簽名
1.javap -s -p [full class Name]
-s 表示輸出簽名信息
-p 同-private,輸出包括private訪問權限的成員信息

(一)本地代碼訪問Java代碼
1.在被調用的C/C++函數中也可以反過來訪問java程序中的類
2.javah工具生成的C/C++函數聲明中,可以看到兩個參數:
JNIEXPORT void JNICALL Java_cn_itcast_sayHello(JNIEnv*

env,jobject obj){
···
}
(二)JNIEnv類型
(1)其實際代表Java環境。通過這個JNIEnv*指針,就可以對Java端

的代碼進行操作。例如,創建Java類的對象,調用Java對象的方法,

獲取Java對象的屬性等等。JNIEnv的指針會被JNI傳入到本地方法的

實現函數中來對Java端的代碼進行操作。


(2)JNIEnv類中常用函數:
NewObject //創建一個java對象
NewString  //創建一個java的String對象
New<TYPE>Array //創建某一個類型的java數組
Get/Set<TYPE>Field  //獲取或設置某一個對象的屬性(需接收參數

GetStatic/SetStatic<TYPE>Field //獲取或設置某一個類的靜態屬性
(需接收表示類的參數)
Call<TYPE>Method  //調用某一類的方法
CallStatic<TYPE>Method  //調用某一個類的靜態方法

 

(三)Java的數據類型在C/C++中的映射關係
Java類型                        本地類型                           JNI定義的別名
int                                  long                                    jint/jsize
long                               _int64                                 jlong
byte                               signed char                        jbyte
boolean                         unsigned char                   jboolean
char                               unsigned short                  jchar
short                              short                                  jshort
float                               float                                   jfloat
double                           double                               jdouble
object                            _jobject*                            jobject


(四)jclass的取得
1.爲了能夠在C/C++中使用java類,JNI.h頭文件中專門定義了jclass

類型來表是Java中的class類
2.JNIEnv類中取得jclass的函數:
(1)jclass FindClass(const char* clsName);
FindClass會在classpath系統環境變量下尋找類。傳入完整類名,注

意包與包之間是用'/'而不是'.'來分隔
如:jclass cls_string=env->FindClass("java/lang/String");
(2)jclass GetObjectClass(jobject obj);
(3)jclass GetSuperClass(jclass obj);

 

(五)訪問java類中的屬性與方法
1.JNI在Jni.h頭文件中定義了jfieldID,jmethodID類型來分別代表Java

端的屬性和方法。
2.在訪問或設置java屬性時,需先在本地代碼取得代表Java屬性的

jfieldID;同理java方法亦然
3.獲取ID方法(JNIEnv):
(1)GetFieldID/GetMethodID
GetMethodID也能取得構造函數的jmethodID.創建一個java對象時

可以調用指定的構造方法
如:env->GetMethodID(data_Clazz,"<init>","()V");
(2)GetStaticFieldID/GetStaticMethodID
類似java的Reflect,需要指定類跟屬性/方法名來取得相應的jfieldID

跟jmethodID
(3)sign是什麼
例如TestNative類中有兩個重載方法:
package cn.itcast;
public class TestNative{
    public void function(int i){
        System.out.println("Integer:"+i);
    }
    public void function(double d){
        System.out.println("Double:"+d);
    }
}

然後在C/C++代碼中需要調用其中一個function方法的話···
//首先取得要調用的方法所在的類···
jclass clazz_TestNative=env->FindClass("cn/itcast/TestNative");
//取得jmethodID之後才能進行調用···
jmethodID id_func=env->GetMethodID

(clazz_TestNative,"function","??");
······

但是到底取得是
void function(int i)還是
void function(double d)的jmethodID呢?

這就是sign的作用了,它用於指定要取得的屬性/方法的類型
這裏的sign
如果指定爲"(I)V"則取回void function(int) 的jmethodID
如果指定爲"(D)V"則取回void function(double)的jmethodID

(4)sign簽名
用來表示要取得的屬性/方法的類型
類型                      相應的簽名
boolean                    Z
byte                          B
char                          C
short                         S
int                             I
long                          L
float                          F
double                      D
void                          V
object                      L用/分隔包的完整類名:   Ljava/lang/String;
Array                        [簽名          [I      [Ljava/lang/Object;
Method              (參數1類型簽名 參數2類型簽名···)返回值類型簽名

 

 

(五)使用簽名取得屬性/方法ID的例子
import java.util.Date;
public class Hello{
    public int property;
    public int function(int foo,Date date,int[] arr){
        System.out.println("function");
        return 0;
   }
   public native void test();
}

 

 

//test本地方法的實現:
JNIEXPORT void Java_Hello_test(JNIEnv* env,jobject obj){
    //因爲test不是靜態函數,所以傳進來的就是調用這個函數的對象
    //否則就傳入一個jclass對象表示native()方法所在的類
    jclass hello_clazz=env->GetObjectClass(obj);
    jfieldID filedID_prop=env->GetFieldID

(hello_calzz,"property","I");
    jmethodID methodID_func=env->GetMethodID

(hello_clazz,"function","(I Ljava/util/Date; [I)I");
    env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
}

 

 

(六)使用javap命令來產生簽名
1.javap -s -p [full class Name]
-s 表示輸出簽名信息
-p 同-private,輸出包括private訪問權限的成員信息

(一)本地代碼訪問Java代碼
1.在被調用的C/C++函數中也可以反過來訪問java程序中的類
2.javah工具生成的C/C++函數聲明中,可以看到兩個參數:
JNIEXPORT void JNICALL Java_cn_itcast_sayHello(JNIEnv*

env,jobject obj){
···
}
(二)JNIEnv類型
(1)其實際代表Java環境。通過這個JNIEnv*指針,就可以對Java端

的代碼進行操作。例如,創建Java類的對象,調用Java對象的方法,

獲取Java對象的屬性等等。JNIEnv的指針會被JNI傳入到本地方法的

實現函數中來對Java端的代碼進行操作。


(2)JNIEnv類中常用函數:
NewObject //創建一個java對象
NewString  //創建一個java的String對象
New<TYPE>Array //創建某一個類型的java數組
Get/Set<TYPE>Field  //獲取或設置某一個對象的屬性(需接收參數

GetStatic/SetStatic<TYPE>Field //獲取或設置某一個類的靜態屬性
(需接收表示類的參數)
Call<TYPE>Method  //調用某一類的方法
CallStatic<TYPE>Method  //調用某一個類的靜態方法

 

(三)Java的數據類型在C/C++中的映射關係
Java類型                        本地類型                           JNI定義的別名
int                                  long                                    jint/jsize
long                               _int64                                 jlong
byte                               signed char                        jbyte
boolean                         unsigned char                   jboolean
char                               unsigned short                  jchar
short                              short                                  jshort
float                               float                                   jfloat
double                           double                               jdouble
object                            _jobject*                            jobject


(四)jclass的取得
1.爲了能夠在C/C++中使用java類,JNI.h頭文件中專門定義了jclass

類型來表是Java中的class類
2.JNIEnv類中取得jclass的函數:
(1)jclass FindClass(const char* clsName);
FindClass會在classpath系統環境變量下尋找類。傳入完整類名,注

意包與包之間是用'/'而不是'.'來分隔
如:jclass cls_string=env->FindClass("java/lang/String");
(2)jclass GetObjectClass(jobject obj);
(3)jclass GetSuperClass(jclass obj);

 

(五)訪問java類中的屬性與方法
1.JNI在Jni.h頭文件中定義了jfieldID,jmethodID類型來分別代表Java

端的屬性和方法。
2.在訪問或設置java屬性時,需先在本地代碼取得代表Java屬性的

jfieldID;同理java方法亦然
3.獲取ID方法(JNIEnv):
(1)GetFieldID/GetMethodID
GetMethodID也能取得構造函數的jmethodID.創建一個java對象時

可以調用指定的構造方法
如:env->GetMethodID(data_Clazz,"<init>","()V");
(2)GetStaticFieldID/GetStaticMethodID
類似java的Reflect,需要指定類跟屬性/方法名來取得相應的jfieldID

跟jmethodID
(3)sign是什麼
例如TestNative類中有兩個重載方法:
package cn.itcast;
public class TestNative{
    public void function(int i){
        System.out.println("Integer:"+i);
    }
    public void function(double d){
        System.out.println("Double:"+d);
    }
}

然後在C/C++代碼中需要調用其中一個function方法的話···
//首先取得要調用的方法所在的類···
jclass clazz_TestNative=env->FindClass("cn/itcast/TestNative");
//取得jmethodID之後才能進行調用···
jmethodID id_func=env->GetMethodID

(clazz_TestNative,"function","??");
······

但是到底取得是
void function(int i)還是
void function(double d)的jmethodID呢?

這就是sign的作用了,它用於指定要取得的屬性/方法的類型
這裏的sign
如果指定爲"(I)V"則取回void function(int) 的jmethodID
如果指定爲"(D)V"則取回void function(double)的jmethodID

(4)sign簽名
用來表示要取得的屬性/方法的類型
類型                      相應的簽名
boolean                    Z
byte                          B
char                          C
short                         S
int                             I
long                          L
float                          F
double                      D
void                          V
object                      L用/分隔包的完整類名:   Ljava/lang/String;
Array                        [簽名          [I      [Ljava/lang/Object;
Method              (參數1類型簽名 參數2類型簽名···)返回值類型簽名

 

 

(五)使用簽名取得屬性/方法ID的例子
import java.util.Date;
public class Hello{
    public int property;
    public int function(int foo,Date date,int[] arr){
        System.out.println("function");
        return 0;
   }
   public native void test();
}

 

 

//test本地方法的實現:
JNIEXPORT void Java_Hello_test(JNIEnv* env,jobject obj){
    //因爲test不是靜態函數,所以傳進來的就是調用這個函數的對象
    //否則就傳入一個jclass對象表示native()方法所在的類
    jclass hello_clazz=env->GetObjectClass(obj);
    jfieldID filedID_prop=env->GetFieldID

(hello_calzz,"property","I");
    jmethodID methodID_func=env->GetMethodID

(hello_clazz,"function","(I Ljava/util/Date; [I)I");
    env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
}

 

 

(一)本地代碼訪問Java代碼

(六)使用javap命令來產生簽名
1.javap -s -p [full class Name]
-s 表示輸出簽名信息
-p 同-private,輸出包括private訪問權限的成員信息

1.在被調用的C/C++函數中也可以反過來訪問java程序中的類
2.javah工具生成的C/C++函數聲明中,可以看到兩個參數:
JNIEXPORT void JNICALL Java_cn_itcast_sayHello(JNIEnv*

env,jobject obj){
···
}
(二)JNIEnv類型
(1)其實際代表Java環境。通過這個JNIEnv*指針,就可以對Java端

的代碼進行操作。例如,創建Java類的對象,調用Java對象的方法,

獲取Java對象的屬性等等。JNIEnv的指針會被JNI傳入到本地方法的

實現函數中來對Java端的代碼進行操作。


(2)JNIEnv類中常用函數:
NewObject //創建一個java對象
NewString  //創建一個java的String對象
New<TYPE>Array //創建某一個類型的java數組
Get/Set<TYPE>Field  //獲取或設置某一個對象的屬性(需接收參數

GetStatic/SetStatic<TYPE>Field //獲取或設置某一個類的靜態屬性
(需接收表示類的參數)
Call<TYPE>Method  //調用某一類的方法
CallStatic<TYPE>Method  //調用某一個類的靜態方法

 

(三)Java的數據類型在C/C++中的映射關係
Java類型                        本地類型                           JNI定義的別名
int                                  long                                    jint/jsize
long                               _int64                                 jlong
byte                               signed char                        jbyte
boolean                         unsigned char                   jboolean
char                               unsigned short                  jchar
short                              short                                  jshort
float                               float                                   jfloat
double                           double                               jdouble
object                            _jobject*                            jobject


(四)jclass的取得
1.爲了能夠在C/C++中使用java類,JNI.h頭文件中專門定義了jclass

類型來表是Java中的class類
2.JNIEnv類中取得jclass的函數:
(1)jclass FindClass(const char* clsName);
FindClass會在classpath系統環境變量下尋找類。傳入完整類名,注

意包與包之間是用'/'而不是'.'來分隔
如:jclass cls_string=env->FindClass("java/lang/String");
(2)jclass GetObjectClass(jobject obj);
(3)jclass GetSuperClass(jclass obj);

 

(五)訪問java類中的屬性與方法
1.JNI在Jni.h頭文件中定義了jfieldID,jmethodID類型來分別代表Java

端的屬性和方法。
2.在訪問或設置java屬性時,需先在本地代碼取得代表Java屬性的

jfieldID;同理java方法亦然
3.獲取ID方法(JNIEnv):
(1)GetFieldID/GetMethodID
GetMethodID也能取得構造函數的jmethodID.創建一個java對象時

可以調用指定的構造方法
如:env->GetMethodID(data_Clazz,"<init>","()V");
(2)GetStaticFieldID/GetStaticMethodID
類似java的Reflect,需要指定類跟屬性/方法名來取得相應的jfieldID

跟jmethodID
(3)sign是什麼
例如TestNative類中有兩個重載方法:
package cn.itcast;
public class TestNative{
    public void function(int i){
        System.out.println("Integer:"+i);
    }
    public void function(double d){
        System.out.println("Double:"+d);
    }
}

然後在C/C++代碼中需要調用其中一個function方法的話···
//首先取得要調用的方法所在的類···
jclass clazz_TestNative=env->FindClass("cn/itcast/TestNative");
//取得jmethodID之後才能進行調用···
jmethodID id_func=env->GetMethodID

(clazz_TestNative,"function","??");
······

但是到底取得是
void function(int i)還是
void function(double d)的jmethodID呢?

這就是sign的作用了,它用於指定要取得的屬性/方法的類型
這裏的sign
如果指定爲"(I)V"則取回void function(int) 的jmethodID
如果指定爲"(D)V"則取回void function(double)的jmethodID

(4)sign簽名
用來表示要取得的屬性/方法的類型
類型                      相應的簽名
boolean                    Z
byte                          B
char                          C
short                         S
int                             I
long                          L
float                          F
double                      D
void                          V
object                      L用/分隔包的完整類名:   Ljava/lang/String;
Array                        [簽名          [I      [Ljava/lang/Object;
Method              (參數1類型簽名 參數2類型簽名···)返回值類型簽名

 

 

(五)使用簽名取得屬性/方法ID的例子
import java.util.Date;
public class Hello{
    public int property;
    public int function(int foo,Date date,int[] arr){
        System.out.println("function");
        return 0;
   }
   public native void test();
}

 

 

//test本地方法的實現:
JNIEXPORT void Java_Hello_test(JNIEnv* env,jobject obj){
    //因爲test不是靜態函數,所以傳進來的就是調用這個函數的對象
    //否則就傳入一個jclass對象表示native()方法所在的類
    jclass hello_clazz=env->GetObjectClass(obj);
    jfieldID filedID_prop=env->GetFieldID

(hello_calzz,"property","I");
    jmethodID methodID_func=env->GetMethodID

(hello_clazz,"function","(I Ljava/util/Date; [I)I");
    env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
}

 

 

(一)本地代碼訪問Java代碼

(六)使用javap命令來產生簽名
1.javap -s -p [full class Name]
-s 表示輸出簽名信息
-p 同-private,輸出包括private訪問權限的成員信息

1.在被調用的C/C++函數中也可以反過來訪問java程序中的類
2.javah工具生成的C/C++函數聲明中,可以看到兩個參數:
JNIEXPORT void JNICALL Java_cn_itcast_sayHello(JNIEnv*

env,jobject obj){
···
}
(二)JNIEnv類型
(1)其實際代表Java環境。通過這個JNIEnv*指針,就可以對Java端

的代碼進行操作。例如,創建Java類的對象,調用Java對象的方法,

獲取Java對象的屬性等等。JNIEnv的指針會被JNI傳入到本地方法的

實現函數中來對Java端的代碼進行操作。


(2)JNIEnv類中常用函數:
NewObject //創建一個java對象
NewString  //創建一個java的String對象
New<TYPE>Array //創建某一個類型的java數組
Get/Set<TYPE>Field  //獲取或設置某一個對象的屬性(需接收參數

GetStatic/SetStatic<TYPE>Field //獲取或設置某一個類的靜態屬性
(需接收表示類的參數)
Call<TYPE>Method  //調用某一類的方法
CallStatic<TYPE>Method  //調用某一個類的靜態方法

 

(三)Java的數據類型在C/C++中的映射關係
Java類型                        本地類型                           JNI定義的別名
int                                  long                                    jint/jsize
long                               _int64                                 jlong
byte                               signed char                        jbyte
boolean                         unsigned char                   jboolean
char                               unsigned short                  jchar
short                              short                                  jshort
float                               float                                   jfloat
double                           double                               jdouble
object                            _jobject*                            jobject


(四)jclass的取得
1.爲了能夠在C/C++中使用java類,JNI.h頭文件中專門定義了jclass

類型來表是Java中的class類
2.JNIEnv類中取得jclass的函數:
(1)jclass FindClass(const char* clsName);
FindClass會在classpath系統環境變量下尋找類。傳入完整類名,注

意包與包之間是用'/'而不是'.'來分隔
如:jclass cls_string=env->FindClass("java/lang/String");
(2)jclass GetObjectClass(jobject obj);
(3)jclass GetSuperClass(jclass obj);

 

(五)訪問java類中的屬性與方法
1.JNI在Jni.h頭文件中定義了jfieldID,jmethodID類型來分別代表Java

端的屬性和方法。
2.在訪問或設置java屬性時,需先在本地代碼取得代表Java屬性的

jfieldID;同理java方法亦然
3.獲取ID方法(JNIEnv):
(1)GetFieldID/GetMethodID
GetMethodID也能取得構造函數的jmethodID.創建一個java對象時

可以調用指定的構造方法
如:env->GetMethodID(data_Clazz,"<init>","()V");
(2)GetStaticFieldID/GetStaticMethodID
類似java的Reflect,需要指定類跟屬性/方法名來取得相應的jfieldID

跟jmethodID
(3)sign是什麼
例如TestNative類中有兩個重載方法:
package cn.itcast;
public class TestNative{
    public void function(int i){
        System.out.println("Integer:"+i);
    }
    public void function(double d){
        System.out.println("Double:"+d);
    }
}

然後在C/C++代碼中需要調用其中一個function方法的話···
//首先取得要調用的方法所在的類···
jclass clazz_TestNative=env->FindClass("cn/itcast/TestNative");
//取得jmethodID之後才能進行調用···
jmethodID id_func=env->GetMethodID

(clazz_TestNative,"function","??");
······

但是到底取得是
void function(int i)還是
void function(double d)的jmethodID呢?

這就是sign的作用了,它用於指定要取得的屬性/方法的類型
這裏的sign
如果指定爲"(I)V"則取回void function(int) 的jmethodID
如果指定爲"(D)V"則取回void function(double)的jmethodID

(4)sign簽名
用來表示要取得的屬性/方法的類型
類型                      相應的簽名
boolean                    Z
byte                          B
char                          C
short                         S
int                             I
long                          L
float                          F
double                      D
void                          V
object                      L用/分隔包的完整類名:   Ljava/lang/String;
Array                        [簽名          [I      [Ljava/lang/Object;
Method              (參數1類型簽名 參數2類型簽名···)返回值類型簽名

 

 

(五)使用簽名取得屬性/方法ID的例子
import java.util.Date;
public class Hello{
    public int property;
    public int function(int foo,Date date,int[] arr){
        System.out.println("function");
        return 0;
   }
   public native void test();
}

 

 

//test本地方法的實現:
JNIEXPORT void Java_Hello_test(JNIEnv* env,jobject obj){
    //因爲test不是靜態函數,所以傳進來的就是調用這個函數的對象
    //否則就傳入一個jclass對象表示native()方法所在的類
    jclass hello_clazz=env->GetObjectClass(obj);
    jfieldID filedID_prop=env->GetFieldID

(hello_calzz,"property","I");
    jmethodID methodID_func=env->GetMethodID

(hello_clazz,"function","(I Ljava/util/Date; [I)I");
    env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
}

 

 

(六)使用javap命令來產生簽名
1.javap -s -p [full class Name]
-s 表示輸出簽名信息
-p 同-private,輸出包括private訪問權限的成員信息

(一)本地代碼訪問Java代碼
1.在被調用的C/C++函數中也可以反過來訪問java程序中的類
2.javah工具生成的C/C++函數聲明中,可以看到兩個參數:
JNIEXPORT void JNICALL Java_cn_itcast_sayHello(JNIEnv*

env,jobject obj){
···
}
(二)JNIEnv類型
(1)其實際代表Java環境。通過這個JNIEnv*指針,就可以對Java端

的代碼進行操作。例如,創建Java類的對象,調用Java對象的方法,

獲取Java對象的屬性等等。JNIEnv的指針會被JNI傳入到本地方法的

實現函數中來對Java端的代碼進行操作。


(2)JNIEnv類中常用函數:
NewObject //創建一個java對象
NewString  //創建一個java的String對象
New<TYPE>Array //創建某一個類型的java數組
Get/Set<TYPE>Field  //獲取或設置某一個對象的屬性(需接收參數

GetStatic/SetStatic<TYPE>Field //獲取或設置某一個類的靜態屬性
(需接收表示類的參數)
Call<TYPE>Method  //調用某一類的方法
CallStatic<TYPE>Method  //調用某一個類的靜態方法

 

(三)Java的數據類型在C/C++中的映射關係
Java類型                        本地類型                           JNI定義的別名
int                                  long                                    jint/jsize
long                               _int64                                 jlong
byte                               signed char                        jbyte
boolean                         unsigned char                   jboolean
char                               unsigned short                  jchar
short                              short                                  jshort
float                               float                                   jfloat
double                           double                               jdouble
object                            _jobject*                            jobject


(四)jclass的取得
1.爲了能夠在C/C++中使用java類,JNI.h頭文件中專門定義了jclass

類型來表是Java中的class類
2.JNIEnv類中取得jclass的函數:
(1)jclass FindClass(const char* clsName);
FindClass會在classpath系統環境變量下尋找類。傳入完整類名,注

意包與包之間是用'/'而不是'.'來分隔
如:jclass cls_string=env->FindClass("java/lang/String");
(2)jclass GetObjectClass(jobject obj);
(3)jclass GetSuperClass(jclass obj);

 

(五)訪問java類中的屬性與方法
1.JNI在Jni.h頭文件中定義了jfieldID,jmethodID類型來分別代表Java

端的屬性和方法。
2.在訪問或設置java屬性時,需先在本地代碼取得代表Java屬性的

jfieldID;同理java方法亦然
3.獲取ID方法(JNIEnv):
(1)GetFieldID/GetMethodID
GetMethodID也能取得構造函數的jmethodID.創建一個java對象時

可以調用指定的構造方法
如:env->GetMethodID(data_Clazz,"<init>","()V");
(2)GetStaticFieldID/GetStaticMethodID
類似java的Reflect,需要指定類跟屬性/方法名來取得相應的jfieldID

跟jmethodID
(3)sign是什麼
例如TestNative類中有兩個重載方法:
package cn.itcast;
public class TestNative{
    public void function(int i){
        System.out.println("Integer:"+i);
    }
    public void function(double d){
        System.out.println("Double:"+d);
    }
}

然後在C/C++代碼中需要調用其中一個function方法的話···
//首先取得要調用的方法所在的類···
jclass clazz_TestNative=env->FindClass("cn/itcast/TestNative");
//取得jmethodID之後才能進行調用···
jmethodID id_func=env->GetMethodID

(clazz_TestNative,"function","??");
······

但是到底取得是
void function(int i)還是
void function(double d)的jmethodID呢?

這就是sign的作用了,它用於指定要取得的屬性/方法的類型
這裏的sign
如果指定爲"(I)V"則取回void function(int) 的jmethodID
如果指定爲"(D)V"則取回void function(double)的jmethodID

(4)sign簽名
用來表示要取得的屬性/方法的類型
類型                      相應的簽名
boolean                    Z
byte                          B
char                          C
short                         S
int                             I
long                          L
float                          F
double                      D
void                          V
object                      L用/分隔包的完整類名:   Ljava/lang/String;
Array                        [簽名          [I      [Ljava/lang/Object;
Method              (參數1類型簽名 參數2類型簽名···)返回值類型簽名

 

 

(五)使用簽名取得屬性/方法ID的例子
import java.util.Date;
public class Hello{
    public int property;
    public int function(int foo,Date date,int[] arr){
        System.out.println("function");
        return 0;
   }
   public native void test();
}

 

 

//test本地方法的實現:
JNIEXPORT void Java_Hello_test(JNIEnv* env,jobject obj){
    //因爲test不是靜態函數,所以傳進來的就是調用這個函數的對象
    //否則就傳入一個jclass對象表示native()方法所在的類
    jclass hello_clazz=env->GetObjectClass(obj);
    jfieldID filedID_prop=env->GetFieldID

(hello_calzz,"property","I");
    jmethodID methodID_func=env->GetMethodID

(hello_clazz,"function","(I Ljava/util/Date; [I)I");
    env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
}

 

 

(六)使用javap命令來產生簽名
1.javap -s -p [full class Name]
-s 表示輸出簽名信息
-p 同-private,輸出包括private訪問權限的成員信息

發佈了10 篇原創文章 · 獲贊 3 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章