मेरे पास एक एंड्रॉइड ऐप है जहां ऐप शुरू होने पर निम्नलिखित सी विधि को कॉल किया जाता है (Activity.onCreate में)।

extern "C"
JNIEXPORT jstring JNICALL
Java_com_google_oboe_test_oboetest_MainActivity_stringFromJNI(
    JNIEnv *env,
    jobject instance) {

    jclass sysclazz = env->FindClass("java/lang/System");
    jmethodID getPropertyMethod = env->GetStaticMethodID(sysclazz, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
    jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, "os.name");
    return result;
}

जब इस विधि को ऐप क्रैश कहा जाता है और मुझे त्रुटि मिलती है:

आवेदन में जेएनआई का पता चला त्रुटि: हटाए गए स्थानीय संदर्भ 0xd280e8d5 का उपयोग

चरण डिबगिंग से पता चलता है कि यह रेखा दुर्घटना का कारण बनती है:

jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, "os.name");

इस त्रुटि का कारण क्या है? और मैं इस त्रुटि को प्राप्त किए बिना जेएनआई का उपयोग करके System.getProperty("os.name") को कैसे कॉल कर सकता हूं?

3
donturner 16 जुलाई 2018, 20:38

1 उत्तर

सबसे बढ़िया उत्तर

मुद्दा यह है कि env->CallStaticObjectMethod अपने तीसरे तर्क के रूप में jstring की अपेक्षा कर रहा है और इसके बजाय एक स्ट्रिंग अक्षर के साथ आपूर्ति की जा रही है।

पहले एक jstring बनाना

jstring arg = env->NewStringUTF("os.name");
jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, arg);

समस्या को ठीक किया।

10
donturner 16 जुलाई 2018, 20:52
DeleteLocalRef उदाहरण के लिए env->DeleteLocalRef(arg); और env->DeleteLocalRef(result); का उपयोग करके उन jstring वेरिएबल्स को मुक्त करना याद रखें अन्यथा आपके कोड के अंदर मेमोरी लीक हो जाएगी।
 – 
shizhen
17 जुलाई 2018, 06:33
3
@shizhen: आवश्यक नहीं है क्योंकि stringFromJNI जावा पर वापस आ जाएगा, जो स्वचालित रूप से बनाए गए स्थानीय संदर्भों को साफ़ कर देता है।
 – 
Michael
17 जुलाई 2018, 08:54
1
सैद्धांतिक रूप से यह सच है कि आपने JVM को आपके लिए उन स्थानीय रेफरी को रिलीज़ करने दिया। लेकिन, यह आपके कोड द्वारा बनाए गए स्थानीय संदर्भों को हटाने के लिए "सर्वोत्तम अभ्यास" की तरह होगा। क्योंकि, स्थानीय संदर्भ बहुत सारे जेवीएम संसाधनों का उपभोग करेंगे, खासकर जब आप इसे एक लंबे लूप के अंदर बनाते/उपयोग करते हैं, स्थानीय संदर्भों के अत्यधिक आवंटन से वीएम मूल विधि के निष्पादन के दौरान स्मृति से बाहर हो सकता है। इस मामले के लिए, यह इतना आसान है कि यह वास्तव में ज्यादा मायने नहीं रखता है। बेशक, यह वास्तव में आप पर निर्भर है कि आप ऐसा करना चाहते हैं या नहीं।
 – 
shizhen
17 जुलाई 2018, 10:48
 – 
shizhen
17 जुलाई 2018, 10:48
1
@EJP, हां, जैसा कि मैंने कहा, यह वास्तव में इस मामले के लिए बहुत मायने नहीं रखता है, स्थानीय संदर्भ को जल्द से जल्द हटाने के महत्व को बताने के लिए यह मामला बहुत आसान है। मैं यहां जो बात कहना चाहता हूं वह यह है कि इस कोडिंग अभ्यास को ध्यान में रखा जाए।
 – 
shizhen
17 जुलाई 2018, 11:19