2011-03-28 14 views
9

मैंने एक मूल कार्यक्रम कहा है जो एक और धागा बनाता है, जो खुद को 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_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 का एक नया उदाहरण का उपयोग करने की जरूरत है, लेकिन मैं निश्चित नहीं कैसे ..

धन्यवाद!

उत्तर

7
m_job = job; 

यह केवल स्थानीय संदर्भ को रखता है जो जैसे ही आप जावा पर वापस आते हैं। आपको 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); 
+0

1. तो उदाहरण new_job = NewGlobalRef (m_job) printConsole समारोह में के लिए? फ़ंक्शन पूरा होने के बाद मुझे new_job को हटाना होगा? 2. क्या आप जेएनआईएनएनवी * प्रारंभिकरण के बारे में निश्चित हैं? अगर मैं जेएनआईएनएनवी * जेएनवी = 0 करता हूं, और संकलक भी पसंद नहीं करता है और जेएनवी नहीं करता है, क्योंकि यह शून्य शून्य सूचक नहीं है। धन्यवाद महोदय! – KaiserJohaan

+1

नहीं, '__job = jenv-> NewGlobalRef (नौकरी)' 'Java_EIGC_1Applet_app_1native_native_1start' में उपयोग करें। जब आप पूरी तरह से इसके साथ काम कर रहे हों तो 'jenv-> DeleteGlobalRef (m_job)' को भी कॉल करें। – Erik

+0

मैं देखता हूं। बहुत धन्यवाद! – KaiserJohaan

संबंधित मुद्दे