1. 程式人生 > >Java中原生(native)函式的用法

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

//呼叫原生函式