頭腦一閃,突然想到JNI應該可以讓他解決問題,但距離上次使用JNI已經是三年前了…
想說三年前才開使撰寫部落格,所以應該會有JNI的筆記吧…
沒想到將舊文翻一翻之後才知道原來我當初沒寫筆記啊…
這次就花時間來寫筆記了啊…囧
免得三年後又用到…
先開啟一個新專案,選擇Win32
要給Java調用,所以選擇DLL並按下完成
接著找到安裝JDK路徑底下的include/jni.h以及/include/win32/jni_md.h,將兩個標頭檔複製到專案資料夾內,再專案資料夾內的兩個標頭檔新增至專案
開啟stdafx.h,下方程式碼貼入即可
標頭檔:
// stdafx.h : 可在此標頭檔中包含標準的系統 Include 檔, // 或是經常使用卻很少變更的 // 專案專用 Include 檔案 // #pragma once #include "targetver.h" #define WIN32_LEAN_AND_MEAN // 從 Windows 標頭排除不常使用的成員 // Windows 標頭檔: #include <windows.h> // JNI 標頭檔 #include "jni.h" #ifndef _Included_CYFang #define _Included_CYFang #ifdef __cplusplus extern "C" { #endif //Java_ClassName_MethodName JNIEXPORT jobjectArray JNICALL Java_CYFang_getInfo(JNIEnv *env, jobject obj); #ifdef __cplusplus } #endif #endif
以下程式碼貼到Win32Project.cpp內
程式碼:
// Win32Project.cpp : 定義 DLL 應用程式的匯出函式。 // #include "stdafx.h" JNIEXPORT jobjectArray JNICALL Java_CYFang_getInfo(JNIEnv *env, jobject obj) { //Array jobjectArray array = env->NewObjectArray(3, env->FindClass("java/lang/String"), 0); char *name = "CYFang"; char *number = "11223344"; char *score = "90"; env->SetObjectArrayElement(array, 0, env->NewStringUTF(name)); env->SetObjectArrayElement(array, 1, env->NewStringUTF(number)); env->SetObjectArrayElement(array, 2, env->NewStringUTF(score)); ZeroMemory(name, strlen(name)); ZeroMemory(number, strlen(number)); ZeroMemory(score, strlen(score)); return array; }
JNI有它的命名規則,已我自訂的方法為例『JNIEXPORT jobjectArray JNICALL Java_CYFang_getInfo』
JNIEXPORT:固定欄位 jobjectArray:方法型別 JNICALL:固定欄位 JAVA:固定的欄位 CYFang:Java的類別名稱 getInfo:方法名稱
關於方法型別可以參考『JNI Types and Data Structures』
接著建制該專案,輸出成功則會在專案資料夾底下找到DLL
WIN32使用者,將該DLL放置C:windows\system32底下
WIN64使用者,將該DLL放置C:windows\system64底下
接著開啟Eclipse,新增Java專案名稱隨意
接著新增Class名稱為JNI所設定的ClassName
Java程式碼:
public class CYFang { static { System.loadLibrary("Win32Project"); } native String[] getInfo(); public static void main(String[] args) { CYFang cyFang = new CYFang(); for (String str : cyFang.getInfo()) { System.out.println(str); } } }
執行結果: