一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 詳解Java 本地接口 JNI 使用方法

詳解Java 本地接口 JNI 使用方法

2020-12-30 10:59攻城獅--晴明 Java教程

這篇文章主要介紹了詳解Java 本地接口 JNI 使用方法的相關(guān)資料,希望通過本文大家能徹底使用JNI編程,需要的朋友可以參考下

詳解java 本地接口 jni 使用方法

對于java程序員來說,java語言的好處和優(yōu)點,我想不用我說了,大家自然會說出很多一套套的。但雖然我們作為java程序員,但我們不得不承認java語言也有一些它本身的缺點。比如在性能、和底層打交道方面都有它的缺點。所以java就提供了一些本地接口,他主要的作用就是提供一個標(biāo)準的方式讓java程序通過虛擬機與原生代碼進行交互,這也就是我們平常常說的java本地接口(jni——java native interface)。它使得在 java 虛擬機 (vm) 內(nèi)部運行的 java 代碼能夠與用其它編程語言(如 c、c++ 和匯編語言)編寫的應(yīng)用程序和庫進行互操作。jni 最重要的好處是它沒有對底層 java 虛擬機的實現(xiàn)施加任何限制。因此,java虛擬機廠商可以在不影響虛擬機其它部分的情況下添加對 jni 的支持。程序員只需編寫一種版本的本地應(yīng)用程序或庫,就能夠與所有支持 jni 的 java 虛擬機協(xié)同工作。我們來看一下為什么要與原生代碼進行交互:

一:提高應(yīng)用程序性能。我們知道java對于c/c++、匯編語言來說,顯得比較“高級”。其實這里的高級就是簡化了程序員的工作。很多底層的東西都讓java虛擬機做了。但畢竟相對于直接訪問底層來講,java多了一步虛擬機的過程,所以在性能上比著這些原生語言稍微有點慢。

二:實現(xiàn)一些與底層相關(guān)的功能。java平臺提供的標(biāo)準類庫,還有強大的api,雖然能完成大部分功能。但有些和底層硬件打交道的功能在java api提供的類庫中還是無法完成。

三:與已有的使用原生代碼編寫的程序進行集成。在于操作系統(tǒng)上由c或者c++等原生語言編寫的軟件進行集 0成的時候,可以用jni。

jni 接口函數(shù)和指針

     平臺相關(guān)代碼是通過調(diào)用 jni 函數(shù)來訪問 java 虛擬機功能的。jni 函數(shù)可通過接口指針來獲得。接口指針是指針的指針,它指向一個指針數(shù)組,而指針數(shù)組中的每個元素又指向一個接口函數(shù)。每個接口函數(shù)都處在數(shù)組的某個預(yù)定偏移量中。下圖說明了接口指針的組織結(jié)構(gòu)。

                   詳解Java 本地接口 JNI 使用方法

           jni 接口的組織類似于 c++ 虛擬函數(shù)表或 com 接口。使用接口表而不使用硬性編入的函數(shù)表的好處是使 jni 名字空間與平臺相關(guān)代碼分開。虛擬機可以很容易地提供多個版本的 jni 函數(shù)表。例如,虛擬機可支持以下兩個 jni 函數(shù)表:

· 一個表對非法參數(shù)進行全面檢查,適用于調(diào)試程序;

· 另一個表只進行 jni 規(guī)范所要求的最小程度的檢查,因此效率較高。

jni 接口指針只在當(dāng)前線程中有效。因此,本地方法不能將接口指針從一個線程傳遞到另一個線程中。實現(xiàn) jni 的虛擬機可將本地線程的數(shù)據(jù)分配和儲存在 jni 接口指針?biāo)赶虻膮^(qū)域中。

本地方法將jni 接口指針當(dāng)作參數(shù)來接受。虛擬機在從相同的 java 線程中對本地方法進行多次調(diào)用時,保證傳遞給該本地方法的接口指針是相同的。但是,一個本地方法可被不同的 java 線程所調(diào)用,因此可以接受不同的 jni 接口指針。                     

詳解Java 本地接口 JNI 使用方法

(1)編寫java類代碼

    其中,需要jni實現(xiàn)的方法應(yīng)當(dāng)用native關(guān)鍵字聲明。在該類中,用system.1oadlibrary()方法加載需要的動態(tài)鏈接庫。關(guān)鍵代碼如下:  

?
1
2
3
4
5
6
7
//compute.java
public class compute{
public native double sqrt(double params);
static{
//調(diào)用動態(tài)鏈接庫
system.loadlibrary(“compute”);
}

  (2)編譯成字節(jié)代碼

    在這個過程中,由于采用了native關(guān)鍵字聲明,java編譯器會忽視沒有代碼體的jni方法部分。   

 (3)生成相關(guān)jni方法的頭文件

    這個過程的實現(xiàn)一般是通過利用jlavah-jni  * class生成的(-jni可以省略),也可以手工生成該文件;但是由于 java 虛擬機是根據(jù)一定的命名規(guī)范完成對jni方法的調(diào)用,所以手工編寫頭文件需要特別小心。

    上述文件產(chǎn)生的頭文件部分代碼如下: 

?
1
2
3
//compute.h
extern“c”{
jniexport jdoublejnicall java_compute_comp(jni-env *, jobject, jdoublearray);

    jni函數(shù)名稱分為三部分:首先是java關(guān)鍵字,供java虛擬機識別;然后是調(diào)用者類名稱(全限定的類名,其中用下劃線代替名稱分隔符);最后是對應(yīng)的方法名稱,各段名稱之間用下劃線分割。

    jni函數(shù)的參數(shù)也由三部分組成:首先是jnienv *,是一個指向jni運行環(huán)境的指針;第二個參數(shù)隨本地方法是靜態(tài)還是非靜態(tài)而有所不同一一非靜態(tài)本地方法的第二個參數(shù)是對對象的引用,而靜態(tài)本地方法的第二個參數(shù)是對其java類的引用;其余的參數(shù)對應(yīng)通常java方法的參數(shù),參數(shù)類型需要根據(jù)一定規(guī)則進行映射。

    (4)編寫相應(yīng)方法的實現(xiàn)代碼

    在編碼過程中,需要注意變量的長度問題,例如java的整型變量長度為32位,而c語言為16位,所以要仔細核對變量類型映射表,防止在傳值過程中出現(xiàn)問題。

    (5)將jni實現(xiàn)代碼編譯成動態(tài)鏈接庫

    編譯過程是利用c/c++編譯器實現(xiàn)的,在windows平臺上,編譯和連接的結(jié)果是動態(tài)鏈接庫dll文件。當(dāng)要使用生成的動態(tài)鏈接庫時,調(diào)用者類中需要顯式調(diào)用該鏈接庫dll文件。

    經(jīng)過上述處理,基本上完成了一個包含本地化方法的java類的開發(fā)。

附錄:將jav類型映射到本地 c 類型

 

 基本類型和本地等效類型

java 類型

本地類型

說明

boolean

jboolean

無符號,8 位

byte

jbyte

無符號,8 位

char

jchar

無符號,16 位

short

jshort

有符號,16 位

int

jint

有符號,32 位

long

jlong

有符號,64 位

float

jfloat

32 位

double

jdouble

64 位

void

void

n/a

 

為了使用方便,特提供以下定義。

?
1
2
#define jni_false 0
#define jni_true 1

jsize 整數(shù)類型用于描述主要指數(shù)和大小:

?
1
typedef jint jsize;

故障排除

當(dāng)使用 jni 從 java 程序訪問本機代碼時,您會遇到許多問題。您會遇到的三個最常見的錯誤是:

1)無法找到動態(tài)鏈接。它所產(chǎn)生的錯誤消息是:java.lang.unsatisfiedlinkerror。這通常指無法找到共享庫,或者無法找到共享庫內(nèi)特定的本機方法。

2)無法找到共享庫文件。當(dāng)用 system.loadlibrary(string libname) 方法(參數(shù)是文件名)裝入庫文件時,請確保文件名拼寫正確以及沒有指定擴展名。還有,確保庫文件的位置在類路徑中,從而確保 jvm 可以訪問該庫文件。

3)無法找到具有指定說明的方法。確保您的 c/c++ 函數(shù)實現(xiàn)擁有與頭文件中的函數(shù)說明相同的說明。

結(jié)束語

            從 java 調(diào)用 c 或 c++ 本機代碼(雖然不簡單)是 java 平臺中一種良好集成的功能。雖然 jni 支持 c 和 c++,但 c++ 接口更清晰一些并且通常比 c 接口更可取。正如您已經(jīng)看到的,調(diào)用 c 或 c++ 本機代碼需要賦予函數(shù)特殊的名稱,并創(chuàng)建共享庫文件。當(dāng)利用現(xiàn)有代碼庫時,更改代碼通常是不可取的。要避免這一點,在 c++ 中,通常創(chuàng)建代理代碼或代理類,它們有專門的 jni 所需的命名函數(shù)。然后,這些函數(shù)可以調(diào)用底層庫函數(shù),這些庫函數(shù)的說明和實現(xiàn)保持不變。

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

原文鏈接:http://blog.csdn.net/qq_37267015/article/details/77303382

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本h乱淫动漫在线观看 | 欧美在线观看视频一区 | 欧美高清在线不卡免费观看 | 美女脱了内裤打开腿让男人图片 | 色综合视频一区二区观看 | 蜜柚精彩在线观看 | 3d动漫免费 | 日韩成本大片35分钟免费播放 | 日本福利片国产午夜久久 | 国产精品视频久久久久 | 国产chinese男同gay | 欧美精品亚洲精品日韩专区va | 日本成熟| 毛片网站观看 | 亚洲精品www久久久久久久软件 | 国产免费大片 | 王晶三级作品 | 久久精品午夜一区二区福利 | 精品一成人岛国片在线观看 | 亚洲精品在线免费观看视频 | 久久久GOGO无码啪啪艺术 | 久久国产乱子伦精品免费不卡 | 欧美四虎影院 | 我要色色网 | 亚洲国产99999在线精品一区 | 九九大香尹人视频免费 | 国产清纯白嫩大学生正在播放 | 欧美男同videos | 国产精品对白刺激久久久 | 日韩视频一| 特黄特色大片免费视频播放 | 天堂在线中文字幕 | 男生同性啪视频在线观看 | 成人影院免费在线观看 | 视频免费视频观看网站 | 草莓视频网站18勿进 | 青青青视频免费观看 | 国产盗摄女厕美女嘘嘘 | 欧美yw193.c㎝在线观看 | 精品视频网站 | 国产成人精品高清不卡在线 |