Android之——JNI與C語言常見術語
庫函式:
|- 為了程式碼重用,在C語言中提供了一些常用的、用於執行一些標準任務(如輸入/出)的函式,這些函式事先被編譯,並生成目的碼,然後將生成的目的碼打包成一個庫檔案,以供再次使用。庫檔案中的函式被稱為庫函式,庫檔案被稱為函式庫。
|- 在Windows中C語言庫函式中的中間程式碼都是以.obj為字尾的,Linux中是以.o為字尾。
提示:單個目的碼是無法直接執行的,目的碼在執行之前需要使用連線程式將目的碼和其他庫函式連線在一起後生成可執行的檔案。 Windows下.dll的檔案 , linux下 .so .a的檔案.
標頭檔案:
|- 標頭檔案中存放的是對某個庫中所定義的函式、巨集、型別、全域性變數等進行宣告,它類似於一份倉庫清單。若使用者程式中需要使用某個庫中的函式,則只需要將該庫所對應的標頭檔案include到程式中即可。
|- 標頭檔案中定義的是庫中所有函式的函式原型。而函式的具體實現則是在庫檔案中。
|- 簡單的說:標頭檔案是給編譯器用的,庫檔案是給聯結器用的。
|- 在聯結器連線程式時,會依據使用者程式中匯入的標頭檔案,將對應的庫函式匯入到程式中。標頭檔案以.h為字尾名。
函式庫:
|- 動態庫:在編譯使用者程式時不會將使用者程式內使用的庫函式連線到使用者程式的目的碼中,只有在執行時,且使用者程式執行到相關函式時才會呼叫該函式庫裡的相應函式,因此動態函式庫所產生的可執行檔案比較小。
|- 靜態庫:在編譯使用者程式時會將其內使用的庫函式連線到目的碼中,程式執行時不再需要靜態庫。使用靜態庫生成可執行檔案比較大。
在Linux中:
|- 靜態庫命名一般為:lib+庫名+.a 。
|- 如:libcxy.a 其中lib說明此檔案是一個庫檔案,cxy是庫的名稱,.a說明是靜態的。
|- 動態庫命名一般為:lib+庫名+.so 。.so說明是動態的。
交叉編譯:
|- 將中間程式碼連線成當前計算機可執行的二進位制程式時,連線程式會根據當前計算機的CPU、作業系統的型別來轉換。
根據執行的裝置的不同,可以將cpu分為:
|- arm結構 :主要在移動手持、嵌入式裝置上。
|- x86結構 : 主要在臺式機、筆記本上使用。如Intel和AMD的CPU 。
若想在使用了基於x86結構CPU的作業系統中編譯出可以在基於arm結構CPU的作業系統上執行的程式碼,就必須使用交叉編譯。
交叉編譯:在一個平臺下編譯出在另一個平臺中可以執行的二進位制程式碼。Google提出的NDK就可以完成交叉編譯的工作。
NDK全稱:Native Development Kit 。
|- NDK是一系列工具的集合,它有很多作用。
|- 首先,NDK可以幫助開發者快速開發C(或C++)的動態庫。
|- 其次,NDK集成了交叉編譯器。使用NDK,我們可以將要求高效能的應用邏輯使用C開發,從而提高應用程式的執行效率。
NDK工具必須在Linux下執行,它可以在linux環境下編譯出可以在arm平臺下執行的二進位制庫檔案。
使用JNI技術,其實就是在Java程式中,呼叫C語言的函式庫中提供的函式,來完成一些Java語言無法完成的任務。由於Java語言和C語言結構完全不相同,因此若想讓它們二者互動,則需要制定一系列的規範。JNI就是這組規範,此時 Java只和JNI互動,而由JNI去和C語言互動。
JNI技術分為兩部分:Java端和C語言端。且以Java端為主導。
|- 首先,Java程式設計師在Java端定義一些native方法,並將這些方法以C語言標頭檔案的方式提供給C程式設計師。
|- 然後,C程式設計師使用C語言,來實現Java程式設計師提供的標頭檔案中定義的函式。
|- 接著,C程式設計師將函式打包成一個庫檔案,並將庫檔案交給Java程式設計師。
|- 最後,Java程式設計師在Java程式中匯入庫檔案,然後呼叫native方法。
在Java程式執行的時候,若在某個類中呼叫了native方法,則虛擬機器會通過JNI來轉呼叫庫檔案中的C語言程式碼。提示:C程式碼最終是在Linux程序中執行的,而不是在虛擬機器中。