I'm not sure which section I should post this in, since the problem covers Java, C++ and .NET managed C++...
Anyway - I'm using some Java classes via JNI in unmanaged C++, then call the unmanaged C++ class from managed C++.
What I want to be able to do is create an object that uses JNI, then destroy it, then create and use another.
The problem is that the second time around funcCreateJavaV M returns -1 (unknown error). I figure I'm not disposing it properly the first time, but I'm not sure what I'm doing wrong. The call to DestroyJavaVM is in the destructor of the unmanaged class.
The unmanaged class looks something like this:
[CODE=cpp]//Path to jvm.dll
#define JVMDLLPATH "C:\\Progra m Files\\Java\\jd k1.6.0_04\\jre\ \bin\\client\\j vm.dll"
//Function type for JNI_CreateJavaV M
typedef UINT (CALLBACK* CreateJavaVM)(J avaVM**,void**, JavaVMInitArgs* );
class edoc
{
JNIEnv *env;
JavaVM *jvm;
HINSTANCE jvmdll;
JavaVMInitArgs vmargs;
public:
void init()
{
env = (JNIEnv*)malloc (sizeof(JNIEnv) );
jvm = (JavaVM*)malloc (sizeof(JavaVM) );
//Load jvm.dll
jvmdll = LoadLibrary(JVM DLLPATH);
//Initialize function variable for JNI_CreateJavaV M
CreateJavaVM funcCreateJavaV M;
funcCreateJavaV M = (CreateJavaVM)G etProcAddress(j vmdll,"JNI_Crea teJavaVM");
//Start JVM
JavaVMOption vmoptions[1];
vmargs.version= JNI_VERSION_1_6 ;
vmargs.nOptions =2;
vmoptions[0].optionString=V MOPTIONCLASSPAT H; //capitalized are macros containing paths
vmoptions[1].optionString=V MOPTIONPATH;
vmargs.options = vmoptions;
vmargs.ignoreUn recognized = JNI_FALSE;
funcCreateJavaV M(&jvm, (void**)&env, &vmargs);
//multiple calls to JVM via env go here - initialising jclass, jmethodID variables and the like
}
~edoc()
{
jvm->DestroyJavaVM( );
FreeLibrary(jvm dll);
}
};
The managed class looks something like this:
public ref class clrEDOC
{
edoc* ed;
public: clrEDOC()
{
ed = new edoc();
ed->init();
}
~clrEDOC()
{
ed->~edoc(); //used to be "delete ed;"
}
};
And the code that calls it is as follows (edocjni is the namespace):
void main()
{
edocjni::clrEDO C^ clred = gcnew edocjni::clrEDO C(); //executes properly
clred->~clrEDOC(); //used to be "delete clred;"
edocjni::clrEDO C^ ed = gcnew edocjni::clrEDO C(); //unknown error while creating JVM
}[/CODE]
Anyway - I'm using some Java classes via JNI in unmanaged C++, then call the unmanaged C++ class from managed C++.
What I want to be able to do is create an object that uses JNI, then destroy it, then create and use another.
The problem is that the second time around funcCreateJavaV M returns -1 (unknown error). I figure I'm not disposing it properly the first time, but I'm not sure what I'm doing wrong. The call to DestroyJavaVM is in the destructor of the unmanaged class.
The unmanaged class looks something like this:
[CODE=cpp]//Path to jvm.dll
#define JVMDLLPATH "C:\\Progra m Files\\Java\\jd k1.6.0_04\\jre\ \bin\\client\\j vm.dll"
//Function type for JNI_CreateJavaV M
typedef UINT (CALLBACK* CreateJavaVM)(J avaVM**,void**, JavaVMInitArgs* );
class edoc
{
JNIEnv *env;
JavaVM *jvm;
HINSTANCE jvmdll;
JavaVMInitArgs vmargs;
public:
void init()
{
env = (JNIEnv*)malloc (sizeof(JNIEnv) );
jvm = (JavaVM*)malloc (sizeof(JavaVM) );
//Load jvm.dll
jvmdll = LoadLibrary(JVM DLLPATH);
//Initialize function variable for JNI_CreateJavaV M
CreateJavaVM funcCreateJavaV M;
funcCreateJavaV M = (CreateJavaVM)G etProcAddress(j vmdll,"JNI_Crea teJavaVM");
//Start JVM
JavaVMOption vmoptions[1];
vmargs.version= JNI_VERSION_1_6 ;
vmargs.nOptions =2;
vmoptions[0].optionString=V MOPTIONCLASSPAT H; //capitalized are macros containing paths
vmoptions[1].optionString=V MOPTIONPATH;
vmargs.options = vmoptions;
vmargs.ignoreUn recognized = JNI_FALSE;
funcCreateJavaV M(&jvm, (void**)&env, &vmargs);
//multiple calls to JVM via env go here - initialising jclass, jmethodID variables and the like
}
~edoc()
{
jvm->DestroyJavaVM( );
FreeLibrary(jvm dll);
}
};
The managed class looks something like this:
public ref class clrEDOC
{
edoc* ed;
public: clrEDOC()
{
ed = new edoc();
ed->init();
}
~clrEDOC()
{
ed->~edoc(); //used to be "delete ed;"
}
};
And the code that calls it is as follows (edocjni is the namespace):
void main()
{
edocjni::clrEDO C^ clred = gcnew edocjni::clrEDO C(); //executes properly
clred->~clrEDOC(); //used to be "delete clred;"
edocjni::clrEDO C^ ed = gcnew edocjni::clrEDO C(); //unknown error while creating JVM
}[/CODE]
Comment