古詩詞大全網 - 藝術簽名 - 如何用C++程序運行jar文件

如何用C++程序運行jar文件

首先需要加載JVM,然後根據jar中的函數簽名找到對應的函數,然後運行對應的函數。

示例代碼如下

#包含?& ltiostream & gt

#包含?& ltjni.h & gt

#包含?& ltwindows.h & gt

#包含?& ltcstring & gt

#包含?& ltdirect.h & gt

使用?命名空間?std

#定義?迪倫?10000

char*?GetJrepath(int?位);

int?CallJAR(int?BIT,char*buf,char*classPath,char * function name);

int?main(int?argc,?夏爾?*argv[])

{

夏爾?*?buff?=?新的?char[DIRLEN];

getcwd(buff,DIRLEN);

strcat(buff," \ \ lib \ \ support . jar ");

如果?(argc & lt3)

{

cout & lt& lt”錯誤的輸入參數”;

回歸?0;

}

int?比特?=?32;

如果(!strcmp(argv[2]," 64 "))

比特?=?64?;

//-30?沒有安裝jre環境?-31?創建jvm失敗?-32?缺少相關庫。

如果?(!strcmp(argv[1]," 0 "))

{

//-20?配置文件錯誤?-21?JSON異常

回歸?CallJAR(BIT,buff," com/run/Author "," start Author ");

}

不然呢?如果(!strcmp(argv[1]," 1 "))

{

回歸?CallJAR(BIT,buff," com/run/UpdateStatus "," UpdateStatus 1 ");

}

不然呢?如果(!strcmp(argv[1]," 2 "))

{

回歸?CallJAR(BIT,buff," com/run/SendMsg_webchinese "," send SMS ");

}

其他

{

回歸?CallJAR(BIT,buff," com/run/UpdateStatus "," UpdateANDSMS ");

}

}

char*?GetJrepath(int?位)

{

#定義?MYBUFF?123

HKEY?hKey

龍?lRet

char*?dir?=?新的?char[my buff];

DWORD?dwBufLen?=?MYBUFF

char*?s?=?新的?char[my buff];

如果(位?==?64)

strcpy(s," SOFTWARE \ \ wow 6432 node \ \ Java soft \ \ Java?運行時?環境\ \ ";

其他

strcpy(s," SOFTWARE\\JavaSoft\\Java?運行時?環境\ \ ";

lRet?=?RegOpenKeyEx(HKEY _ LOCAL _ MACHINE,

正文((TCHAR*)s),

0,

關鍵字查詢值,

& amphKey);

if(lRet!=錯誤_成功)

回歸?NULL

lRet?=?RegQueryValueEx(hKey,

文本((TCHAR*)“當前版本”),

空,

空,

(LPBYTE)dir,

& ampdwBufLen);

RegCloseKey(hKey);

if(lRet!=錯誤_成功)

回歸?NULL

strcat(s,dir);

lRet?=?RegOpenKeyEx(HKEY _ LOCAL _ MACHINE,

正文((TCHAR*)s),

0,

關鍵字查詢值,

& amphKey);

if(lRet!=錯誤_成功)

回歸?NULL

dwBufLen?=?MYBUFF

lRet?=?RegQueryValueEx(hKey,

正文((TCHAR *)“runtime lib”),

空,

空,

(LPBYTE)dir,

& ampdwBufLen);

RegCloseKey(hKey);

if(lRet!=錯誤_成功)

回歸?NULL

回歸?dir

}

int?CallJAR(int?BIT,char*buf,char*classPath,char*functionName)

{

typedef?金特?(WINAPI?*PFunCreateJavaVM)(JavaVM?**,?作廢?**,?作廢?*);?

int?res?

JavaVMInitArgs?vm _ args?

JavaVMOption?選項[3];?

JavaVM?* jvm?

JNIEnv?* env?

int?萊恩。=strlen("-Djava.class.path=。;")+strlen(buf)+20;

char*?臨時工?=?新的?char[len];

strcpy(temp,"-Djava.class.path=。;");

strcat(temp,buf);

/*設置初始化參數*/?

//禁用?JIT,這是JNI文檔中的解釋,具體意思不是很清楚嗎?不清楚可以取哪些值。?

//來自JNI文檔中給出的示例代碼?

選項[0]。optionString?=?"-DJ ava . compiler = NONE ";?

//設置類路徑。如果程序使用第三方JAR包,也可以包含在裏面?

選項[1]。optionString?=?溫度;?

//設置顯示消息的類型。這些值是gc、class和jni。如果壹次選擇了多條消息,這些值用逗號分隔,例如-verbose:gc,class?

//這個參數可以用來觀察C++調用JAVA的過程。設置此參數後,程序將在標準輸出設備上打印調用信息?

選項[2]。optionString?=?"-詳細:無";?

//設置版本號,包括JNI _版本_1_1,JNI _版本_1_2,JNI _版本_1_4?

//只需選擇妳安裝的JRE版本的最新版本號,但妳的JRE版本必須等於或高於指定的版本號?

vm_args.version?=?JNI _版本_ 1 _ 4;?

vm _ args.nOptions?=?3;?

vm_args.options?=?選項;?

//此參數指定是否忽略非標準參數。如果填充了JNI_FLASE,JNI_CreateJavaVM在遇到非標準參數時會返回JNI_ERR。

vm_args.ignoreUnrecognized?=?JNI _真的;?

//加載JVM.DLL動態庫?

HINSTANCE?hInstance?=?*加載庫(GetJrepath(BIT));?

如果?(hInstance?==?NULL)?

{?

回歸?-30;?

}?

//獲取裏面的JNI_CreateJavaVM函數指針?

PFunCreateJavaVM?funCreateJavaVM?=?(PFunCreateJavaVM)::GetProcAddress(h instance," JNI _ CreateJavaVM ");?

//調用JNI_CreateJavaVM創建虛擬機?

res?=?(*funCreateJavaVM)。jvm,?(void * *)& amp;env,?& ampVM _ args);?

如果?(res?& lt?0)?

{?

回歸?-31;?

}?

//找到測試。演示類並返回JAVA類的類對象。

jclass?cls?=?env->;FindClass(類路徑);?

//根據類的類對象獲取類的實例?

如果?(cls==0)

{

printf("FindClass?失敗\ n ");

(JVM)-& gt;DestroyJavaVM();?

回歸?-32;

}

job object?obj?=?env->;alloc object(cls);?

//獲取類中的方法。最後壹個參數是方法的簽名,通過javap?-s?-p?-類路徑?路徑?文件名

jmethodID?mid?=?env->;GetMethodID(cls,functionName,"()I ");?

如果?(mid==0)

{

printf("getMethodID?失敗\ n ");

(JVM)-& gt;DestroyJavaVM();?

回歸?-32;

}

//構造參數,調用對象的方法?

jstring?味精?=?(jstring)?env->;CallObjectMethod(obj,mid);?

//銷毀虛擬機,釋放動態庫?

JVM-& gt;DestroyJavaVM();?

*免費圖書館(hInstance);?

回歸?(int)msg;

}