最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析Java中JNI靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)

 更新時(shí)間:2024年12月16日 08:35:28   作者:louisgeek  
這篇文章主要為大家詳細(xì)介紹了Java中JNI靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)的相關(guān)知識(shí),文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

靜態(tài)注冊(cè)是指 Java native 方法和對(duì)應(yīng)的本地函數(shù)按照預(yù)先定義好的命名規(guī)則來(lái)建立關(guān)聯(lián),實(shí)現(xiàn)了 Java native 方法與本地函數(shù)實(shí)現(xiàn)的綁定,這些函數(shù)會(huì)在 Java 類加載時(shí)被靜態(tài)注冊(cè)到 JVM 中,以確保 JVM 能夠正確地找到對(duì)應(yīng)的函數(shù)

動(dòng)態(tài)注冊(cè)是通過(guò)提供一個(gè) Java native 方法和本地函數(shù)一一對(duì)應(yīng)的映射表,然后在 JNI_OnLoad 回調(diào)里將映射表注冊(cè)給 JVM,這樣一來(lái) JVM 就可以用這個(gè)映射表來(lái)調(diào)用相應(yīng)的函數(shù)了,而不必像靜態(tài)注冊(cè)那樣通過(guò)函數(shù)名去查找需要調(diào)用的函數(shù),所以本地函數(shù)名不需要遵循特定命名規(guī)則

PS:在 JNI 中靜態(tài)注冊(cè)和靜態(tài)庫(kù)之間沒(méi)有直接的關(guān)系,無(wú)論是靜態(tài)注冊(cè)還是動(dòng)態(tài)注冊(cè)都可以生成動(dòng)態(tài)庫(kù)(.so文件)或者靜態(tài)庫(kù)(.a 文件)

public class MainActivity extends AppCompatActivity {
    // Used to load the 'myjni' library on application startup.
    static {
        System.loadLibrary("myjni");
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //
        String str = stringFromJNI();
        Log.e("TAG", "onCreate: str="+str);
    }
    /**
     * A native method that is implemented by the 'myjni' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI(); //java native 方法
}

靜態(tài)注冊(cè)

本地函數(shù)的函數(shù)名需要遵循 Java_類全限定名_方法名 的格式(類全限定名中的 . 需要用 _ 替換)命名規(guī)范

extern "C" JNIEXPORT jstring JNICALL
Java_com_louis_myjni_MainActivity_stringFromJNI(
        JNIEnv* env,           //JNIEnv 指的是當(dāng)前 JNI 環(huán)境,利用 JNIEnv 可以操作 java 層代碼
        jobject /* this */) {  //jobject 指的是 JNI 函數(shù)對(duì)應(yīng)的 java native 方法所在類的實(shí)例對(duì)象,如果 native 方法是 static 的話則類型就需要改成 jclass,代表的是類對(duì)象
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

動(dòng)態(tài)注冊(cè)

  • 當(dāng) Java 層調(diào)用 System.loadLibrary 方法時(shí),JNI_OnLoad 函數(shù)會(huì)在庫(kù)被加載到 Java 虛擬機(jī)時(shí)調(diào)用
  • PS:比如 Android 系統(tǒng)的 JNI 函數(shù)和 FFmpeg 相關(guān)函數(shù)和都是使用的動(dòng)態(tài)注冊(cè)
//定義本地函數(shù),函數(shù)名任意
jstring stringFromJNI_JNI_OnLoad(JNIEnv *env, jobject/* this */) {
    std::string hello = "Hello from C++  stringFromJNI_JNI_OnLoad";
    return env->NewStringUTF(hello.c_str());
}

//定義一個(gè) JNINativeMethod 結(jié)構(gòu)體數(shù)組(映射表),結(jié)構(gòu)體包含 Java 方法名、方法簽名(方法描述符)以及對(duì)應(yīng)關(guān)聯(lián)的本地函數(shù)的指針
JNINativeMethod nativeMethods[] = {
    //stringFromJNI 對(duì)應(yīng) Java native 方法,stringFromJNI_JNI_OnLoad 對(duì)應(yīng)本地函數(shù)
    {"stringFromJNI", "()Ljava/lang/String;", (jstring *) stringFromJNI_JNI_OnLoad}
};

//Java 調(diào)用 System.loadLibrary 時(shí)此 JNI_OnLoad 函數(shù)就會(huì)執(zhí)行
//JavaVM *vm 參數(shù)是一個(gè)指向 Java 虛擬機(jī)的指針,通過(guò)這個(gè)指針可以訪問(wèn) JVM 的功能
//void *reserved 是一個(gè)保留參數(shù),通常不使用
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;
    //獲取與當(dāng)前線程關(guān)聯(lián)的 JNI 環(huán)境
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        LOGE("獲取 JNI 環(huán)境失敗");
        return JNI_ERR;
    }
    //通過(guò)類的全限定名來(lái)查找并加載一個(gè)類,返回一個(gè)指向該類的 jclass 引用
    jclass clazz = env->FindClass("com/louis/myjni/MainActivity");
    if (clazz == NULL) {
        LOGE("獲取 jclass 失敗");
        return JNI_ERR;
    }
    //計(jì)算 arr 數(shù)組的長(zhǎng)度 int length = sizeof(arr) / sizeof(arr[0]);
    int nMethods = sizeof(nativeMethods) / sizeof(nativeMethods[0]);
    //參數(shù) nMethods 指定數(shù)組中 NativeMethod 的數(shù)量
    if (env->RegisterNatives(clazz, nativeMethods, nMethods) != JNI_OK) {
        LOGE("注冊(cè)本地函數(shù)失敗");
        return JNI_ERR;
    }
    LOGE("注冊(cè)成功");
    return JNI_VERSION_1_6; //返回當(dāng)前支持的 JNI 版本號(hào)
}

總結(jié)

靜態(tài)注冊(cè)簡(jiǎn)單易用,函數(shù)必須要有類似 JNIEXPORT jstring JNICALL 這樣的相關(guān)聲明,而且函數(shù)名必須要按照 JNI 的命名規(guī)則去命名,由于 JNI 函數(shù)名暴露,所以存在一定的安全隱患

動(dòng)態(tài)注冊(cè)靈活性高,不依賴于固定的命名規(guī)則,不過(guò)需要自行注冊(cè)手動(dòng)關(guān)聯(lián),可以做到在運(yùn)行時(shí)根據(jù)條件選擇不同的實(shí)現(xiàn),更適合復(fù)雜項(xiàng)目

到此這篇關(guān)于淺析Java中JNI靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)的文章就介紹到這了,更多相關(guān)Java JNI靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何在攔截器中獲取url路徑里面@PathVariable的參數(shù)值

    如何在攔截器中獲取url路徑里面@PathVariable的參數(shù)值

    這篇文章主要介紹了如何在攔截器中獲取url路徑里面@PathVariable的參數(shù)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java后臺(tái)處理Json格式數(shù)據(jù)的方法

    Java后臺(tái)處理Json格式數(shù)據(jù)的方法

    這篇文章主要介紹了Java后臺(tái)處理Json格式數(shù)據(jù)的方法的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • IDEA創(chuàng)建Maven工程Servlet的詳細(xì)教程

    IDEA創(chuàng)建Maven工程Servlet的詳細(xì)教程

    這篇文章主要介紹了IDEA創(chuàng)建Maven工程Servlet的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Spring為什么要用三級(jí)緩存解決循環(huán)依賴呢

    Spring為什么要用三級(jí)緩存解決循環(huán)依賴呢

    本文主要介紹了Spring如何使用三級(jí)緩存解決循環(huán)依賴問(wèn)題,本文為了方便說(shuō)明,先設(shè)置兩個(gè)業(yè)務(wù)層對(duì)象,命名為AService和BService,結(jié)合示例給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-01-01
  • Java輸出多位小數(shù)的三種方法(附代碼)

    Java輸出多位小數(shù)的三種方法(附代碼)

    這篇文章主要給大家介紹了關(guān)于Java輸出多位小數(shù)的三種方法的相關(guān)資料,在實(shí)際工作中常常需要設(shè)定數(shù)字的輸出格式,如以百分比的形式輸出,或者設(shè)定小數(shù)位數(shù)等,需要的朋友可以參考下
    2023-07-07
  • MyBatis輸入映射和輸出映射實(shí)例詳解

    MyBatis輸入映射和輸出映射實(shí)例詳解

    mapper.xml是我們配置操作數(shù)據(jù)庫(kù)的sql語(yǔ)句的地方.這篇文章主要介紹了MyBatis輸入映射和輸出映射實(shí)例詳解,需要的朋友可以參考下
    2017-02-02
  • 如何基于sqlite實(shí)現(xiàn)kafka延時(shí)消息詳解

    如何基于sqlite實(shí)現(xiàn)kafka延時(shí)消息詳解

    這篇文章主要給大家介紹了關(guān)于如何基于sqlite實(shí)現(xiàn)kafka延時(shí)消息的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-01-01
  • Java面試題沖刺第一天--基礎(chǔ)篇1

    Java面試題沖刺第一天--基礎(chǔ)篇1

    這篇文章主要為大家分享了最有價(jià)值的三道java面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-07-07
  • MyBatis Generator 自定義生成注釋的方法

    MyBatis Generator 自定義生成注釋的方法

    這篇文章主要介紹了MyBatis Generator 自定義生成注釋的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Java參數(shù)校驗(yàn)@Validated、@Valid介紹及使用詳解

    Java參數(shù)校驗(yàn)@Validated、@Valid介紹及使用詳解

    Javax.validation是?spring?集成自帶的一個(gè)參數(shù)校驗(yàn)接口,可通過(guò)添加注解來(lái)設(shè)置校驗(yàn)條件,這篇文章主要介紹了Java參數(shù)校驗(yàn)@Validated、@Valid介紹及使用詳解,需要的朋友可以參考下
    2024-08-08

最新評(píng)論

贵港市| 万荣县| 湖北省| 宁阳县| 甘德县| 克山县| 贺兰县| 来安县| 全椒县| 塔河县| 五原县| 土默特右旗| 大港区| 城步| 莱阳市| 通许县| 望谟县| 靖西县| 永仁县| 科技| 囊谦县| 新田县| 海口市| 安吉县| 霍邱县| 同心县| 竹山县| 安新县| 呼和浩特市| 卓资县| 奇台县| 栾川县| 霍城县| 阳谷县| 乾安县| 庆城县| 万山特区| 罗源县| 剑川县| 蛟河市| 凤山县|