免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
JNI調(diào)用機(jī)制
 JNI的簡單介紹

Java Native Interface (JNI)是java本地調(diào)用接口,所謂的native就是調(diào)用c/c++的程序。
java調(diào)用C語言的情況一般有三種:
  1. 調(diào)用驅(qū)動。由于操作系統(tǒng)提供的驅(qū)動一般都是C接口,Java語言并不具備操作這些驅(qū)動的能力。
  2. 對于計(jì)算量比較大,處理數(shù)據(jù)比較多的模塊,java的效率沒有C高,所以希望用C去完成。
  3. 對于某些功能模塊,可能Java和C的效率差不多,但是C已經(jīng)寫好了,就不想用Java重寫了。
從程序的角度來說,主要關(guān)注兩種情況:
  • java訪問C
  • C訪問java
對于理解JNI的調(diào)用實(shí)現(xiàn),對于理解Android的源碼有幫助,因?yàn)锳ndroid系統(tǒng)中大量的使用了JIN。

Java訪問C

    任何語言直接的交互都必須遵循一定的規(guī)則或者協(xié)議,只有這樣雙方才能理解各自的意圖。
java中定義native函數(shù),對于native函數(shù)只需要聲明,具體實(shí)現(xiàn)由C去實(shí)現(xiàn)。也就是說,native函數(shù)的
實(shí)現(xiàn)與聲明是分離的,java負(fù)責(zé)聲明,C負(fù)責(zé)實(shí)現(xiàn)。所以java在編譯是不會關(guān)心具體實(shí)現(xiàn),編譯時就不會出錯。

    如何調(diào)用的呢?在調(diào)用之前java是不會關(guān)心是否已經(jīng)實(shí)現(xiàn),只有在調(diào)用native方法的時候,去找C生成的動態(tài)庫,如果
找不到動態(tài)庫,那么native方法就會報(bào)錯。

   java如何找到C的函數(shù)的呢?

    java的native函數(shù)和C中的函數(shù)存在一種映射關(guān)系,這個映射關(guān)系就是遵循的一種協(xié)議或者稱為規(guī)則。
    比如,F(xiàn)ramework中AssetManager類中聲明了:
    
    private native final void init()

    該方法在C中對應(yīng)的是:
   static void android_content_AssetManager_init(JNIEnv* env, jobject clazz)

   從上面的對應(yīng)關(guān)系可以看出,在C中的規(guī)則就是,包名+類名+方法名,并且中間用下劃線分割
   第一個參數(shù)env,是JNIEnv對象,該對象代表一個Java虛擬機(jī)所運(yùn)行的環(huán)境,通過它可以訪問JVM內(nèi)部的各種對象;
    第二個參數(shù)jobject和是調(diào)用該函數(shù)的對象,上面的例子指的就是AssetManager對象;每個這樣的C函數(shù)的參數(shù)至少
    有這兩個參數(shù),如果native函數(shù)里有多個參數(shù),依次在后面排列,java的數(shù)據(jù)類型和JNI中的數(shù)據(jù)類型對應(yīng)關(guān)系,
自己可以去網(wǎng)上查詢一下。

   當(dāng)java調(diào)用native函數(shù)時,編譯器會向native引擎?zhèn)鬟f調(diào)用者的包名,函數(shù)名及參數(shù)類型,native引擎
根據(jù)這些信息決定應(yīng)該調(diào)用具體的的哪個函數(shù)。

在android中,native引擎中的AndroidRuntime類提供了一個registerNativeMethods()函數(shù),通過此函數(shù)
定義java方法和C函數(shù)的映射關(guān)系。

生成 .h文件

java 的native方法和JNI中的c中的函數(shù)的對應(yīng)的定義文件頭文件(.h文件)可以手工寫,有些麻煩
并且還容易出錯,java提供了一個javah工具,通過該工具可以從一個java文件自動生成相應(yīng)的
投文件,網(wǎng)上查詢一下具體用法。
    
接下來就是根據(jù)頭文件去實(shí)現(xiàn)相應(yīng)的C代碼,然后生成動態(tài)庫

如果想在java中調(diào)用native方法,需要使用在調(diào)用的代碼前面使用System.loadLibrary("lib_name")
裝載該動態(tài)庫


C訪問java

  雖然C訪問java的情況不多見,不過也是能遇到的。

 由于java中的函數(shù)在native引擎中并沒有直接的函數(shù)指針,java函數(shù)只能由java引擎去執(zhí)行,而不是C。所以訪問
java不能通過指針,只能通過參數(shù)接口。

 java訪問c的時候,把類名,函數(shù)名,參數(shù)類型傳遞給native引擎,然后由native引擎處理C函數(shù),同理,
C調(diào)用java時,也需要把想要訪問的類名、函數(shù)名、參數(shù)傳遞給java引擎。

按照如下步驟:

  1. 獲取java對象的類
    jclass cls = env->GetObjectclass(jobject);
    jobject就是需要調(diào)用的誰的方法,java對象在JNI中的表示。
  2. 獲得java方法的Id值
    jmethodId mid = env->GetMethodId(cls, "method_name", "([Ljava/lang/String;)V");
    第一個參數(shù)是java對象對應(yīng)的類
    第二個參數(shù)是java中的方法名稱
    第三個參數(shù)是數(shù)據(jù)類型和返回值
    解釋一下第三個參數(shù):
    參數(shù)在括弧中,返回值在括弧外, ([Ljava/lang/String;)V" : [Ljava/lang/String代表參數(shù)類型,如果是類包名用
    “/”分開,并且前面加上又給大寫的L。
    java和native數(shù)據(jù)類型對應(yīng)表
    java類型native類型
    booleanZ
    byteB
    charC
    doubleD
    floatF
    intI
    longL
    Object'L' + '包名'+';'
    shortS
    這個參數(shù)可以自己手工寫,還是那樣容易出錯,java提供了一個工具用來查看參數(shù)簽名,使用javap工具可以自動生成,自己從網(wǎng)上查詢一下即可。
  3. 調(diào)用函數(shù)
    env->CallXXXMethod(jobject, mid, ret);

    其中XXX是不同的類型,包括:Void,Oject,Boolean,Byte,Char,Short,Int,Long,Float,Double
    第一個參數(shù)是調(diào)用的類的對象
    第二個參數(shù)是上一步獲得的方法的id
    第三個參數(shù)數(shù)是返回值
上面是調(diào)用方法,調(diào)用java的變量也類似:

  1. 獲取java對象的類
    jclass cls = env->GetObjectclass(jobject);
  2. 獲得變量的id
    jfiledId fid = env->GetFiledId(cls, "fileName", "I");
  3. 獲取變量值
    value = env->GetXXXField(env, jobject, fid);

在C中使用持久對象和保持持久對象

 C中本身無法保存持久對象,把持久對象保存到一個int類型的變量上,使用的時候再強(qiáng)制轉(zhuǎn)型成對象。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JNI 對象在函數(shù)調(diào)用中的生命周期
Android 基于NDK的JNI開發(fā) C調(diào)用java和java調(diào)用C
AndroidJNI基礎(chǔ)篇(一)
JNI技術(shù)與Android應(yīng)用(0)
[深入理解Android卷一 全文
安卓JNI精細(xì)化講解,讓你徹底了解JNI(二):用法解析
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服