JNI创建虚拟机失败(第一次可以,第二次调用失败)
jni创建虚拟机失败问题(为了调用Java类的方法,用VC写了DLL供别的程序调用,调用第二次提示失败),
C++调用JAVA代码如下:
#include<stdio.h>
#include"GoalSearch.h"
#include "windows.h"
#include "jni.h"
#include <string>
#include <iostream>
using namespace std;
JavaVM *jvm;
JNIEnv *env;
long* GoalSearch(const char szTest[])
{
jstring NewJString(JNIEnv *env, LPCTSTR str);
string JStringToCString (JNIEnv *env, jstring str);
//定义一个函数指针,下面用来指向JVM中的JNI_CreateJavaVM函数
typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, void *);
int res=0;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
/*设置初始化参数*/
//disable JIT,这是JNI文档中的解释,具体意义不是很清楚 ,能取哪些值也不清楚。
//从JNI文档里给的示例代码中搬过来的
options[0].optionString = "-Djava.compiler=NONE";
//设置classpath,如果程序用到了第三方的JAR包,也可以在这里面包含进来
options[1].optionString = "-Djava.class.path=.;C:\\test";
//设置显示消息的类型,取值有gc、class和jni,如果一次取多个的话值之间用逗号格开,如-verbose:gc,class
//该参数可以用来观察C++调用JAVA的过程,设置该参数后,程序会在标准输出设备上打印调用的相关信息
options[2].optionString = "-verbose:NONE";
//选择一个根你安装的JRE版本最近的版本号即可,不过你的JRE版本一定要等于或者高于指定的版本号
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 3;
vm_args.options = options;
//该参数指定是否忽略非标准的参数,如果填JNI_FLASE,当遇到非标准参数时,JNI_CreateJavaVM会返回JNI_ERR
vm_args.ignoreUnrecognized = JNI_TRUE;
//加载JVM.DLL动态库
HINSTANCE hInstance = ::LoadLibrary("C:\\jdk1.6.0_10\\jre\\bin\\client\\jvm.dll");
if (hInstance == NULL)
{
cout<<"Can not found 'JVM.DLL'!"<<endl;
return false;
}
else cout<<"Successfully find the JVM.dll..."<<endl;
//取得里面的JNI_CreateJavaVM函数指针
PFunCreateJavaVM funCreateJavaVM = (PFunCreateJavaVM)::GetProcAddress(hInstance, "JNI_CreateJavaVM");
cout<<"Successfully Create JAVAVM..."<<endl;
//调用JNI_CreateJavaVM创建虚拟机
res = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args);
//查找test.Demo类,返回JAVA类的CLASS对象
jclass cls = env->FindClass("GoalSearch");
if(cls!=0){
cout<<"Successfully get the class..."<<endl;
}
//根据类的CLASS对象获取该类的实例
//获取类中的方法,最后一个参数是方法的签名,通过javap -s -p filename可以获得
//Get the Constructor of the java class
jmethodID mid = env->GetMethodID(cls,"<init>","(Ljava/lang/String;)V");
if(mid!=0){
cout<<"Successfully get the constructor..."<<endl;
}
jstring arg = NewJString(env, szTest);
//Create an object of java class FindGoalID
jobject demo = env->NewObject(cls,mid,arg);
if(demo!=NULL){
cout<<"Successfully create an object..."<<endl;
}
//Get the method in java
mid = env->GetMethodID(cls, "getGoalID","()[I");
if(mid!=0){
cout<<"Successfully get the method..."<<endl;
}
//Get the array from java
jintArray arr =(jintArray) env->CallObjectMethod(demo,mid);
if(arr!=NULL){
cout<<"Successfully execute the mothod..."<<endl;
}
//Convent from jintArray to Array
int len = env->GetArrayLength(arr);
if(len>=0){
cout<<"Successfully get the length of the array..."<<endl;
}
jint* elems =env-> GetIntArrayElements(arr, 0);
for(int i=0; i<len; i++){
cout<<"ELEMENT "<<i<<" IS "<<elems[i]<<endl;
}
//Destroy the JVM.DLL
jvm->DestroyJavaVM();
cout<<"DestroyJVM"<<endl;
::FreeLibrary(hInstance);
return elems;
}
jstring NewJString(JNIEnv *env, LPCTSTR str)
{
if(!env || !str)
{
return 0;
}
int slen = strlen(str);
jchar* buffer = new jchar[slen];
int len = MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,slen);
if(len>0 && len < slen)
{
buffer[len]=0;
}
jstring js = env->NewString(buffer,len);
delete [] buffer;
return js;
}
int main(){
GoalSearch("I want a SUV");
GoalSearch("I want a SUV");
return 0;
}
第一次没有任何问题,在第二次调用的时候运行到res = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args);这一行时,res变成-1,所以一直失败,不知道是什么问题,请各位大侠帮忙解决一下