JNI技術如何在嵌入式軟件開發中應用?
發布時間:2016/12/6 15:41:41 訪問次數:9331
眾所周知,“一次編程,到處使用”的java軟件概念原本就是針對網上嵌入式小設備提出的,幾經周折,目前sun公司已推出了j2me(java 2 p1atform micro edition)針對信息家電的java版本,其技術日趨成熟,開始投入使用。sun公司java虛擬機(jvm)技術的有序開放,使得java軟件真正實現跨平臺運行,即java應用小程序能夠在帶有jvm的任何硬軟件系統上執行。加上java語言本身所具有的安全性、可靠性和可移植性等特點,對實現瘦身上網的信息家電等網絡設備十分有利,同時對嵌入式設備特別是上網設備軟件編程技術產生了很大的影響。
嵌入式系統是以應用為中心、以計算機技術為基礎、軟件硬件可裁剪、適應應用系統對功能、可靠性、成本、體積、功耗嚴格要求的專用計算機系統。嵌入式軟件的基本體系結構包括嵌入式實時操作系統rtos(realtime operating systerrl)、嵌入式設備驅動程序、嵌入式應用程序編程接口(中間件)和嵌入式應用程序。
現階段,計算機應用的普及、互聯網技術的實用以及納米微電子技術的突破,正有力推動著21世紀的工業生產、商業活動、科學實驗和家庭生活等領域自動化和信息化進程。全過程自動化產品制造、大范圍電子商務活動、高度協同科學實驗以及現代化家居生活,為嵌入式產品造就了嶄新而巨大的商機。除了溝通信息高速公路的交換機、路由器和調制解調器,構建計算機集成制造系統(cims)所需的數據傳輸系統dcs(data communication system)和機器人以及規模較大的家用汽車電子系統,最有產量效益和時代特征的嵌入式產品應數因特網上的信息家電(information appliances),如網絡可視電話、網絡游戲機、電子商務、商務通(pda)、移動電話以及多媒體產品(如電視機頂盒、dvd播放機、電子閱讀機)。
1 java的性能問題及幾種解決方案
java程序也有其本身的缺陷,那就是其效率問題。由于java是一種介于解釋型和編譯型之間的語言,其對內存的管理是通過jvm虛擬機來實現的,同樣的程序,如果用編譯型語言c來實現,其運行速度一般要比java快得多。因此,提高java的性能就顯得十分重要。
迄今為止,人們為提高java的運行速度而做出的許多努力,主要集中在程序設計的方法和模式選擇方面。但是由于算法和設計模式的優化是通用的,對java 有效的優化算法和設計模式,對其他編譯語言也基本適用,因此不能從根本上改變java程序與編譯型語言在執行效率方面的差異。
另外,jit(just in time,及時編譯)技術也是一個比較好的思想。它的基本原理是,首先,通過java編譯器把java源代碼編譯成與平臺無關的二進制字節碼。然后,在 java程序真正執行之前,系統通過jit編譯器把java的字節碼編譯為本地化機器碼。最后,系統執行本地化機器碼,不用對字節碼進行解釋。這樣做的優點是,大大提高了java程序的性能,縮短了加載程序的時間;同時,由于編譯的結果并不在程序運行期間保存,因此也節約了存儲空間。缺點是,由于jit編譯器對所有的代碼都想優化,因此同樣也占用了很多時間。
動態優化技術即提前編譯為機器碼的技術(dynamicopttmization,ahead of time technology)是提高java性能的另一個嘗試。動態優化技術充分利用了java源碼編譯、字節碼編譯、動態編譯和靜態編譯的技術。其輸入是 java的源碼或字節碼。而輸出是經過高度優化的可執行代碼和動態庫(window中是.dil文件,unix中是共享庫.a.so文件)。其優點是能大大提高程序的性能,缺點是破壞了java的可移植性,也對java的安全帶來了一定的隱患。
2 jni技術
實際上,有一種通常被忽視的技術可以在很大程度上解決這個難題,那就是jni(java native interface,java本地化方法)。圖1是jni技術實現的一般步驟。
(1)編寫java類代碼
其中,需要jni實現的方法應當用native關鍵字聲明。在該類中,用system.1oadlibrary()方法加載需要的動態鏈接庫。關鍵代碼如下:
//compute.java
public class compute{
public native double comp (double params);
static{
//調用動態鏈接庫
system.loadlibrary(“mathlib”);
}
(2)編譯成字節代碼
在這個過程中,由于采用了native關鍵字聲明,java編譯器會忽視沒有代碼體的jni方法部分。
(3)生成相關jni方法的頭文件
這個過程的實現一般是通過利用jlavah-jni * class生成的,也可以手工生成該文件;但是由于java虛擬機是根據一定的命名規范完成對jni方法的調用,所以手工編寫頭文件需要特別小心。
上述文件產生的頭文件部分代碼如下:
//compute.h
;
extern“c”{
jniexport jdoublejnicall java_compute_comp(jni-env *, jobject, jdoublearray);
;
jni函數名稱分為三部分:首先是java關鍵字,供java虛擬機識別;然后是調用者類名稱(全限定的類名,其中用下劃線代替名稱分隔符);最后是對應的方法名稱,各段名稱之間用下劃線分割。
jni函數的參數也由三部分組成:首先是jnienv *,是一個指向jni運行環境的指針;第二個參數隨本地方法是靜態還是非靜態而有所不同一一非靜態本地方法的第二個參數是對對象的引用,而靜態本地方法的第二個參數是對其java類的引用;其余的參數對應通常java方法的參數,參數類型需要根據一定規則進行映射。
(4)編寫相應方法的實現代碼
在編碼過程中,需要注意變量的長度問題,例如java的整型變量長度為32位,而c語言為16位,所以要仔細核對變量類型映射表,防止在傳值過程中出現問題。
(5)將jni實現代碼編譯成動態鏈接庫
編譯過程是利用c/c++編譯器實現的,當要使用生成的動態鏈接庫時,調用者類中需要顯式調用該鏈接庫。
經過上述處理,基本上完成了一個包含本地化方法的java類的開發。
3 基于jni的嵌入式手機軟件開發實例
下面通過一個實例來描述運用jni技術在手機上操縱攝像頭,捕捉視頻并存儲圖片的過程。
(1)活動/狀態圖
圖2為捕捉視頻并存儲圖片的活動/狀態圖
眾所周知,“一次編程,到處使用”的java軟件概念原本就是針對網上嵌入式小設備提出的,幾經周折,目前sun公司已推出了j2me(java 2 p1atform micro edition)針對信息家電的java版本,其技術日趨成熟,開始投入使用。sun公司java虛擬機(jvm)技術的有序開放,使得java軟件真正實現跨平臺運行,即java應用小程序能夠在帶有jvm的任何硬軟件系統上執行。加上java語言本身所具有的安全性、可靠性和可移植性等特點,對實現瘦身上網的信息家電等網絡設備十分有利,同時對嵌入式設備特別是上網設備軟件編程技術產生了很大的影響。
嵌入式系統是以應用為中心、以計算機技術為基礎、軟件硬件可裁剪、適應應用系統對功能、可靠性、成本、體積、功耗嚴格要求的專用計算機系統。嵌入式軟件的基本體系結構包括嵌入式實時操作系統rtos(realtime operating systerrl)、嵌入式設備驅動程序、嵌入式應用程序編程接口(中間件)和嵌入式應用程序。
現階段,計算機應用的普及、互聯網技術的實用以及納米微電子技術的突破,正有力推動著21世紀的工業生產、商業活動、科學實驗和家庭生活等領域自動化和信息化進程。全過程自動化產品制造、大范圍電子商務活動、高度協同科學實驗以及現代化家居生活,為嵌入式產品造就了嶄新而巨大的商機。除了溝通信息高速公路的交換機、路由器和調制解調器,構建計算機集成制造系統(cims)所需的數據傳輸系統dcs(data communication system)和機器人以及規模較大的家用汽車電子系統,最有產量效益和時代特征的嵌入式產品應數因特網上的信息家電(information appliances),如網絡可視電話、網絡游戲機、電子商務、商務通(pda)、移動電話以及多媒體產品(如電視機頂盒、dvd播放機、電子閱讀機)。
1 java的性能問題及幾種解決方案
java程序也有其本身的缺陷,那就是其效率問題。由于java是一種介于解釋型和編譯型之間的語言,其對內存的管理是通過jvm虛擬機來實現的,同樣的程序,如果用編譯型語言c來實現,其運行速度一般要比java快得多。因此,提高java的性能就顯得十分重要。
迄今為止,人們為提高java的運行速度而做出的許多努力,主要集中在程序設計的方法和模式選擇方面。但是由于算法和設計模式的優化是通用的,對java 有效的優化算法和設計模式,對其他編譯語言也基本適用,因此不能從根本上改變java程序與編譯型語言在執行效率方面的差異。
另外,jit(just in time,及時編譯)技術也是一個比較好的思想。它的基本原理是,首先,通過java編譯器把java源代碼編譯成與平臺無關的二進制字節碼。然后,在 java程序真正執行之前,系統通過jit編譯器把java的字節碼編譯為本地化機器碼。最后,系統執行本地化機器碼,不用對字節碼進行解釋。這樣做的優點是,大大提高了java程序的性能,縮短了加載程序的時間;同時,由于編譯的結果并不在程序運行期間保存,因此也節約了存儲空間。缺點是,由于jit編譯器對所有的代碼都想優化,因此同樣也占用了很多時間。
動態優化技術即提前編譯為機器碼的技術(dynamicopttmization,ahead of time technology)是提高java性能的另一個嘗試。動態優化技術充分利用了java源碼編譯、字節碼編譯、動態編譯和靜態編譯的技術。其輸入是 java的源碼或字節碼。而輸出是經過高度優化的可執行代碼和動態庫(window中是.dil文件,unix中是共享庫.a.so文件)。其優點是能大大提高程序的性能,缺點是破壞了java的可移植性,也對java的安全帶來了一定的隱患。
2 jni技術
實際上,有一種通常被忽視的技術可以在很大程度上解決這個難題,那就是jni(java native interface,java本地化方法)。圖1是jni技術實現的一般步驟。
(1)編寫java類代碼
其中,需要jni實現的方法應當用native關鍵字聲明。在該類中,用system.1oadlibrary()方法加載需要的動態鏈接庫。關鍵代碼如下:
//compute.java
public class compute{
public native double comp (double params);
static{
//調用動態鏈接庫
system.loadlibrary(“mathlib”);
}
(2)編譯成字節代碼
在這個過程中,由于采用了native關鍵字聲明,java編譯器會忽視沒有代碼體的jni方法部分。
(3)生成相關jni方法的頭文件
這個過程的實現一般是通過利用jlavah-jni * class生成的,也可以手工生成該文件;但是由于java虛擬機是根據一定的命名規范完成對jni方法的調用,所以手工編寫頭文件需要特別小心。
上述文件產生的頭文件部分代碼如下:
//compute.h
;
extern“c”{
jniexport jdoublejnicall java_compute_comp(jni-env *, jobject, jdoublearray);
;
jni函數名稱分為三部分:首先是java關鍵字,供java虛擬機識別;然后是調用者類名稱(全限定的類名,其中用下劃線代替名稱分隔符);最后是對應的方法名稱,各段名稱之間用下劃線分割。
jni函數的參數也由三部分組成:首先是jnienv *,是一個指向jni運行環境的指針;第二個參數隨本地方法是靜態還是非靜態而有所不同一一非靜態本地方法的第二個參數是對對象的引用,而靜態本地方法的第二個參數是對其java類的引用;其余的參數對應通常java方法的參數,參數類型需要根據一定規則進行映射。
(4)編寫相應方法的實現代碼
在編碼過程中,需要注意變量的長度問題,例如java的整型變量長度為32位,而c語言為16位,所以要仔細核對變量類型映射表,防止在傳值過程中出現問題。
(5)將jni實現代碼編譯成動態鏈接庫
編譯過程是利用c/c++編譯器實現的,當要使用生成的動態鏈接庫時,調用者類中需要顯式調用該鏈接庫。
經過上述處理,基本上完成了一個包含本地化方法的java類的開發。
3 基于jni的嵌入式手機軟件開發實例
下面通過一個實例來描述運用jni技術在手機上操縱攝像頭,捕捉視頻并存儲圖片的過程。
(1)活動/狀態圖
圖2為捕捉視頻并存儲圖片的活動/狀態圖