Java中原生(native)函式的用法
1、原生(Native)函式的概念
在Java程式中,可以使用由其他程式語言實現的函式,這種函式,在Java中被稱之為
原生(Native)函式。
2、在Java程式中使用原生函式的優缺點
1)優點
A、在Java程式中,可以複用已由其他語言實現的各種庫。
可能已存在很多由其他語言編寫的庫,為了在Java程式中能夠複用這些庫,就需要用到原生函式。
B、增加了Java標準類庫中不存在的功能
由於Java的可移植性,它不能利用與作業系統相關的特點,因此,當要訪問特定的硬體裝置或使用新的網路驅動器時,就不得不使用原生函式提供的功能。
2)缺點
A、任何包含原生函式的Java類均不能用於Applet程式。
這主要是出於安全性的考慮,因為Java的安全管理機制難以防範來自原生函數的惡意攻擊。
B、使用原生函式將會使Java程式失去可移植性。
因為,你必須為執行該Java程式的各種平臺編寫不同的原生函式連結庫。
3、原生函式的實現步驟
1)JNI介面
JNI介面是Java Native Interface的縮寫,它已成為Java平臺的一部分,它允許
在Java程式中呼叫由其他語言編寫的函式。
JNI介面標準的設計目的有:
A、Java標準類庫可能不支援應用程式中需要用到的與平臺相關的功能,這部分功能就需要由JNI來實現。
B、對於已存在的由其他語言編寫的庫或者應用程式,在Java程式中,可以通過JNI來實現對這些已存在介面的呼叫。
C、可能需要用低階語言如彙編來實現一些對執行時間很嚴格的程式碼,在Java程式
中,就可以通過JNI介面來呼叫這些程式碼。
2)原生函式的實現步驟
A、編寫帶有native宣告的Java類,如test.java
B、使用javac命令編譯第一步中編寫的java類,如javac test.java,假設生成的文件為test.class
C、使用javah命令來生成java類對應的存根標頭檔案,如javah -jni test,假設生成的檔案為test.h
D、使用C/C++來實現test.h中的native介面,如test.c
E、將test.c編譯為動態連結庫,如libtest.so。
這樣,執行命令java test
4、例子
在這裡,我們編寫一個最簡單的列印hellow world的例子
1、編寫一個帶有native宣告的Java類,如test.java
class TestJni
{
public native void myPrint();
static
{
System.loadLibrary("hellow");
//動態連結庫的名字(linux下對應為libhellow.so)
}
public static void main(String args[])
{
TestJni test = new TestJni();
test.myPrint();
}
}
2、使用javac命令編譯第一步中編寫的java類
#javac test.java
這條命令將會編譯該java程式,並生成相應的位元組碼檔案:TestJni.class
3、使用javah命令來生成java類對應的存根標頭檔案
#javah -jni TestJni
這條命令會根據指定的位元組碼檔案生成相應的存根標頭檔案TestJni.h,其內容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestJni */
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJni
* Method: myPrint
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestJni_myPrint
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
4、使用C/C++來實現TestJni.h中的native介面,比如將其相應的實現命名為TestJni.c:
#include <stdio.h>
#include "TestJni.h"
JNIEXPORT void JNICALL Java_TestJni_myPrint
(JNIEnv *, jobject)
{
printf("Hellow World!/n");
}
5、將TestJni.c編譯為動態連結庫
執行命令:
g++ -shared -o libhellow.so TestJni.c -I/usr/lib/jvm/java-6-sun-1.6.0.24/include
-I/usr/lib/jvm/java-6-sun-1.6.0.24/include/linux/
該命令執行後會生成名為libhellow.so的動態連結庫。
注意:生成動態連結庫時,標頭檔案路徑需要根據具體情況而修改
最後,就可以通過命令執行相應的java程式了(這裡一般需要設定環境變數:LD_LIBRARY_PATH,即動態連結庫libhellow.so 的路徑):
#java TestJni
輸出為:Hellow World!
這表明,一切OK。
//呼叫原生函式