Linux下 JNI的使用

來源:互聯網
上載者:User

Linux下 JNI的使用

       學習Android其中涉及對JNI的使用,對於這種跨語言的調用真沒有見過,

Java也都是最近才學的更別說對JNI的瞭解了,

JNI的使用對於Android來說又是十分的重要和關鍵。那麼到底Java到底是如何調用C/C++的,

通過網路達人的總結中學習,自己也順便總結一下這個學習的過程。

什麼是JNI

     JNI是Java native interface的簡寫,可以譯作Java原生介面。

Java可以通過JNI調用C/C++的庫,這對於那些對效能要求比較高的Java程式無疑是一個福音。

JNI是Java與C/C++互動的介面。

      使用JNI也是有代價。大家都知道JAVA程式是運行在JVM之上的,可以做到平台無關。

但是如果Java程式通過JNI調用了原生的代碼(比如c/c++等),則Java程式就喪失了平台無關性。

最起碼需要重新編譯原生代碼部分。所以應用JNI需要好好權衡,不到萬不得已,請不要選擇JNI,

可以選擇替代方案,比如TCP/IP進行進程間通訊等等。這也是為什麼Google的Android平台的底層雖然用JNI實現,

但是他不建議開發人員用JNI來開發Android上面的應用的原因。將會喪失Android上面的應用程式平台無關性。

代碼執行個體

      下面以HelloWorld的實現學習Linux下 JNI的使用。

第一步:

建立一個 TestJni.java檔案

import java.util.*;public class TestJni{      //聲明原生函數:參數為String類型      public native void print(String content);      //載入本地庫代碼           static      {           System.loadLibrary("TestJni");      }}

 

 

編譯 TestJni.java檔案:javac TestJni.java

在當前檔案夾下產生TestJni.class檔案

      注意print方法的聲明,關鍵字native表明該方法是一個原生代碼實現的。

另外注意static程式碼片段的System.loadLibrary調用,這段代碼錶示在程式載入的時候,自動載入libTestJni.so庫。

 

第二步:

產生 TestJni.h檔案

執行命令: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 __cplusplusextern "C" {#endif/* * Class:     TestJni * Method:    print * Signature: (Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_TestJni_print  (JNIEnv *, jobject, jstring);#ifdef __cplusplus}#endif#endif

 

該檔案中包含了一個函數Java_TestJni_print的聲明。這裡面自動包含兩個參數,非常重要。JNIEnv *和 jobject

 

第三步:

      建立TestJni.c檔案

#include <jni.h>#include <stdio.h>#include <TestJni.h>JNIEXPORT void JNICALL      Java_TestJni_print(JNIEnv *env,jobject obj, jstring content){      // 從 instring 字串取得指向字串 UTF 編碼的指標      //注意C語言必須(*env)->         C++ env->      const jbyte *str =           (const jbyte *)(*env)->GetStringUTFChars(env,content, JNI_FALSE);      printf("Hello---->%s\n",str);      // 通知虛擬機器本地代碼不再需要通過 str 訪問 Java 字串。    (*env)->ReleaseStringUTFChars(env, content, (const char *)str );    return;}

 

//這裡看到  JNIEnv作用了,使得我們可以使用Java的方法

//jobject 指向在此 Java 代碼中執行個體化的 Java 對象 LocalFunction 的一個控制代碼,相當於 this 指標

參數類型 jstring 對應java中的String,這裡是有所不同的。每一個Java裡的類型這裡有對應的與之匹配。

 

命令列輸入:

      cc -I/usr/lib/jvm/java-6-sun/include/linux/

  -I/usr/lib/jvm/java-6-sun/include/

  -I/home/xmp/AndroidProject/apk/JNI 

  -fPIC -shared -o libTestJni.so TestJni.c

產生:libTestJni.so庫檔案

 

  在目前的目錄產生libTestJni.so。注意一定需要包含Java的include目錄(請根據自己系統內容設定),

因為libTestJni.c中包含了jni.h。另外一個值得注意的是在libTestJni.java中我們LoadLibrary方法載入的是“TestJni”,

可我們產生的Library卻是libTestJni。這是Linux的連結規定的,

一個庫的必須要是:lib+庫名+.so。連結的時候只需要提供庫名就可以了

 

  -I/home/xmp/AndroidProject/apk/JNI 是我自己的練習目錄也必須包含,否則.c檔案中會找不到TestJni.h標頭檔。

  現在 liblibTestJni.so就是一個可以使用的庫了,其功能就是有一個print函數 與剛才所建立的TestJni.java檔案對應,

TestJni.java類中載入庫liblibTestJni.so,聲明了其函數print。所以現在TestJni.java中具備使用print函數的功能;

所以現在我們就可以通過使用TestJni.java來使用調用C庫libTestJni.so中的函數

 

當然現在任何java類都可已載入liblibTestJni.so庫來使用其中的功能。

 

第四步:

     建立HelloWord.java函數

import java.util.*;public class HelloWorld{     public static void main(String argv[])     {         new HelloWorld();     }     public HelloWorld()     {         new TestJni().print("Hello,World !"); //調用TestJni的原生函數print     }}

 

輸入命令編譯: javac HelloWorld.java

產生HelloWorld.class

 

第五步:

      運行HelloWorld程式

命令列輸入:java HelloWorld

輸出結果:Hello---->Hello,World !

驗證OK!

 

如果你這步發生問題,如果這步你收到java.lang.UnsatisfiedLinkError異常,可以通過如下方式指明共用庫的路徑:

java -Djava.library.path='.' HelloWorld

 

或者輸入命令:

export LD_LIBRARY_PATH=“HelloWorld路徑”:$LD_LIBRARY_PATH   設定環境變數

然後再 java HelloWorld 一樣OK

 

簡單例子,照著以下參考文檔即可實現。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.