Java 調用Native Method 和Library

Java 調用Native Method和Libary,就會丟失Java自己的一些屬性,比如誇平臺運行,除非你確認必須調用Native Method 和Library,否則儘量別用,我們通常這樣用的原因是之前我們寫了很多代碼,希望重用,或者是因爲執行速度的原因我們需要利用Native code去運行特定的功能。

1. 調用Native Method和Library的例子,

public class SimpleFile {
	public static final char separatorChar='>';
	protected String path;
	protected int fd;

	public SimpleFile(String path) {
		// TODO Auto-generated constructor stub
		this.path = path;
	}
	
	public String getFileName()
	{
		int index = path.lastIndexOf(separatorChar);
		return index <0? path: path.substring(index +1);
	}
	
	public String getPath()
	{
		return this.path;
	}

	public native boolean open();
	public native void close();
	public native int read(byte[] buffer, int length);
	public native int write(byte[] buffer, int length);
	// run when the class is loaded first time.
	static {
		System.loadLibrary("Simple"); //simple.dll
	}
}
然後正常調用SimpleFile中的open等方法,

SimpleFile sf = new SimpleFile(">some>path>and>filename");
		sf.open();
		byte[] buffer = new byte[1024];
		sf.read(buffer, buffer.length);
		fillBufferWithData(buffer, buffer.length);
		sf.write(buffer, buffer.length);
		sf.close();

2. 寫C代碼,

根據我們的定義,我們需要在DLL(Simple.dll)中實現如上native 函數(open, close, read 等等),那麼首先我們需要通過這個SimpleFile類去產生對應的頭文件,

2.1 利用Javah.exe去產生頭文件,

爲了生成對應的頭文件,我們需要先編譯源文件,比如本例中的SimpleFile.java,編譯爲SimpleFile.class, 然後利用javah + 類名(加上package名字)的形式產生對應的頭文件,

例如本例 javah MySubPackage/SimpleFile,則在目錄下會產生MySubPackage_SimpleFile.h,裏面會有如下具體的定義。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MySubPackage_SimpleFile */

#ifndef _Included_MySubPackage_SimpleFile
#define _Included_MySubPackage_SimpleFile
#ifdef __cplusplus
extern "C" {
#endif
#undef MySubPackage_SimpleFile_separatorChar
#define MySubPackage_SimpleFile_separatorChar 62L
/*
 * Class:     MySubPackage_SimpleFile
 * Method:    open
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_MySubPackage_SimpleFile_open
  (JNIEnv *, jobject);

/*
 * Class:     MySubPackage_SimpleFile
 * Method:    close
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_MySubPackage_SimpleFile_close
  (JNIEnv *, jobject);

/*
 * Class:     MySubPackage_SimpleFile
 * Method:    read
 * Signature: ([BI)I
 */
JNIEXPORT jint JNICALL Java_MySubPackage_SimpleFile_read
  (JNIEnv *, jobject, jbyteArray, jint);

/*
 * Class:     MySubPackage_SimpleFile
 * Method:    write
 * Signature: ([BI)I
 */
JNIEXPORT jint JNICALL Java_MySubPackage_SimpleFile_write
  (JNIEnv *, jobject, jbyteArray, jint);

#ifdef __cplusplus
}
#endif
#endif


通過分析上面頭文件的名字,就會發現命名格式Java_Package名字_類名_函數名。


2.2 編寫C代碼,

要按照頭文件中的函數聲明去編寫實現C代碼,

3,編譯Java代碼

在實現C代碼之後,編譯C代碼,產生dll(windows 下),將dll 放入對應的目錄下, Java程序在運行過程中去加載該dll(具體加載dll的方式有好幾種,將在後面學習).

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章