日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java jni 原理_JNI的实现原理

發(fā)布時間:2025/3/12 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java jni 原理_JNI的实现原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

Java虛擬機訪問本機代碼通過調(diào)用JNI的功能特性。JNI的功能都可以通過一個接口指針。一個接口指針是一個指向指針的指針。這個指針指向一個一個指針數(shù)組,這個數(shù)組中的每一個成員指向一個函數(shù)入口。每個接口的功能是在一個預定義的內(nèi)部數(shù)組的偏移量。

圖一、JNI接口函數(shù)和指針

JNI接口的組織像C++虛函數(shù)列表或COM接口一樣。使用接口列表的好處是JNI名字空間與本地代碼分離開來。

JNI接口指針只在當前線程有效。因此,一個本地方法不能從一個線程通過該接口指針指向另一個線程。

本地方法像參數(shù)一樣接收JNI接口指針。當在同一個線程中有多個調(diào)用本地方法,VM保證相同的接口指針傳遞到這個本地方法。然而,本地方法可以被不同的Java線程調(diào)用,因此可能會收到不同的JNI接口指針。

加載和鏈接本機方法

本地方法裝載的是System.loadLibrary方法。在下面的例子中,類的初始化方法加載一個特定平臺的本地庫中的本地方法f定義如下:

package

pkg;

class

Cls {

native

double f(int i, String s);

static

{

System.loadLibrary(“pkg_Cls”);

}

}

System.loadLibrary中的參數(shù)是一個庫名,它是由程序員任意選擇的。該系統(tǒng)遵循一個標準:把庫名轉(zhuǎn)換為本地庫名的方法,但這是與平臺相關(guān)的。例如,Solaris系統(tǒng)把pkg_Cls轉(zhuǎn)換為libpkg_Cls.so,而Win32系統(tǒng)則轉(zhuǎn)換為pkg_Cls.dll。

程序員可以使用一個單一的庫來存儲所有的任何類需要的本地方法,只要這些類能夠被同一類加載器加載。虛擬機內(nèi)部會為每個類加載器維護一個加載本地庫的的列表。

虛擬機會檢查與本地庫匹配的方法名。虛擬機會首先查找短名稱,即沒有參數(shù)的名稱簽名。然后,再查找長名稱,即帶參數(shù)簽名的名稱。程序員只有當一個本地方法與另一本機方法重載時才需要使用長名稱。

在下面的例子中,本地方法g不必須連接使用長名稱,因為其另一個方法g不是一個本地方法,因此也沒有在本地庫。

class

Cls1 {

int

g(int i);

native

int g(double d);

}

本機方法的參數(shù)

JNI接口指針是本地方法的第一個參數(shù)。在JNI接口指針的類型是JNIEnv。第二個參數(shù)不同,這取決于本地方法是靜態(tài)的還是非靜態(tài)的。第二個參數(shù)為一個非靜態(tài)本地方法時是對對象的引用。第二個參數(shù)為靜態(tài)本地方法是對的Java類的引用。

其余的參數(shù)對應于常規(guī)的Java方法的參數(shù)。本機方法通過返回值調(diào)用傳遞它的結(jié)果返回到調(diào)用例程。

下面代碼舉例說明了使用C函數(shù)來實現(xiàn)f本地方法時,本地方法f聲明如下:

package

pkg;

class

Cls {

native

double f(int i, String s);

...

}

Java對象引用

像整數(shù),字符,等等這些原始類型,都在Java與本機代碼之間復制。另外,任意Java對象,是通過引用傳遞。虛擬機必須跟蹤所有已傳遞到本地代碼的對象,使這些對象不會被垃圾收集器釋放。相反,本地代碼必須有一種機制來通知虛擬機什么時候不再需要使用這些對象了。此外,垃圾收集器必須能夠搬運對象所指的本機代碼。

全局和局部引用

JNI把本地代碼使用的相關(guān)對象分為兩在范疇:局部和全局引用。局部引用的有效期為一個本地方法調(diào)用的時間,并自動機方法返回后獲釋。全球引用仍然有效,直到它們被明確釋放。

所有的Java的JNI函數(shù)返回的對象都是局部引用。JNI允許程序員通過局部引用來創(chuàng)建全局引用。

局部引用只有在線程中被建立時才有效,并只在該線程中有效。本地代碼不能在線程之間調(diào)用局部引用。

訪問字段和方法

JNI允許本地代碼訪問字段和調(diào)用Java對象的方法。JNI通過符號名稱和類型簽名來判定方法和字段。例如,要調(diào)用類cls中的方法f,本地代碼首先獲得一個方法的ID,如下:

jmethodID

mid = env->GetMethodID(cls, “f”, “(ILjava/lang/String;)D”);

本地代碼便可以重復的使用method

ID而在方法查找時不需要時間,具體如下:

jdouble

result = env->CallDoubleMethod(obj, mid, 10, str);

報告程序錯誤

JNI不檢查編程錯誤,如空指針或非法參數(shù)類型傳遞。非法使用的參數(shù)類型包括用父類對象引用子類對象。

Java異常

JNI允許本地方法任意提高Java異常。本機代碼也可以處理嚴重的Java異常。Java的未處理的異常是傳送回了VM。

因此,程序員可以快速檢查上次的JNI調(diào)用的返回值,以確定是否發(fā)生了錯誤,并調(diào)用一個函數(shù),ExceptionOccurred(),以獲得異常對象,它包含一個錯誤的條件更詳細的說明。

異常處理

在本地代碼中有兩種方法處理異常:

1、本機方法可以選擇立即返回,在Java代碼中拋出異常,啟動了本地方法調(diào)用。

2、本地代碼能過調(diào)用ExceptionClear()來清除異常,然后執(zhí)行自己的異常處理代碼。

在異常被提升之后,本地代碼在其它JNI調(diào)用之前必須先清除異常。

總結(jié)

以上是生活随笔為你收集整理的java jni 原理_JNI的实现原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。