今天列出一个自己写的jni类,主要是自己当时c++要调用java程序
#pragma once
#include "jni.h"
class JNIOperator
{
public:
JNIOperator(void);
~JNIOperator(void);
private:
BOOL ReadJVMDLLPath(TCHAR tJvmDllPath[MAX_PATH]);
BOOL ReadClassPath(TCHAR tClassPath[MAX_PATH]);
BOOL ReadLibPath(TCHAR tLibPath[MAX_PATH]);
BOOL ReadClassConfigPath(TCHAR tClassPath[MAX_PATH]);
/*C字符串转JNI字符串*/
jstring stringtoJstring(JNIEnv* env, const char* pat);
/*JNI字符串转C字符串*/
char* jstringTostring(JNIEnv* env, jstring jstr);
public:
BOOL JNIInit();
BOOL JNIClose();
BOOL JNIFindClass();
BOOL JNIGetAndExecuteBooleanMethod();
BOOL JNIGetAndExecuteStaticBooleanMethod();
string JNIGetAndExecuteStringMethod();
string JNIGetAndExecuteStringParamMethod(string str,int jk);
void JNIGetAndExecuteStaticMainMethod(string str);//([Ljava/lang/String;)V
void JNIDeinit();
void ExeBat();
void ExeNode1();
void ExeNode2();
BOOL ReadJavaExePath(TCHAR tJavaExePath[MAX_PATH]);
private:
string classpath;
protected:
static JNIEnv* env;
static JavaVM* jvm;
static jclass cls;
};
extern JNIOperator jni;
//下面是cpp实现
#include "stdafx.h" #include "JNIOperator.h" #include "UnicodeToAscii.h" //声明全局变量 JNIEnv*JNIOperator::env=NULL; JavaVM*JNIOperator::jvm=NULL; jclass JNIOperator::cls=NULL; #ifdef tuoli //定义一个函数指针,下面用来指向JVM中的JNI_CreateJavaVM函数 typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, void *); HINSTANCE hInstance=NULL; #endif JNIOperator jni; //256/512,xms和xmx的值最好一样,在服务器上面。否则容易造成内存溢出 //最小内存 static char MinMB[] = "-Xms1024M"; //最大内存 static char MaxMB[] = "-Xmx1024M"; JNIOperator::JNIOperator(void) { } JNIOperator::~JNIOperator(void) { JNIDeinit(); } void JNIOperator::JNIDeinit() { JNIClose(); #ifdef tuoli ::FreeLibrary(hInstance); #endif } /*C字符串转JNI字符串*/ jstring JNIOperator::stringtoJstring(JNIEnv* env, const char* pat) { jclass strClass = env->FindClass("Ljava/lang/String;"); jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); jbyteArray bytes = env->NewByteArray(strlen(pat)); env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); jstring encoding = env->NewStringUTF("utf-8"); jstring rstStr =(jstring) env->NewObject(strClass, ctorID, bytes, encoding); return rstStr; } char* JNIOperator::jstringTostring(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); return rtn; } BOOL JNIOperator::ReadClassPath(TCHAR tClassPath[MAX_PATH]) { TCHAR FPath[MAX_PATH]; ZeroMemory(FPath,sizeof(FPath)); ::GetCurrentDirectory(MAX_PATH, FPath); lstrcat(FPath, L"\\Config.ini"); GetPrivateProfileString(L"CLASSPATH", L"classpath", L"", tClassPath, MAX_PATH, FPath); if(!lstrlen(tClassPath)) { return FALSE; } return TRUE; } BOOL JNIOperator::ReadLibPath(TCHAR tLibPath[MAX_PATH]) { TCHAR FPath[MAX_PATH]; ZeroMemory(FPath,sizeof(FPath)); ::GetCurrentDirectory(MAX_PATH, FPath); lstrcat(FPath, L"\\Config.ini"); GetPrivateProfileString(L"LIBPATH", L"libpath", L"", tLibPath, MAX_PATH, FPath); if(!lstrlen(tLibPath)) { return FALSE; } return TRUE; } BOOL JNIOperator::JNIClose() { env->DeleteLocalRef(cls); if (!jvm->DestroyJavaVM()) { return TRUE; } return FALSE; } BOOL JNIOperator::JNIInit() { TCHAR tClassPath[MAX_PATH]; ZeroMemory(tClassPath,sizeof(tClassPath)); if (!ReadClassPath(tClassPath)) { return FALSE; } TCHAR tLibPath[MAX_PATH]; ZeroMemory(tLibPath,sizeof(tLibPath)); if (!ReadLibPath(tLibPath)) { return FALSE; } JavaVMOption options[8]; JavaVMInitArgs vm_args; long status; jclass cls; jmethodID mid; jint square; jboolean not; UnicodeToAscii u2a; // options[0].optionString = "-Djava.compiler=NONE"; char* pLibPath=u2a.WcharToChar(tLibPath); cout<<pLibPath<<endl; options[1].optionString = pLibPath; //options[1].optionString = "-Djava.library.path=."; char* pClassPath=u2a.WcharToChar(tClassPath); cout<<pClassPath<<endl; options[2].optionString = pClassPath; //options[2].optionString = "-Djava.class.path=C:\\Program Files\\Java\\jdk1.7.0_80\\jre\\bin\\server\\testc.jar"; options[3].optionString = "-verbose"; //设置JVM最大允许分配的堆内存,按需分配 options[4].optionString = MinMB; //-Xmx1200m -XX:MaxPermSize=512m options[5].optionString = MaxMB; //-Xmx1200m -XX:MaxPermSize=512m //modify at 2017-4-10 options[6].optionString = "-XX:NewRatio=1"; options[7].optionString = "-XX:MaxGCPauseMillis=28"; // memset(&vm_args, 0, sizeof(vm_args)); vm_args.version = JNI_VERSION_1_8; vm_args.nOptions = 8; vm_args.options = options; vm_args.ignoreUnrecognized = JNI_TRUE; #ifdef tuoli //定义一个函数指针,下面用来指向JVM中的JNI_CreateJavaVM函数 typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, void *); //加载JVM.DLL动态库 测试exe脱离jre同一级目录限制测试 //string pPath="C://Program Files//Java//jdk1.7.0_80//jre//bin//server//jvm.dll"; //借用strcpy将const char* 转换为char * //char *buf = new char[strlen(pPath.c_str())+1]; //strcpy(buf, pPath.c_str()); //TCHAR* ppPath=u2a.CharToWchar(buf); TCHAR ppPath[MAX_PATH]; ZeroMemory(ppPath,sizeof(ppPath)); if (!ReadJVMDLLPath(ppPath)) { return FALSE; } HINSTANCE hInstance = ::LoadLibrary(ppPath); if (hInstance == NULL) { return false; } //取得里面的JNI_CreateJavaVM函数指针 PFunCreateJavaVM funCreateJavaVM = (PFunCreateJavaVM)::GetProcAddress(hInstance, "JNI_CreateJavaVM"); //调用JNI_CreateJavaVM创建虚拟机 status = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args); #else status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); #endif if (status!=JNI_ERR) { return TRUE; } return FALSE; } BOOL JNIOperator::ReadClassConfigPath(TCHAR tClassConfigPath[MAX_PATH]) { TCHAR FPath[MAX_PATH]; ZeroMemory(FPath,sizeof(FPath)); ::GetCurrentDirectory(MAX_PATH, FPath); lstrcat(FPath, L"\\Config.ini"); GetPrivateProfileString(L"CLASSCONFIGPATH", L"classconfigpath", L"", tClassConfigPath, MAX_PATH, FPath); if(!lstrlen(tClassConfigPath)) { return FALSE; } return TRUE; } BOOL JNIOperator::JNIFindClass() { TCHAR tClassConfigPath[MAX_PATH]; ZeroMemory(tClassConfigPath,sizeof(tClassConfigPath)); if (!ReadClassConfigPath(tClassConfigPath)) { return FALSE; } UnicodeToAscii u2a; char* pClassConfigPath=u2a.WcharToChar(tClassConfigPath); cout<<pClassConfigPath<<endl; cls=env->FindClass(pClassConfigPath); if (cls!=0) { cout<<"find class successful!"<<endl; return TRUE; } return FALSE; } BOOL JNIOperator::JNIGetAndExecuteBooleanMethod() { jmethodID mid; jboolean not; //根据类的CLASS对象获取该类的实例 jobject obj = env->AllocObject(cls); mid = env->GetMethodID(cls,"booleanMethodA","()Z"); // if(mid !=0) { not=env->CallBooleanMethod(obj,mid); printf("Result of booleanMethod:%d\n", not); //释放资源 env->DeleteLocalRef(obj); // return TRUE; } return FALSE; } BOOL JNIOperator::JNIGetAndExecuteStaticBooleanMethod() { jmethodID mid; jboolean not; mid = env->GetStaticMethodID(cls, "booleanMethod", "(Z)Z") ; if(mid !=0) { not = env->CallStaticBooleanMethod(cls, mid, 1); printf("Result of staticbooleanMethod: %d\n", not); return TRUE; } return FALSE; } BOOL JNIOperator::ReadJVMDLLPath(TCHAR tJvmDllPath[MAX_PATH]) { TCHAR FPath[MAX_PATH]; ZeroMemory(FPath,sizeof(FPath)); ::GetCurrentDirectory(MAX_PATH, FPath); lstrcat(FPath, L"\\Config.ini"); GetPrivateProfileString(L"DLLPATH", L"dllpath", L"", tJvmDllPath, MAX_PATH, FPath); if(!lstrlen(tJvmDllPath)) { return FALSE; } return TRUE; } string JNIOperator::JNIGetAndExecuteStringMethod() { jmethodID mid; //根据类的CLASS对象获取该类的实例 jobject obj = env->AllocObject(cls); mid=env->GetMethodID(cls,"getMessage","()Ljava/lang/String;"); if (mid!=0) { jstring msg = (jstring)env->CallObjectMethod(obj, mid); string pmsg=jstringTostring(env, msg); //unicode工程,需要转换才能显示 UnicodeToAscii u2a; //借用strcpy将const char* 转换为char * char *buf = new char[strlen(pmsg.c_str())+1]; strcpy(buf, pmsg.c_str()); TCHAR* pmsgtemp=u2a.CharToWchar(buf); cout<<pmsgtemp<<endl; wprintf(L"getMessage=%s\n",pmsgtemp); // printf("getMessage=%s\n",pmsg.c_str()); //释放资源 env->DeleteLocalRef(msg); // return pmsg; } return ""; } string JNIOperator::JNIGetAndExecuteStringParamMethod(string str,int jk) { jmethodID mid; //根据类的CLASS对象获取该类的实例 jobject obj = env->AllocObject(cls); mid=env->GetMethodID(cls,"getMessageA","(Ljava/lang/String;I)Ljava/lang/String;"); if (mid!=0) { jstring msg = (jstring)env->CallObjectMethod(obj, mid,stringtoJstring(env,str.c_str()),jk); string pmsg=jstringTostring(env, msg); printf("getMessageA=%s\n",pmsg.c_str()); //释放资源 env->DeleteLocalRef(msg); // return pmsg; } return ""; } void JNIOperator::JNIGetAndExecuteStaticMainMethod(string str) { // jmethodID mid; mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V") ; if(mid !=0) { env->CallStaticVoidMethod(cls, mid, ""); printf("main exec success\n"); } else { printf("main exec failer\n"); } } BOOL JNIOperator::ReadJavaExePath(TCHAR tJavaExePath[MAX_PATH]) { TCHAR FPath[MAX_PATH]; ZeroMemory(FPath,sizeof(FPath)); ::GetCurrentDirectory(MAX_PATH, FPath); lstrcat(FPath, L"\\Config.ini"); GetPrivateProfileString(L"JAVAEXEPATH", L"javapath", L"", tJavaExePath, MAX_PATH, FPath); if(!lstrlen(tJavaExePath)) { return FALSE; } return TRUE; } void JNIOperator::ExeBat() { InitLogName("javaexe"); /*TCHAR ppPath[MAX_PATH]; ZeroMemory(ppPath,sizeof(ppPath)); if (!ReadJavaExePath(ppPath)) { Log(L_ERROR,"ReadJavaExePath failer!"); return; }*/ SHELLEXECUTEINFO ShellInfo; memset(&ShellInfo, 0, sizeof(ShellInfo)); ShellInfo.cbSize = sizeof(ShellInfo); ShellInfo.hwnd = NULL; ShellInfo.lpVerb = L"open"; ShellInfo.lpFile = L"cmd.exe"; //ShellInfo.lpFile = L"F:\\tool\\tool\\java\\start_myhttpd.bat"; // 此处写执行文件的绝对路径 //ShellInfo.lpFile = ppPath; // 此处写执行文件的绝对路径 ShellInfo.lpParameters = L"/K java -jar myhttpd.jar";//参数,多个参数用空格隔开(para1和para2是字符串);参数也可以是一个LPCWSTR类型的变量,写法:ShellInfo.lpParameters = 变量名; //ShellInfo.lpParameters = L"/C F:\tool\tool\java\start_myhttpd.bat"; ShellInfo.nShow = SW_HIDE; ShellInfo.fMask = SEE_MASK_NOCLOSEPROCESS; BOOL bResult = ShellExecuteEx(&ShellInfo);//调用exe程序 if(bResult) { Log(L_ERROR,"exe sussess!"); }else { Log(L_ERROR,"exe failer!"); } } void JNIOperator::ExeNode1() { SHELLEXECUTEINFO ShellInfo; memset(&ShellInfo, 0, sizeof(ShellInfo)); ShellInfo.cbSize = sizeof(ShellInfo); ShellInfo.hwnd = NULL; ShellInfo.lpVerb = L"open"; ShellInfo.lpFile = L"cmd.exe"; ShellInfo.lpParameters = L"/K forever start policyServer.js";//参数,多个参数用空格隔开(para1和para2是字符串);参数也可以是一个LPCWSTR类型的变量,写法:ShellInfo.lpParameters = 变量名; //ShellInfo.lpParameters = L"/C F:\tool\tool\java\start_myhttpd.bat"; ShellInfo.nShow = SW_HIDE; ShellInfo.fMask = SEE_MASK_NOCLOSEPROCESS; BOOL bResult = ShellExecuteEx(&ShellInfo);//调用exe程序 if(bResult) { Log(L_ERROR,"exe sussess!"); }else { Log(L_ERROR,"exe failer!"); } } void JNIOperator::ExeNode2() { SHELLEXECUTEINFO ShellInfo; memset(&ShellInfo, 0, sizeof(ShellInfo)); ShellInfo.cbSize = sizeof(ShellInfo); ShellInfo.hwnd = NULL; ShellInfo.lpVerb = L"open"; ShellInfo.lpFile = L"cmd.exe"; ShellInfo.lpParameters = L"/K forever start gps.js";//参数,多个参数用空格隔开(para1和para2是字符串);参数也可以是一个LPCWSTR类型的变量,写法:ShellInfo.lpParameters = 变量名; //ShellInfo.lpParameters = L"/K F:\tool\tool\java\start_myhttpd.bat"; ShellInfo.nShow = SW_HIDE; ShellInfo.fMask = SEE_MASK_NOCLOSEPROCESS; BOOL bResult = ShellExecuteEx(&ShellInfo);//调用exe程序 if(bResult) { Log(L_ERROR,"exe sussess!"); }else { Log(L_ERROR,"exe failer!"); } }