2008年6月17日 星期二

[Java] 最簡單建立 JNI DLL 的方法 (不用 IDE)

可以利用 Visual Studio 隨便建立一個 DLL 實做 JNI 定義的 function, 但是這篇文章介紹的是如何完全用命令列的方式建立 dll.

為何不用 IDE 建立 JNI 的 DLL 呢? 主要原因還是當我同時開多個IDE 一起處理我的專案時, Visual Studio 實在是像烏龜般地緩慢, 整個系統連 開個檔案總管都要跑半天.

我的 RAM 已經插滿與不想換 Notebook 的情況下, 還是使用 NotePad ++ 建立 DLL 檔, 用 GNU make 我的專案.

我的天空也就瞬間晴朗了起來 ...

來看看我怎麼做的.

Step 1: 定義在 java 裡面的 native method

------------------ Main_japi.java ---------------

public class Main_japi{

public static native void Test();

}
-----------------------------------------------

Step 2: 產生標頭檔 --> Main_japi.h

javah -jni Main_japi

Step 3: 實做 Main_japi.h 裡面的 function (直接用 Notepad 就可以了)

---------------- Main_api.cpp -------------

#include "Main_japi.h"

#include <windows.h>
#include <tchar.h>

JNIEXPORT void JNICALL Java_Main_1japi_Test
(JNIEnv *env, jclass obj){
MessageBox(NULL,_T("test"),_T("Info"),MB_OK);
}
-----------------------------------------------

你可以用 c++ 或 c 實做 function.

Step 4: 建立 Main_api.dll (直接下指令 or 用 Visual Studio 隨便建 Main_api.dll )

cl -I${JDKROOT}/include
-I${JDKROOT}/include/win32
-I${VCROOT}include \
-I${VCROOT}PlatformSDK/Include \
-LD Main_api.cpp User32.lib\
-Main_api.dll

如果你在這裡發現找不到 User32.lib 時, 設定一下環境變數 LIB 到他的位置就可以了

請參考:

[C++] LINK : fatal error LNK1104: cannot open file 'LIBCMT.lib'

我使用的是 SetEnv 所以設定範例如下:

SetEnv LIB "c:\Program Files\Microsoft Visual Studio 8\VC\lib"
SetEnv LIB %%"c:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Lib

[程式設計] 自動設定環境變數 -- SetEnv

Step 5: 使用 native code 的方法範例

public class Main {
static {
System.loadLibrary("Main_api");
}
public Main() {

Main_japi.Test();
}

}

為了方便起見, 通常我們會把上面的編譯步驟寫成一個 Makefile, 然後在 MinGW 環境裡面執行 make.

範例如下:

------------------- Makefile -------------------

JAVASRC = $(shell ls *.java)

all: compile jni
jni: Main_japi.java
[tab鍵]javah -jni Main_japi
[tab鍵]cl -I${JDKROOT}/include
-I${JDKROOT}/include/win32
-I${VCROOT}include \
-I${VCROOT}PlatformSDK/Include \
-LD Main_api.cpp User32.lib\
-Main_api.dll

compile:$(JAVASRC)
[tab鍵]javac $(JAVASRC)
clean:
[tab鍵] rm -fr *.class *.obj

以後, 只要下一個 make, 所有東西都會自動建置完成.

Enjoy.

by Jing

延伸閱讀

1. [程式設計] 自動設定環境變數 -- SetEnv

2. [程式設計] 在 MINGW32 中, 指定長檔名包含空白目錄的方法

3. [C++] LINK : fatal error LNK1104: cannot open file 'LIBCMT.lib'

4. [程式設計] gnu make makefile 最簡單說明

5. [軟體] MSYS -- Minimal SYStem

2 則留言: