问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何使用C++程序运行一个jar文件

发布网友 发布时间:2022-12-22 07:13

我来回答

1个回答

热心网友 时间:2024-10-23 18:27

首先需要先加载JVM,然后根据jar中的函数签名寻找到相应的函数,然后运行相应的函数

一段样例代码如下

#include <iostream>
#include <jni.h>
#include <windows.h>
#include <cstring>
#include <direct.h>
using namespace std;
#define  DIRLEN 10000

char* GetJrepath(int BIT);
int CallJAR(int BIT,char*buf,char*classPath,char*functionName);
int main(int argc, char *argv[])
{
char * buff = new char[DIRLEN];
getcwd(buff,DIRLEN);
strcat(buff,"\\lib\\support.jar");
if (argc<3)
{
cout<<"输入参数错误";
return 0;
}
int BIT = 32;
if(!strcmp(argv[2],"64"))
BIT = 64 ;
//-30 没有安装jre环境 -31 创建jvm失败 -32 缺少相关的库
if (!strcmp(argv[1],"0"))
{
//-20 配置文件错误  -21 JSON异常
return CallJAR(BIT,buff,"com/run/Author","StartAuthor");
}
else if(!strcmp(argv[1],"1"))
{
return CallJAR(BIT,buff,"com/run/UpdateStatus","UpdateStatus1");
}
else if(!strcmp(argv[1],"2"))
{
return CallJAR(BIT,buff,"com/run/SendMsg_webchinese","SendSMS");
}
else
{
return CallJAR(BIT,buff,"com/run/UpdateStatus","UpdateANDSMS");
}

}
char* GetJrepath(int BIT)
{
#define MYBUFF 123
    HKEY hKey;
    long lRet;
    char* dir = new char[MYBUFF];
    DWORD dwBufLen = MYBUFF;
    char* s = new char[MYBUFF];
    if(BIT == 64)
        strcpy(s,"SOFTWARE\\Wow6432Node\\JavaSoft\\Java Runtime Environment\\");
    else
        strcpy(s,"SOFTWARE\\JavaSoft\\Java Runtime Environment\\");
    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        TEXT((TCHAR*)s),
        0,
        KEY_QUERY_VALUE,
        &hKey);
    if(lRet!=ERROR_SUCCESS)
        return NULL;
    lRet = RegQueryValueEx(hKey,
        TEXT((TCHAR*)"CurrentVersion"),
        NULL,
        NULL,
        (LPBYTE)dir,
        &dwBufLen);
    RegCloseKey(hKey);
    if(lRet!=ERROR_SUCCESS)
        return NULL;
    strcat(s,dir);

    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        TEXT((TCHAR*)s),
        0,
        KEY_QUERY_VALUE,
        &hKey);
    if(lRet!=ERROR_SUCCESS)
        return NULL;
    dwBufLen = MYBUFF;
    lRet = RegQueryValueEx(hKey,
        TEXT((TCHAR*)"RuntimeLib"),
        NULL,
        NULL,
        (LPBYTE)dir,
        &dwBufLen);
    RegCloseKey(hKey);
    if(lRet!=ERROR_SUCCESS)
        return NULL;
    return dir;
}
int CallJAR(int BIT,char*buf,char*classPath,char*functionName)
{
typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, void *);  

    int res;  
    JavaVMInitArgs vm_args;  
    JavaVMOption options[3];  
    JavaVM *jvm;  
    JNIEnv *env;  
int len =strlen("-Djava.class.path=.;")+strlen(buf)+20;
char* temp = new char[len];
strcpy(temp,"-Djava.class.path=.;");
strcat(temp,buf);
    /*设置初始化参数*/  
    //disable JIT,这是JNI文档中的解释,具体意义不是很清楚 ,能取哪些值也不清楚。  
    //从JNI文档里给的示例代码中搬过来的  
    options[0].optionString = "-Djava.compiler=NONE";  
    //设置classpath,如果程序用到了第三方的JAR包,也可以在这里面包含进来  
    options[1].optionString = temp;  
    //设置显示消息的类型,取值有gc、class和jni,如果一次取多个的话值之间用逗号格开,如-verbose:gc,class  
    //该参数可以用来观察C++调用JAVA的过程,设置该参数后,程序会在标准输出设备上打印调用的相关信息  
    options[2].optionString = "-verbose:NONE";  

    //设置版本号,版本号有JNI_VERSION_1_1,JNI_VERSION_1_2和JNI_VERSION_1_4  
    //选择一个根你安装的JRE版本最近的版本号即可,不过你的JRE版本一定要等于或者高于指定的版本号  
    vm_args.version = JNI_VERSION_1_4;  
    vm_args.nOptions = 3;  
    vm_args.options = options;  
    //该参数指定是否忽略非标准的参数,如果填JNI_FLASE,当遇到非标准参数时,JNI_CreateJavaVM会返回JNI_ERR  
    vm_args.ignoreUnrecognized = JNI_TRUE;  
    //加载JVM.DLL动态库  
    HINSTANCE hInstance = ::LoadLibrary(GetJrepath(BIT));  
    if (hInstance == NULL)  
    {  
        return -30;  
    }  
    //取得里面的JNI_CreateJavaVM函数指针  
    PFunCreateJavaVM funCreateJavaVM = (PFunCreateJavaVM)::GetProcAddress(hInstance, "JNI_CreateJavaVM");  
    //调用JNI_CreateJavaVM创建虚拟机  
    res = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args);  
    if (res < 0)  
    {  
        return -31;  
    }  
    //查找test.Demo类,返回JAVA类的CLASS对象  
    jclass cls = env->FindClass(classPath);  
    //根据类的CLASS对象获取该类的实例  
if (cls==0)
{
printf("FindClass failed\n");
(jvm)->DestroyJavaVM(); 
return -32;
}
    jobject obj = env->AllocObject(cls);  

    //获取类中的方法,最后一个参数是方法的签名,通过javap -s -p -classpath 路径 文件名
    jmethodID mid = env->GetMethodID(cls, functionName,"()I");  
    if (mid==0)
    {
printf("getMethodID failed\n");
(jvm)->DestroyJavaVM(); 
return -32;
    }
//构造参数并调用对象的方法  
    
    
    jstring msg = (jstring) env->CallObjectMethod(obj, mid);  


    //销毁虚拟机并释放动态库  
    jvm->DestroyJavaVM();  
    ::FreeLibrary(hInstance);  
    return (int)msg;
}

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
梦到老婆生下儿子一生下儿子就活蹦乱跳 痤疮的抗生素治疗 胸前皮肤痒如何止痒 马拉色菌毛囊炎 面部怎么清洗? NYC 指数是什么意思? 扬州学区多久划分一次 为什么磁铁的磁场是电磁线的磁场呢? 为什么国内求职很少有overqualified这种说法? ...表示你已经做好了工作的准备,同时怎么让面试官对你有个好的第一印... ...同日本及西欧关系的演变,并简述其对世界和中国的影响。 教育与儿童发展的关系是 我今天发了一个文件给朋友 是个压缩包来的 也就14MB 我添加文件,后来到... 辽宁经济职业技术学院的QQ群,谢谢. 对方是以老百姓家包来的工成,我去做了没&#x2CA1;完的工资怎么为?老披不想... 心目中的高中小学作文 百家姓中包是怎么来的 柠檬树积水叶子掉光了怎么救? 请问这个牌子的衣服好吗??? 期货从业资格考试方式,时间,题型和计分情况是怎么的 我想问的是……那位大神知道现在写小说在那个网站比较好啊?,,求详 ... 面膜是用好还是不用好? 钟丽缇女儿考拉的爸爸是谁 钟丽缇张伦硕有孩子吗 15-18米径的白蜡需要生长多长时间 手机APP的超级应用究竟是为了啥? 怎么编vb恶搞程序 空气压缩机的问题 ! 汽车“油改气” 听说山东东营的天然气改装要听改了有确切消息吗? 车辆改装天然气需要办理什么手续 济南思明特科技有限公司怎么样? 领着包来做的事是雇佣关系还是承揽关系 java对so库和jar哪个调用快,里面封装类似功能的话 披萨的做法芝士披萨怎么做 除蝇小妙招 如何去除苍蝇 易烊千玺晒照告别韦一航,《送你一朵小红花》中他的演技怎么样? 手柄上power和mode 请问歇后语捏着槌子旧海角~有点辣手 手柄开启mode才能换视角 解释歇后语,捏锤子春海椒,有点辣手 捏着槌子舂海椒---有点辣手在十二生肖中指的是那个 捏着槌子春海椒,有点辡手。解一生肖 捏着槌子舂海椒--有点辣手 ?? 这句话的意思是说十二生肖哪个肖呢? 说 ... 歇后语捏着槌子舂海椒---有点辣手指哪个生肖请说明理由谢谢 修改对联 身系职教几度春秋以人为本 心怀综艺数载寒暑以校为家_百度... 哪些省市的简称和别称一样呢? 中通快递到运转中心,还要多长时间到武侯 中国有姓柚的吗? 沉香泡水里有柚吗 ...偶起个4字男游戏网名,低调一点的偶练得是梦幻诛仙里的青云,不要火星... 梦幻诛仙焚香谷网名