您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Linux系統(tǒng)中如何使用JNI,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
JNI是Java Native Interface的縮寫,通過使用 Java本地接口書寫程序,可以確保代碼在不同的平臺上方便移植。從Java1.1開始,JNI標準成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交。
我將詳細說明在 Linux 平臺下如何實現本地共享庫與 Java 協同工作,老規(guī)矩以Hello world為例。
public class Hello { static { try { // 此處即為本地方法所在鏈接庫名 System.loadLibrary("hello"); } catch(UnsatisfiedLinkError e) { System.err.println( "Cannot load hello library:\n " + e.toString() ); } } public Hello() { } // 聲明的本地方法 public native void SayHello(String strName); }
這里有兩個注意事項:
首先:為要使用的每個本地方法編寫本地方法聲明,只是必須指定 native 關鍵字,如下所示:
public native void SayHello(String strName);
其次:必須顯式地加載本地代碼庫。我們需在類的靜態(tài)塊中加載這個庫(靜態(tài)庫在類加載時候就會調用)
現在我們來編輯hello.java以生成hello.class文件。
要為以上定義的類生成 Java 本地接口頭文件,需使用 javah,Java 編譯器的 javah 功能將根據 Hello 類生成必要的聲明,此命令將生成 Hello.h 文件
生成的 Hello.h 文件 內容如下所示:
#include /* Header for class Hello */#ifndef _Included_Hello#define _Included_Hello#ifdef __cplusplusextern "C" {#endif/* * Class: Hello * Method: SayHello * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_Hello_SayHello (JNIEnv *, jobject, jstring);#ifdef __cplusplus}#endif#endif
內容如下:
#include "Hello.h"#include // 與 Hello.h 中函數聲明相同 JNIEXPORT void JNICALL Java_Hello_SayHello (JNIEnv * env, jobject arg, jstring instring) { // 從 instring 字符串取得指向字符串 UTF 編碼的指針 const jbyte *str = (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE ); printf("Hello,%s\n",str); // 通知虛擬機本地代碼不再需要通過 str 訪問 Java 字符串。 env->ReleaseStringUTFChars( instring, (const char *)str ); return; }
這里有三個參數,下面講一下參數用法:
(1)所有的 JNI 調用都使用了 JNIEnv * 類型的指針,習慣上在 CPP 文件中將這個變量定義為 evn,它是任意一個本地方法的第一個參數。env 指針指向一個函數指針表,在 VC 中可以直接用”->”操作符訪問其中的函數。 (2)jobject 指向在此 Java 代碼中實例化的 Java 對象 LocalFunction 的一個句柄,相當于 this 指針。 (3)第三個參數就是本地調用中有 Java 程序傳進的參數,本例中只有一個 String 型參數。 對于字符串型參數,因為在本地代碼中不能直接讀取 Java 字符串,而必須將其轉換為 C /C++ 字符串或 Unicode。
使用 GCC 時 , 必須通知編譯器在何處查找此 Java 本地方法的支持文件,并且顯式通知編譯器生成位置無關的代碼,在我的環(huán)境中按如下過程編譯:
gcc -I/home/jbuilder/jdk1.3.1/include -I/home/jbuilder/jdk1.3.1/include/linux -fPIC -c Hello.c
生成 Hello.o
gcc -shared -Wl,-soname,libhello.so -o libhello.so Hello.o
生成 libhello.so(這就是linux下動態(tài)鏈接庫的文件名格式,就像windows下是.dll文件后綴名類似)
最后通知動態(tài)鏈接程序此共享文件的路徑。
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
將如下源碼存為 A.java:
import Hello; import java.util.*; public class A { public static void main(String argv[]) { A a = new A(); } public A() { Hello h = new Hello(); // 調用本地方法 h.SayHello("Hello world"); } }
用 javac 編譯A.java,生成A.class 向執(zhí)行普通 Java 程序一樣使用 java A,我們會看到在屏幕上出現 Hello world。 ok,完成!
關于“Linux系統(tǒng)中如何使用JNI”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。