1. 程式人生 > 實用技巧 >JNI 原理介紹及最簡單例項程式碼

JNI 原理介紹及最簡單例項程式碼

  JNI是JAVA標準平臺中的一個重要功能,它彌補了JAVA的與平臺無關這一重大優點的不足,在JAVA實現跨平臺的同時,也能與其它語言(如C、C++)的動態庫進行互動,給其它語言發揮優勢的機會。

  有了JAVA標準平臺的支援,使JNI模式更加易於實現和使用。在此總結了下面這個知識圖: 

  例項:

  環境說明:ubuntu 16.04 LTS系統

  程式清單1:src/com/clay/example/HelloWorld.java

 1 package com.clay.example;
 2 
 3 public class HelloWorld {
 4     static {
 5
System.loadLibrary("Hello"); 6 } 7 8 public native void DisplayHello(); 9 10 public static void main(String[] args) { 11 new HelloWorld().DisplayHello(); 12 } 13 14 }

  在這裡,庫的副檔名字可以不用寫出來,究竟是DLL還是SO,由系統自己判斷。
  還需要對將要呼叫的方法做本地宣告,關鍵字為native。並且只需要宣告,而不需要具 體實現。

  進入src目錄下,編譯該JAVA類,

  命令javac ./com/clay/example/HelloWorld.java

  在該HelloWorld.java所在目錄下生成HelloWorld.class

  然後使用 javah 生成標頭檔案,

  命令javah -jni com.clay.example.HelloWorld

  在當前目錄下生成 com_clay_example_HelloWorld.h 標頭檔案,此檔案供C、C++程式來引用並實現其中的函式

程式清單2:com_clay_example_HelloWorld.h

 1 /* DO NOT EDIT THIS FILE - it is machine generated 
*/ 2 #include <jni.h> 3 /* Header for class com_clay_example_HelloWorld */ 4 5 #ifndef _Included_com_clay_example_HelloWorld 6 #define _Included_com_clay_example_HelloWorld 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 /* 11 * Class: com_clay_example_HelloWorld 12 * Method: DisplayHello 13 * Signature: ()V 14 */ 15 JNIEXPORT void JNICALL Java_com_clay_example_HelloWorld_DisplayHello 16 (JNIEnv *, jobject); 17 18 #ifdef __cplusplus 19 } 20 #endif 21 #endif

  注:1)、此標頭檔案是不需要使用者編譯的,直接供其它C、C++程式引用。
   2)、此標頭檔案中的Java_com_clay_example_HelloWorld_DisplayHello(JNIEnv *, jobject);方法,是將來與動態連結庫互動的介面,並需要名字保持一致。

程式清單3:src/jni_helloworldImpl.cpp

 1 #include <jni.h>
 2 #include "com_clay_example_HelloWorld.h"
 3 #include <stdio.h>
 4 
 5 JNIEXPORT void JNICALL Java_com_clay_example_HelloWorld_DisplayHello
 6 (JNIEnv *env, jobject obj)
 7 {
 8     printf("From jni_helloworldImpl.cpp :");
 9     printf("Hello World! \n");
10 }

  此C++檔案實現了上述標頭檔案中的函式,注意方法函式名要保持一致。
  編譯生成動態庫libHello.so,

  命令:g++ -shared -fPIC -I /opt/jdk1.8.0_221/include/ -I /opt/jdk1.8.0_221/include/linux/ jni_helloworldImpl.cpp -o libHello.so

  成功後,便會在當前目錄下生成動態連結庫libHello.so檔案。

  有了具體實現的動態庫後,就可以執行JAVA呼叫JNI程式類的native方法了,

  命令:java -Djava.library.path=. com.clay.example.HelloWorld

  輸入結果即為:From jni_helloworldImpl.cpp :Hello world !

  感謝閱讀,希望能幫助到大家