1. 程式人生 > >Java通過JNI呼叫C的一個小DEMO

Java通過JNI呼叫C的一個小DEMO

    最近看java原始碼,發現很多方法用native修飾,那麼什麼是native方法呢?

    簡單地講,一個Native Method就是一個java呼叫非java程式碼的介面。一個Native Method是這樣一個java的方法:該方法的實現由非java語言實現,比如C。這個特徵並非java所特有,很多其它的程式語言都有這一機制,比如在C++中,你可以用extern "C"告知C++編譯器去呼叫一個C的函式。

    JNI是Java Native Interface的 縮寫。從Java 1.1開始,Java Native Interface (JNI)標準成為java平臺的一部分,它允許Java程式碼和其他語言寫的程式碼進行互動。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計 的,但是它並不妨礙你使用其他語言,只要呼叫約定受支援就可以了。

    使用java與本地已編譯的程式碼互動,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬體、作業系統進行互動,或者為了提高程式的效能。JNI標準至少保證原生代碼能工作在任何Java 虛擬機器實現下。

JNI(Java Native Interface)的書寫步驟:

     1、編寫帶有native宣告的方法的java類
     2、使用javac命令編譯所編寫的java類
     3、使用javah ?jni java類名生成副檔名為h的標頭檔案
     4、用C/C++(或者其他程式設計想語言)實現本地方法
     5、將C/C++編寫的檔案生成動態連線庫

下面我們通過一個小案例來講解java如何通過JNI呼叫C中的方法:

1. 編寫java程式碼,程式碼如下:

package com.xiaomo.jni;

public class JNI_Test {
	
	public native void showStr(String name);
	
	public native void add(int a,int b);
	
	public native int combineStr(int a,int b);
	
	static{
		System.loadLibrary("JNI_DLL");
	}
	
	public static void main(String[] args) throws InterruptedException {
		JNI_Test jni = new JNI_Test();
		jni.showStr("Hello!");
		jni.add(1, 2);
		Thread.sleep(5000);
		System.out.println(jni.combineStr(5, 2));
	}

}

2. 編譯成.class檔案,記得要配置環境變數哦,不會配置的童鞋自己去補充下課外知識吧╮(╯▽╰)╭。

3. 生成.h檔案 :javah –jni  com.xiaomo.jni.JNI_Test 會在JNI_Test的包目錄下找到com_xiaomo_jni_JNI_Test.h檔案


注意:帶有package的類要返回到包的根目錄才能呼叫javah命令,否則會找不到類檔案!(在這裡跌倒過╮(╯▽╰)╭)

4. 生成.dll檔案

1) 開啟Visual c++ 6.0,選擇 檔案->新建->工程(選擇Win32 Dynamic-Link Library->確定->空白的dll工程->完成。 



2) 選擇 工具->選項->目錄(新增目錄JDK安裝目錄下的INCLUDEINCLUDE\WIN32兩個目錄)


com_xiaomo_jni_JNI_Test.h拷貝到新建的工程資料夾中。

3) 新增原始檔JNI_Test.cpp,並完成要實現的本地方法:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "com_xiaomo_jni_JNI_Test.h"
#include <stdio.h>
/*
 * Class:     com_xiaomo_jni_JNI_Test
 * Method:    showStr
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_xiaomo_jni_JNI_1Test_showStr
  (JNIEnv * env , jobject obj, jstring str)
{
	printf("%s\n",&str);
}

/*
 * Class:     com_xiaomo_jni_JNI_Test
 * Method:    add
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_com_xiaomo_jni_JNI_1Test_add
(JNIEnv * env, jobject obj, jint a, jint b)
{
	int sum = a + b;
	printf("%d",sum);
}

JNIEXPORT jint JNICALL Java_com_xiaomo_jni_JNI_1Test_combineStr
  (JNIEnv * env, jobject obj, jint a, jint b)
{
	int sum = a + b;
	return sum;
}

5. 這樣在C++工程下就生成了一個JNI_Test.dll檔案(在工程下debug資料夾下)



6. 將JNI_Test.dll檔案複製進JDK安裝目錄下的bin資料夾裡,執行java com.xiaomo.jni.JNI_Test 控制檯列印(亂碼的問題這裡就不說了,自己慢慢研究吧╮(╯▽╰)╭):


作者:佇望碧落 出處:http://blog.csdn.net/cl05300629