<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JNI:本地代碼調(diào)用Java代碼

          共 2063字,需瀏覽 5分鐘

           ·

          2022-03-04 01:00

          1. 本地代碼訪問(wèn)Java代碼

          • 在被調(diào)用的C/C++函數(shù)中也可以反過(guò)來(lái)訪問(wèn)Java程序中的方法

          • javah 工具生成的C/C++函數(shù)聲明中,可以看到有兩個(gè)參數(shù):

          JNIEXPORT void JNICALL Java_com_omg_NativeLib_sayHello (JNIEnv *env, jobject jobj){     cout << "hello world" << endl;}

          2. JNIEnv 類型

          • JNIENV類型實(shí)際上代表了Java環(huán)境,通過(guò)這個(gè)JNIEnv*指針,就可以對(duì)Java端的代碼進(jìn)行操作。例如,創(chuàng)建Java類的對(duì)象、調(diào)用Java對(duì)象的方法、獲取Java對(duì)象的屬性等。JNIEnv的指針會(huì)被JNI傳入到本地方法的實(shí)現(xiàn)函數(shù)中來(lái)對(duì)Java端的代碼進(jìn)行操作。

          • JNIEnv類中有很多函數(shù)可以使用

          NewObject / NewString / NewArrayGetField / SetFieldGetStaticField / SetStaticFieldCallMethod / CallStaticMethod

          等許許多多的函數(shù)

          • jobject 什么的一個(gè)類型呢?

          不是靜態(tài)方式時(shí),傳入的是當(dāng)前關(guān)聯(lián)的類對(duì)象

          靜態(tài)方法時(shí),傳入當(dāng)前類的Class對(duì)象

          3. Java的類型在C/C++中的映射關(guān)系

          Java類型本地類型JNI定義的別名
          intlongjint / jsize
          long__int64jlong
          bytesigned charjbyte
          booleanunsigned charjboolean
          charunsigned shortjchar
          shortshortjshort
          floatfloatjfloat
          doubledoublejdouble
          Object_jobject*jobject

          4. jclass如何獲取

          • 為了能夠在C/C++中使用Java類。JNI.h頭文件中,專門(mén)定義了jclass類型來(lái)表示Java中的Class類

          • JNIEnv類中有以下幾個(gè)函數(shù)可以獲取jclass:

          jclass FindClass(const char* clsName);jclass GetObjectClass(jobject ojb);jclass GetSuperClass(jclass obj);

          在Java JDK中也有這幾個(gè)方法

          • FindClass 將會(huì)在classpath環(huán)境變量下尋找類。傳入完整類名,注意包與包之間是使用 ?“/ “ ,而不是使用 “.“ 來(lái)分隔

          jclass cls_str = env->FindClass("java/lang/String");

          5. 訪問(wèn)Java類中的屬性與方法

          • 在C/C++本地代碼中訪問(wèn)Java端的代碼,一個(gè)常見(jiàn)的場(chǎng)景就是獲取類的屬性和調(diào)用類的方法。為了在C/C++中表示屬性和方法,JNI在jni.h頭文件中定義了jfieldID和jmethdID類型來(lái)分別代表Java端的屬性和方法

          • 在訪問(wèn),或者設(shè)置Java屬性的時(shí)候,首先就要先在本地代碼中獲得代表Java屬性的jfieldID;然后才能在本地代碼中進(jìn)行Java的屬性操作。同樣的,在需要調(diào)用Java的方法時(shí),也是需要先獲取到代表該方法的jmethodID才能進(jìn)行Java方法調(diào)用

          使用JNIEnv的

          GetFieldID / GetMethodIDGetStaticFieldID / GetStaticMethodID

          來(lái)取得相應(yīng)的jfieldID和jmethodID

          來(lái)看下方法定義

          jfieldID GetFieldID(jclass clazz, const char *name, const char *sig);
          jmethodID GetMethodID(jclass clazz, const char *name, const char *sig);
          jfieldID GetStaticFieldID(jclass clazz, const char *name, const char *sig);
          jmethodID GetStaticMethodID(jclass clazz, const char *name, const char *sig);
          • GetMethodID也能夠獲得構(gòu)造函數(shù)的jmethodID。創(chuàng)建一個(gè)Java對(duì)象時(shí)可以調(diào)用指定的構(gòu)造方法,這個(gè)將在后面向大家介紹

          如:env -> GetMethodID(data_Clazz, "", "()V");

          • 類似Java的發(fā)射(Reflect),需要指定類跟屬性/方法名來(lái)獲取相應(yīng)的jfieldID或者jmethodID。而sign又是什么呢?

          6. Sign是什么?

          例如:TestNative類中有兩個(gè)重載的方法

          package com.omg;
          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++代碼中調(diào)用其中的一個(gè)function方法的話;

          //首先取得要調(diào)用的方法所在的類jclass clazz_TestNative = env->FindClass("com/omg/TestNative");//獲取jmethodID之后才能進(jìn)行調(diào)用jmethodID id_func = env->GetMethodID(clazz_TestNative, "function", ??);

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

          這就是sign的作用了,他用于指定要取得的屬性/方法的類型。

          這里的sign如果指定為"(I)V",則獲得的是 void function(int i) 方法的jmethodID;如果指定為"(D)V",則獲得的是 void function(double d) 方法的jmethodID

          7. sign簽名

          用來(lái)表示要取得的屬性/方法的類型

          類型簽名
          booleanZ
          byteB
          charC
          shortS
          intI
          longL
          floatF
          doubleD
          voidV
          objectL + 用/分隔包的完整類名 + ;
          Array[ + 簽名 ? 例如,[I、[Ljava/lang/String;
          Method(參數(shù)1類型簽名 參數(shù)2類型簽名...)返回值類型簽名

          8. 使用簽名獲得屬性/方法ID的例子(復(fù)雜)

          import java.util.Date;
          public class HelloNative(){
          public int property;
          public int function(int foo, Date date, int[] arr){ System.out.println("function"); }
          public native void test();}

          test本地方法的實(shí)現(xiàn)

          JNIEXPORT void Java_Hello_test(JNIEnv* env, jboject ojb) {   //因?yàn)閠est不是靜態(tài)函數(shù),所以傳進(jìn)來(lái)的就是調(diào)用這個(gè)函數(shù)的對(duì)象   jclass hello_clazz = env->GetObjectClass(obj);   jfieldID filedID_prop = env->GetFieldID(hello_clazz, "property", "I");   jmethodID methodID_func = env->GetMethodID("hello_clazz", "function", "(ILjava/util/Date;[I)I");   env->CallIntMethod(obj, methodID_func, 0L, NULL, NULL); //invoke}

          取得的property是int類型的,所以在簽名中傳入"I"

          取得function的ID時(shí)

          所以在最后得到(ILjava/util/Date;[I)I

          9. 使用javap命令來(lái)產(chǎn)生簽名

          • JDK提供了一個(gè)工具來(lái)查看一個(gè)類的申請(qǐng),其中就可以設(shè)置輸出每一個(gè)方法/屬性的簽名

          • java -s -p [full Calss Name]

          -s 表示輸出簽名信息

          -p 通-private,輸出包括private訪問(wèn)權(quán)限的成員信息

          分享&在看

          瀏覽 50
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  美女黄色毛片 | 成人A级视频 | 白虎逼操逼 | 国产精品传媒秘 麻豆Hd | 大香蕉伊人综合 |