2011年11月15日 星期二

JNI運用在JAVA 與 c 該如何作DLL檔


雖然JAVA的程式都必須在JAVA的虛擬機器上執行,但是我們可以在這部機器中打一個洞,讓JAVA程式可以直接溝通實際的機器.
JNI是一種讓JAVA程式可以外接外部程式的一種機制,讓JAVA程式更具有擴充性,下面將示範一個簡單的範例,這個範例中說明JAVA程式如何與C語言接軌,透過dll和native的方式來達成這項任務.
工具介紹:visual c++ 6.0來製作dll,使用java sdk 1.4來編譯java
java部分的實作
程式碼如下(HelloWorld.java):
class HelloWorld { 
  public native void displayHelloWorld();//native型態是通知Java這個函數會使用到外部函數 
 
  static { 
    System.loadLibrary("hello"); //載入hello.dll的動態連結
  } 
 
  public static void main(String[] args) { 
    new HelloWorld().displayHelloWorld(); 
  } 
}
將這個程式存檔為'HelloWorld.java'先用
'javac HelloWorld.java'
這個指令將它組譯成HelloWorld.class,然後使用
'javah HelloWorld'
產生HelloWorld.h,在HelloWorld.h中我們要實作一個函數
Java_HelloWorld_displayHelloWorld(JNIEnv *, jobject);
首先啟動visual c++ 6.0,在檔案中選擇新增,然後在project中選擇Win32 Dynamic-Link Library這個選項,填寫專案的名稱'hello',按下'Ok',請選擇An empty Dll project這一選項,然後按'Finish'再按下'Ok'。
經過上述動作之後我們就會得到一個空的專案資料,然後我們需要增加一些程式到專案中,在這之前先處理好.h檔,首先先到安裝java JDK的目錄下找到include的資料夾,為了以後撰寫程式方便,將這個目錄下的所有檔案複製一份到你安裝visual c++ 6.0目錄下VC98\Include裡面,預設路徑為
C:\Program Files\Microsoft Visual Studio\VC98\Include
將資料複製到此資料夾中,並將原本放在win32中的jawt_md.h和jni_md.h複製一份至
C:\ Program Files\Microsoft Visual Studio\VC98\Include
完成這些前置動作之後,再來將我們剛剛產生的HelloWorld.h加入我們的Header Files中,並新增一個.c的檔案HelloWorldImp.c,到上方的功能表中Build選則'Build hello.dll',將會得到一個hello.dll在專案目錄下的Debug\hello.dll
HelloWorldImp.c程式碼如下:
#include 
#include "HelloWorld.h" 
#include 
 
JNIEXPORT void JNICALL 
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) 
{ 
printf("HelloWorld"); 
return; 
}
HelloWorld.h程式碼如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include 
/* 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
然後將hello.dll和HelloWorld.class放在同一個目錄下,執行java HelloWorld,出現列印HelloWorld在畫面上的結果
以上這是一個小小的範例,目的只是在做一個小小的實驗,因為沒有一個人會因為要列印一串自救去呼叫C語言來幫你做事,而會直接使用System.out.print("HelloWorld"),比較快一點.透過以上這個小實驗讓我們知道java和c之間是有辦法互通的,因此或許java可以透過這個方式與作業系統之間有更密切的互動

沒有留言: