今天列出一个自己写的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!");
}
}