C/C++啟動JVM
- 測試環境
- 目錄結構
- 需要的資源檔案路徑
- jni.h
- jni_md.h
- jre
- 代碼
- 項目下載下傳
測試環境
系統:windwos 10
架構:x86_64
開發工具:Visual Studio 2019
java:1.8
目錄結構
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5yM2YzM5QjMhNjZ0UTNllDOxYzXyUDNwETM5AzLcFTMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLzM3Lc9CX6MHc0RHaiojIsJye.png)
需要的資源檔案路徑
jni.h 頭檔案在 jdk/include/jin.h
jni_md.h 頭檔案在 jdk/include/win32/jni_md.h
jre 即java運作環境jvm在 jdk/jre
代碼
#include "windows.h"
#include "iostream"
#include <tchar.h>
#include "jni.h"
#include <libloaderapi.h>
using namespace std;
typedef jint(JNICALL* JNICREATEPROC)(JavaVM**, void**, void*);
bool startJVM();
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Application run." << endl;
startJVM();
return 0;
}
//啟動java虛拟機
bool startJVM() {
int pause;
//擷取jvm動态庫的路徑
TCHAR* jvmPath = _T(".\\jre\\bin\\server\\jvm.dll");
//java虛拟機啟動時接收的參數,每個參數單獨一項
int nOptionCount = 2;
JavaVMOption vmOption[2];
//設定JVM最大允許配置設定的堆記憶體,按需配置設定
vmOption[0].optionString = "-Xmx1024M";
//設定classpath
vmOption[1].optionString = "-Djava.class.path=./Test.jar";
JavaVMInitArgs vmInitArgs;
vmInitArgs.version = JNI_VERSION_1_8;
vmInitArgs.options = vmOption;
vmInitArgs.nOptions = nOptionCount;
//忽略無法識别jvm的情況
vmInitArgs.ignoreUnrecognized = JNI_TRUE;
//設定啟動類,注意分隔符為"/"
const char startClass[] = "test/Test";
//啟動方法,一般是main函數,當然可以設定成其他函數
const char startMethod[] = "main";
//加載JVM,注意需要傳入的字元串為LPCWSTR,指向一個常量Unicode字元串的32位指針,相當于const wchar_t*
HINSTANCE jvmDLL = LoadLibrary(jvmPath);
if (jvmDLL == NULL) {
cout << "加載JVM動态庫錯誤" << endl;
return false;
}
//初始化jvm實體位址
JNICREATEPROC jvmProcAddress = (JNICREATEPROC)GetProcAddress(jvmDLL, "JNI_CreateJavaVM");
if (jvmDLL == NULL) {
FreeLibrary(jvmDLL);
cout << "加載JVM動态庫錯誤" << endl;
return false;
}
//建立JVM
JNIEnv* env;
JavaVM* jvm;
jint jvmProc = (jvmProcAddress)(&jvm, (void**)&env, &vmInitArgs);
if (jvmProc < 0 || jvm == NULL || env == NULL) {
FreeLibrary(jvmDLL);
cout << "建立JVM錯誤" << endl;
return false;
}
//加載啟動類
jclass mainclass = env->FindClass(startClass);
if (env->ExceptionCheck() == JNI_TRUE || mainclass == NULL) {
env->ExceptionDescribe();
env->ExceptionClear();
FreeLibrary(jvmDLL);
cout << "加載啟動類失敗" << endl;
return false;
}
//加載啟動方法
jmethodID methedID = env->GetStaticMethodID(mainclass, startMethod, "([Ljava/lang/String;)V");
if (env->ExceptionCheck() == JNI_TRUE || methedID == NULL) {
env->ExceptionDescribe();
env->ExceptionClear();
FreeLibrary(jvmDLL);
cout << "加載啟動方法失敗" << endl;
cin >> pause;
return false;
}
cout << "開始執行" << endl;
env->CallStaticVoidMethod(mainclass, methedID, NULL);
cout << "執行結束" << endl;
//jvm釋放
jvm->DestroyJavaVM();
return true;
}
項目下載下傳