Java JNI-线程和作业对象的问题
我调用了一个本机程序,它创建了另一个线程,该线程将自身连接到JVM。现在我想访问JVM的方法,但失败了。代码如下:Java JNI-线程和作业对象的问题,java,c++,dll,jvm,java-native-interface,Java,C++,Dll,Jvm,Java Native Interface,我调用了一个本机程序,它创建了另一个线程,该线程将自身连接到JVM。现在我想访问JVM的方法,但失败了。代码如下: // // This is the native function that gets called first. // it creates another thread which runs, and also calls the printing-methods in my // java applet. // JNIEXPORT void JNICALL Java_EI
//
// This is the native function that gets called first.
// it creates another thread which runs, and also calls the printing-methods in my
// java applet.
//
JNIEXPORT void JNICALL Java_EIGC_1Applet_app_1native_native_1start(JNIEnv* jenv, jobject job) {
printAppletConsole(jenv,job,"unused atm");
// save current java VM;
// save main applet class;
// used by main thread
jenv->GetJavaVM(&applet_java_jvm);
m_job = job;
// create the working and start it
applet_thread_main = new EIGC_Applet_thread(&main);
applet_thread_main->start();
}
//
// This is the running thread that was created
// This will run and call the printing method in the applet
//
unsigned __stdcall main(void* args) {
// The JNIEnv
JNIEnv* jenv = new JNIEnv();
// attach thread to running JVM
applet_java_jvm->AttachCurrentThread((void**)jenv,NULL);
// main running loop
while (true) {
Sleep(1000);
printAppletConsole(jenv,m_job,"unused");
}
applet_thread_main->stop();
return 0;
}
//
// Calls the "writeConsole()" method in applet which prints "test" in a JTextArea
//
void printAppletConsole(JNIEnv* jenv,jobject job,char* text) {
jclass cls = jenv->GetObjectClass(job);
jmethodID mid = jenv->GetMethodID(cls,"writeConsole","()V");
if (mid==NULL) {
printf("Method not found");
}
else {
jenv->CallVoidMethod(job,mid);
}
}
我有一个问题
1) 在新创建的线程中,当我尝试调用printAppletConsole时,JVM挂起,它挂起在GetObjectClass()上。为什么会这样
我的怀疑是,由于我创建了一个新线程,我需要访问jobject的一个新实例,但我不确定如何
谢谢
m_job = job;
这只会保留本地引用,一旦返回java,本地引用就无效。您需要使用NewGlobalRef
创建一个全局引用并存储该引用
JNIEnv* jenv = new JNIEnv();
applet_java_jvm->AttachCurrentThread((void**)jenv,NULL);
应该是:
JNIEnv* jenv = 0:
applet_java_jvm->AttachCurrentThread(&jenv,NULL);
编辑:对于较旧的JNI版本,请使用:
JNIEnv* jenv = 0:
applet_java_jvm->AttachCurrentThread((void **) &jenv,NULL);
1.例如,打印控制台函数中的new_job=NewGlobalRef(m_job)?功能完成后是否必须删除新的_作业?2.你确定JNIEnv*的初始化吗?如果我执行JNIEnv*jenv=0,它就会崩溃,而且编译器不喜欢&jenv,因为它不是void**指针。谢谢你,先生!否,请在
Java\u EIGC\u 1Applet\u 1native\u native\u 1start中使用m\u job=jenv->NewGlobalRef(job)
。当您完成任务后,也可以调用jenv->DeleteGlobalRef(m_job)
。