欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析Java中JNI靜態(tài)注冊和動態(tài)注冊

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

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

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

PS:在 JNI 中靜態(tài)注冊和靜態(tài)庫之間沒有直接的關(guān)系,無論是靜態(tài)注冊還是動態(tài)注冊都可以生成動態(tài)庫(.so文件)或者靜態(tài)庫(.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)注冊

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

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

動態(tài)注冊

  • 當 Java 層調(diào)用 System.loadLibrary 方法時,JNI_OnLoad 函數(shù)會在庫被加載到 Java 虛擬機時調(diào)用
  • PS:比如 Android 系統(tǒng)的 JNI 函數(shù)和 FFmpeg 相關(guān)函數(shù)和都是使用的動態(tài)注冊
//定義本地函數(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());
}

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

//Java 調(diào)用 System.loadLibrary 時此 JNI_OnLoad 函數(shù)就會執(zhí)行
//JavaVM *vm 參數(shù)是一個指向 Java 虛擬機的指針,通過這個指針可以訪問 JVM 的功能
//void *reserved 是一個保留參數(shù),通常不使用
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;
    //獲取與當前線程關(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;
    }
    //通過類的全限定名來查找并加載一個類,返回一個指向該類的 jclass 引用
    jclass clazz = env->FindClass("com/louis/myjni/MainActivity");
    if (clazz == NULL) {
        LOGE("獲取 jclass 失敗");
        return JNI_ERR;
    }
    //計算 arr 數(shù)組的長度 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("注冊本地函數(shù)失敗");
        return JNI_ERR;
    }
    LOGE("注冊成功");
    return JNI_VERSION_1_6; //返回當前支持的 JNI 版本號
}

總結(jié)

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

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

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

相關(guān)文章

  • Java語法之 Java 的多態(tài)、抽象類和接口

    Java語法之 Java 的多態(tài)、抽象類和接口

    上節(jié)介紹了 Java 基礎(chǔ)語法之解析 Java 的包和繼承,如果這類知識有點疑惑的小伙伴,可以去 Java 的包和繼承 這章看看,或許可以幫你解決一些疑惑喲!今天這篇文章我們將講解的是 Java 的多態(tài)、抽象類和接口,感興趣的小伙伴可以參考下面文章的具體內(nèi)容
    2021-09-09
  • Java?synchronized同步關(guān)鍵字工作原理

    Java?synchronized同步關(guān)鍵字工作原理

    synchronized作為Java程序員最常用同步工具,很多人卻對它的用法和實現(xiàn)原理一知半解,以至于還有不少人認為synchronized是重量級鎖,性能較差,盡量少用。但不可否認的是synchronized依然是并發(fā)首選工具,本文就來詳細講講
    2023-02-02
  • kafka內(nèi)外網(wǎng)訪問配置方式

    kafka內(nèi)外網(wǎng)訪問配置方式

    這篇文章主要介紹了kafka內(nèi)外網(wǎng)訪問配置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • java 正則,object中兩個方法的使用(詳解)

    java 正則,object中兩個方法的使用(詳解)

    下面小編就為大家?guī)硪黄猨ava 正則,object中兩個方法的使用(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • spring?IOC容器的Bean管理XML自動裝配過程

    spring?IOC容器的Bean管理XML自動裝配過程

    這篇文章主要為大家介紹了spring?IOC容器Bean管理基于XML的自動裝配過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • java實現(xiàn)上傳文件到服務(wù)器和客戶端

    java實現(xiàn)上傳文件到服務(wù)器和客戶端

    這篇文章主要為大家詳細介紹了java實現(xiàn)上傳文件到服務(wù)器和客戶端,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Java Red5服務(wù)器實現(xiàn)流媒體視頻播放

    Java Red5服務(wù)器實現(xiàn)流媒體視頻播放

    這篇文章主要介紹了Java Red5服務(wù)器實現(xiàn)流媒體視頻播放,對視頻播放感興趣的同學,可以參考下
    2021-04-04
  • Spring中Bean掃描原理詳情

    Spring中Bean掃描原理詳情

    這篇文章主要介紹了Spring中Bean掃描原理詳情,文章為榮啊主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • Mybatis?resultMap標簽繼承、復(fù)用、嵌套方式

    Mybatis?resultMap標簽繼承、復(fù)用、嵌套方式

    這篇文章主要介紹了Mybatis?resultMap標簽繼承、復(fù)用、嵌套方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java教學筆記之對象的創(chuàng)建與銷毀

    java教學筆記之對象的創(chuàng)建與銷毀

    面向?qū)ο蟮木幊陶Z言使程序能夠直觀的反應(yīng)客觀世界的本來面目,并且使軟件開發(fā)人員能夠運用人類認識事物所采用的一般思維方法進行軟件開發(fā),是當今計算機領(lǐng)域中軟件開發(fā)和應(yīng)用的主流技術(shù)。
    2016-01-01

最新評論