日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JNI調(diào)用機(jī)制

 云端素館 2015-05-08
 JNI的簡單介紹

Java Native Interface (JNI)是java本地調(diào)用接口,所謂的native就是調(diào)用c/c++的程序。
java調(diào)用C語言的情況一般有三種:
  1. 調(diào)用驅(qū)動(dòng)。由于操作系統(tǒng)提供的驅(qū)動(dòng)一般都是C接口,Java語言并不具備操作這些驅(qū)動(dòng)的能力。
  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在編譯是不會(huì)關(guān)心具體實(shí)現(xiàn),編譯時(shí)就不會(huì)出錯(cuò)。

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

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

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

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

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

生成 .h文件

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

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


C訪問java

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

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

 java訪問c的時(shí)候,把類名,函數(shù)名,參數(shù)類型傳遞給native引擎,然后由native引擎處理C函數(shù),同理,
C調(diào)用java時(shí),也需要把想要訪問的類名、函數(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");
    第一個(gè)參數(shù)是java對象對應(yīng)的類
    第二個(gè)參數(shù)是java中的方法名稱
    第三個(gè)參數(shù)是數(shù)據(jù)類型和返回值
    解釋一下第三個(gè)參數(shù):
    參數(shù)在括弧中,返回值在括弧外, ([Ljava/lang/String;)V" : [Ljava/lang/String代表參數(shù)類型,如果是類包名用
    “/”分開,并且前面加上又給大寫的L。
    java和native數(shù)據(jù)類型對應(yīng)表
    java類型 native類型
    boolean Z
    byte B
    char C
    double D
    float F
    int I
    long L
    Object 'L' + '包名'+';'
    short S
    這個(gè)參數(shù)可以自己手工寫,還是那樣容易出錯(cuò),java提供了一個(gè)工具用來查看參數(shù)簽名,使用javap工具可以自動(dòng)生成,自己從網(wǎng)上查詢一下即可。
  3. 調(diào)用函數(shù)
    env->CallXXXMethod(jobject, mid, ret);

    其中XXX是不同的類型,包括:Void,Oject,Boolean,Byte,Char,Short,Int,Long,Float,Double
    第一個(gè)參數(shù)是調(diào)用的類的對象
    第二個(gè)參數(shù)是上一步獲得的方法的id
    第三個(gè)參數(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中本身無法保存持久對象,把持久對象保存到一個(gè)int類型的變量上,使用的時(shí)候再強(qiáng)制轉(zhuǎn)型成對象。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多