1. 程式人生 > >探索JAVA知識的路上遇上了JNI

探索JAVA知識的路上遇上了JNI

*前言:前幾天學習時打開了jdk原始碼包,看了集合框架的一些原始碼,想著深化學習下,可是不知道怎麼就打開了FileOpenInputStream的原始碼,看到了下面四個native方法(當然還有其它native方法):

private native void open0(String name) throws FileNotFoundException; 

private native int readBytes(byte b[], int off, int len) throws IOException;

private native void close0() throws IOException;

於是有了一些聯想。聯絡到c中的下列函式:

FILE *fopen( const char * filename, const char * mode );

char *fgets( char *buf, int n, FILE *fp );

int fclose( FILE *fp );

可不是嘛,真像(真香警告!!哈哈),寫到這裡想著要不就把這三個本地方法給實現編寫個自己的FileInputStream,猜測也許可能分別呼叫這三個方法可能行不通呢,但學習可不就是這樣,不去試著搞搞,怎麼提升自己,嘿嘿。希望以後自己看到自己現在的學習狀態不會嘲笑自己吧。

在實現這條路上需要補全很多這方面的知識,JNI的API的熟悉,JNI資料型別與C++中資料型別轉換...

大前天和昨天都在實現native方法呼叫。中間一天佩女朋友了哈哈。在實現過程中當然中間遇到一些問題啦。遇到問題是好事,在解決問題中你可以獲得很多沒有遇到問題時的知識。

*JNI(java native interface) ,它提供了若干的API實現了Java和其他語言的通訊(主要是C&C++

JNI使用的副作用:

1、程式不再跨平臺。要想跨平臺,必須在不同的系統環境下重新編譯本地語言部分。

2、程式不再是絕對安全的,原生代碼的不當使用可能導致整個程式崩潰。

這裡記錄下實現一個簡單的JNI列子:

1.編寫好例子HelloWorld.java

public class HelloWorld{
	public native void sayHello();
	static{
		System.loadLibrary("hello"); //引用動態連結庫的名稱
	}
	public static void main(String[] args){
		new HelloWorld().sayHello();
	}
}

*System.loadLibrary("hello");在這裡宣告JNI的不再跨平臺,不同系統平臺下載入引用的動態連結庫不同

windows平臺下呼叫的動態連結庫為hello.dll

linux平臺下呼叫動態連結庫為hello.so

2.在編譯生成動態連結庫前,先編寫本地實現程式碼c/c++

1)在編寫c/c++程式碼前,在當前環境下編譯HelloWorld.java程式,使用使用工具javah將使用生成程式要使用的標頭檔案HelloWorld.h,執行命令( javah -jni HelloWorld),不同系統平臺下標頭檔案都一樣。

2)引用上面標頭檔案編寫實現程式碼HelloWorld.c

#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_sayHello(JNIEnv *jbi, jobject obj){
	printf("HelloWorld");
	return;
}

3.生成動態連結庫

windows下可使用vc++(推薦),mingw或其他

錯誤資訊為64位的VM不能載入32位的dll(通過java -version檢視本機安裝VM為多少位的)

預設mingw編譯32位作業系統程式。

可下載mingw-w64配置後編譯為64位系統程式(hello.dll),

自己在編譯時系統內部報錯跳過該方法,使用了vc++生成64位的hello.dll,畢竟微軟家的系統和微軟家的vc++;

總結:不同位數的作業系統,執行著不同位數的VM,而VM只支援相同位數的程式時。不同平臺的複雜性,造就了跨平臺的重要性。

linux中使用系統自帶gcc編譯生成

-I大寫的i

gcc -I$JAVA_HOME/java/include -I$JAVA_HOME/java/include/linux HelloWorld.c -fPIC -shared -o hello.so

4.最後執行 java HelloWorld 得到輸出內容

。。。。。。。。。。後續實現文章開頭想要嘗試的,不是一時半夥完成的,堅持住。