[JAVA]JNI之HelloWorld
環境
JAVA:1.8
OS:ubuntu 16.04
--------
在學習java的equals方法和hashcode方法的時候,了解到java的Object類的hashcode方法是一個native方法。初步了解了一點jni,也即JAVA native interface,通過jni可以使用java調用本地其他程序等,這樣雖然函數的聲明是在java代碼中,但函數的實現由其他語言(自己僅知道支持C,C++)實現。
1.首先寫一個java的class
public class HelloWorld {
public native void displayHelloWorld();
static {
System.loadLibrary("HelloWorldImpl");
System.out.println("HelloWorldImpl loaded!");
}
public static void main(String[] args) {
HelloWorld h = new HelloWorld();
h.displayHelloWorld();
}
}
native方法的定義很簡單,在函數名前加一個native就可以。
在static塊中,使用System.loadLibrary,加載庫,在Linux環境中,會加載LD_LIBRARY_PATH環境變量配置路徑中的libHelloWorldImpl.so動態鏈接庫,這是Linux的默認實現方法。
2.運行javac HelloWorld.java編譯java類
3.運行javah -jni HelloWorld生成HelloWorld.h頭文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld*/ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
可以想象,JAVA自定義了一套c語言的數據結構和函數名規則,來使得java和c按照約定的規則進行調用。
4.編輯HelloWorldImpl.c文件,實現如下
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> #include <stdio.h> #include "HelloWorld.h" /* Header for class HelloWorld */ /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *env, jobject jo) { printf("Hello World!\n"); return; }
jni.h在JDK安裝路徑中中,所以編譯的時候,要加入頭文件路徑
gcc -I /usr/lib/java/jdk1.8.0_121/include -I /usr/lib/java/jdk1.8.0_121/include/linux -fPIC -shared -o libHelloWorldImpl.so HelloWorldImpl.c
5.這個時候可以運行程序了,前面說了,使用System.loadLibrary,加載庫,在Linux環境中,會加載LD_LIBRARY_PATH環境變量配置路徑中的libHelloWorldImpl.so動態鏈接庫,運行方法1:設置LD_LIBRARY_PATH環境變量,運行java HelloWorld;運行方法二:java -Djava.library.path=‘.‘ HelloWorld
[JAVA]JNI之HelloWorld