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 !
感謝閱讀,希望能幫助到大家