2009-07-22 18 views
11

का उपयोग कर मूल विधियों से शून्य लौट रहा है मेरे पास कुछ मूल कोड है जो जावा पक्ष पर एक jbyteArray (इसलिए बाइट []) देता है और मैं शून्य वापस करना चाहता हूं। हालांकि, अगर मैं jbyteArray के स्थान पर 0 वापस लौटाता हूं तो मैं समस्याओं में भाग लेता हूं।जेएनआई

कुछ अधिक जानकारी: मुख्य तर्क जावा में है, देशी विधि एक बाइट धारा में कुछ डेटा सांकेतिक शब्दों में बदलना करने के लिए प्रयोग किया जाता है। मत पूछो .. इसे इस तरह किया जाना है। हाल ही में, मूल कोड को थोड़ा बदलना पड़ा और अब यह बहुत ही भयंकर धीमी गति से चल रहा है। कुछ प्रयोगों के बाद, जिसमें वापसी से पहले मूल विधि में सभी कोडों को टिप्पणी करने में शामिल था, यह पता चला कि 0 लौटने से मंदी का कारण बनता है। एक वास्तविक jbyteArray लौटने पर, सबकुछ ठीक है।

मेरी कोड के लिए विधि हस्ताक्षर:

सी ++ तरफ:

extern "C" JNIEXPORT jbyteArray JNICALL Java_com_xxx_recode (JNIEnv* env, jclass java_this, jbyteArray origBytes, jobject message) 

जावा तरफ:

jbyteArray javaArray; 
if (error != ERROR) { 
    // convert to jbyteArray 
    javaArray = env->NewByteArray((jsize) message.size); 
    env->SetByteArrayRegion(java_array, 0, message.size, reinterpret_cast<jbyte*>(message.buffer())); 
    if (env->ExceptionOccurred()) { 
     env->ExceptionDescribe(); 
     error = ERROR; 
    } 
} 
if (error == ERROR) { 
    return 0; // Does NOT work - doesn't crash, just slows everything down horrible. 
} 
else { 
    return javaArray; // Works perfectly. 
} 
:

private static native byte[] recode(byte[] origBytes, Message message); 

मूल कोड कुछ इस तरह दिखता

कोई भी करता है किसी भी कारण से पता चल सकता है कि यह हो सकता है? क्या यह jbyteArray के स्थान पर मूल विधि से NULL को वापस करने के लिए मान्य है, या जावा पर वापस वापस लौटने के लिए एक और प्रक्रिया है। दुर्भाग्य से, मुझे Google पर कोई भाग्य नहीं था।

धन्यवाद!

संपादित करें: अतिरिक्त जानकारी जोड़ा गया।

+0

आप सरणी के बजाय 0 क्यों लौट रहे हैं? आप बस खाली सरणी क्यों नहीं लौट सकते? कृपया इस मूल पुस्तकालय को क्या करना है इसके बारे में कुछ और जानकारी दें। – amischiefr

+0

क्या आप कुछ कोड पोस्ट कर सकते हैं, कम से कम विधि हस्ताक्षर और ऐसे? –

+0

खैर, मैं विशेष रूप से जावा को "शून्य" प्राप्त करना चाहता हूं, खाली बाइट सरणी नहीं।मैं _could_ उस के साथ काम करने के लिए जावा कोड को फिर से लिखता हूं, लेकिन यदि संभव हो तो मैं वास्तव में नहीं बल्कि वास्तव में नहीं चाहूंगा। मैंने विधि हस्ताक्षर जोड़े। – Dan

उत्तर

-1

मुझे नल लौटने का समाधान पसंद नहीं है। आप कुछ खाली कार्यान्वयन लौटना चाहिए यदि संभव हो तो जैसे

return new ArrayList(); 
return new byte[0]; 
return new EmptySomeObjectImpl(); 

से आप NullPointerExceptions

if (error == ERROR) { 
    return env->NewByteArray(0); 
} 

संपादित करें के बारे में चिंतित नहीं है

कोशिश यह हमेशा वापस जाने के लिए अगर आप न EmptyObjects लागू करना चाहते हैं । आप, वापस जाने के लिए जब 'कुछ भी नहीं' लौटने को छोड़कर वस्तु के प्रकार पर फैसला कभी नहीं:

if (error == ERROR) { 
    return javaSrray; // Please test it and than return javaSrray always without if else 
} 
else { 
    return javaSrray; // Works perfectly. 
} 
+2

लेकिन अगर मैं जावा को "शून्य" प्राप्त करना चाहता हूं तो क्या होगा? जेएनआई का उपयोग कर इसके लिए सही प्रक्रिया क्या है? क्या कोई जन्नुल ऑब्जेक्ट है जिसे मैंने अनदेखा किया है, या ..? – Dan

+0

आप शून्य के लिए क्यों पूछ रहे हैं। जब आप एक खाली वस्तु वापस करते हैं तो आप नल क्लोज को हटा सकते हैं और अपने सामान्य तर्क का उपयोग कर सकते हैं। –

+11

दो कारण: 1) मैं मौजूदा कोड को फिर से लिखने से बचाना चाहता हूं और, सबसे महत्वपूर्ण बात यह है कि 2) क्योंकि यह संभव होना चाहिए और मैं सीखना चाहता हूं कि कैसे। अगर मैं इसे समझ नहीं पा रहा हूं, तो मैं आपकी विधि का उपयोग करूंगा। धन्यवाद। – Dan

0

अपने कोड है कि मेरी आँख मारा में कुछ विषमता नहीं है। स्पष्ट रूप से env ऑब्जेक्ट यह तय करता है कि javaSrray आवंटित कैसे करें, तो क्यों इसे किसी प्रकार की खाली सरणी वापस करने के लिए नहीं कहें? यह संभव हो सकता है कि जिन 0 को आप वापस लौटते हैं उन्हें जनी और जावा के बीच मार्शल करते समय विशेष तरीके से संभाला जाना चाहिए।

+0

हां, मुझे लगता है कि 0 लौटने की बजाय (जो काम पर प्रतीत होता है, यानी मुझे जावा पक्ष पर एक शून्य वापस मिल जाता है, लेकिन कुछ अजीब अजीब कारणों से यह वास्तव में धीमा हो जाता है .. शायद जेएनआई इसे एक त्रुटि मामले के रूप में मानता है और शून्य देता है क्योंकि इसका साइड इफेक्ट के रूप में? और अतिरिक्त त्रुटि हैंडलिंग इसे धीमा कर रही है ??) कि मुझे किसी प्रकार की जेनल ऑब्जेक्ट वापस करनी चाहिए, लेकिन मुझे वास्तव में कोई नहीं ढूंढ रहा था ... – Dan

0

क्या आपने एक पूर्ण संदर्भ लौटने की कोशिश की है?

यह अपरीक्षित है (इस समय हाथ में एक JNI विकास के वातावरण की जरूरत नहीं है) लेकिन आप बातिल और इसे इस तरह वापस जाने के लिए एक नया वैश्विक संदर्भ बनाने के लिए सक्षम होना चाहिए:

return (*env)->NewGlobalRef(env, NULL); 

संपादित करें कि कहा जा रहा है, आप जांचते हैं कि कोई अपवाद होता है, लेकिन इसे साफ़ न करें। जहां तक ​​मैं समझ सकता हूं, इसका मतलब है कि यह अभी भी जावा परत में "फेंक दिया गया है", इसलिए आप केवल एक त्रुटि संकेतक के रूप में उपयोग करने में सक्षम होना चाहिए; तो इससे कोई फ़र्क नहीं पड़ता कि फ़ंक्शन क्या देता है।वास्तव में, जब अपवाद फेंक दिया जाता है तो अपवाद क्लीयर()/ExceptionDescribe() के अलावा एक जेएनआई फ़ंक्शन को कॉल करना दस्तावेज़ के अनुसार "सुरक्षित" नहीं होता है। यह कार्य "धीमा" हो सकता है ExceptionDescribe() फ़ंक्शन लेखन डीबगिंग जानकारी के कारण हो सकता है।

तो, अगर मैं इस सही ढंग से समझ, यह एक अच्छी तरह से व्यवहार समारोह एक अपवाद पहली बार एक त्रुटि तब होती है फेंक, और प्रत्येक बाद फोन पर शून्य लौटने (जब तक 'त्रुटि' को मंजूरी दे दी है) होना चाहिए:

if (error != ERROR) { 
    jbyteArray javaArray = env->NewByteArray((jsize) message.size); 
    env->SetByteArrayRegion(javaArray, 0, message.size, reinterpret_cast<jbyte*>(message.buffer())); 
    if (env->ExceptionOccurred()) { 
     error = ERROR; 
     return 0; 
    } 
    return javaArray; 
} else { 
    return env->NewGlobalRef(NULL); 
} 

फिर से, यह अनचाहे है क्योंकि मेरे पास अभी एक जेएनआई पर्यावरण उपलब्ध नहीं है।

+0

इसके लिए धन्यवाद। खैर, कोड अभी भी धीमा है अगर सब कुछ टिप्पणी की जाती है तो वापसी 0 से बाहर है, इसलिए यह ExceptionDescribe() को कॉल नहीं किया जा सकता है। अभी भी एक अच्छा मुद्दा है और आपका कोड मेरा से थोड़ा क्लीनर है। – Dan

+0

आप किस वीएम का उपयोग करते हैं? यदि यह एक खुली सोर्स है, तो देखें कि क्या आप कुछ अतिरिक्त सत्यापन कदम हैं या जो कुछ भी मूल फ़ंक्शन नल लौटाता है, उसे देख सकते हैं :) शायद 'अन्य' मामले के लिए मूल कोड में अपवाद उठाना बेहतर है ? – Christoffer

+0

नहीं, सूर्य वीएम का उपयोग कर। हाँ, मुझे लगता है कि रिटर्न मान शून्य होने पर अतिरिक्त त्रुटि हैंडलिंग कोड चलाया जा रहा है। वैसे भी, यह जानना अच्छा होगा कि यहां क्या सौदा है, लेकिन मैं वैसे भी इसे अन्य तरीकों से ठीक कर सकता हूं। – Dan

3

यह एक पुरानी सवाल है, लेकिन मैं यह था भी एक मिनट पहले ...

आप अपने प्रश्न में कहते हैं:

return 0; // Does NOT work - doesn't crash, just slows everything down horrible. 

मैं बस के रूप में यह एक jintArray साथ वास्तव में एक कोशिश दिया था, मेरे कोड को आवंटित करने और वापस करने के लिए क्या करना है, जब तक कोई त्रुटि न हो (कुछ मानदंडों द्वारा परिभाषित किया गया है जो इस विषय से संबंधित नहीं है) इस मामले में इसे एक नल परिणाम वापस करना होगा।

ऐसा होता है कि NULL (((void*)0) के रूप में परिभाषित) पूरी तरह से काम करता है और जावा पक्ष पर वापस null के रूप में व्याख्या किया जाता है। मैंने प्रदर्शन के किसी भी गिरावट को ध्यान में नहीं देखा। और जब तक मुझे 0 पर वापस आने से कुछ भी याद नहीं आया, void * कास्ट इस पर कुछ भी नहीं बदलेगा।

इसलिए मुझे नहीं लगता कि यह आपके द्वारा सामना की जाने वाली मंदी का कारण था। NULLnull वापस लौटने के लिए ठीक लगता है।

संपादित:

  • मैं पुष्टि करते हैं, वापसी मान प्रदर्शन के साथ कोई संबंध नहीं है। मैंने अभी एक तरफ एक शून्य मूल्य लौटाते हुए एक ही कोड का परीक्षण किया है, और इसके समकक्ष एक ऑब्जेक्ट (jintArray) को दूसरे पर लौट रहे हैं। प्रदर्शन NULL, आकार 0 के jintArray के लिए समान हैं, और कुछ केबी आवंटित कुछ KBs के यादृच्छिक jintArray के समान हैं।

  • मैंने कॉलर क्लास के क्षेत्र के मूल्य को बदलने और लगभग उसी प्रदर्शन के साथ शून्य को पुनर्प्राप्त करने का भी प्रयास किया। बहुत ही धीमी गति से, शायद उस क्षेत्र को पकड़ने और इसे सेट करने के लिए आवश्यक प्रतिबिंब कोड के कारण।

  • ये सभी परीक्षण एंड्रॉइड के तहत किए गए थे, जावा स्टैंडअलोन के तहत नहीं - शायद यही कारण है? (टिप्पणी देखें):

    • एक एपीआई 17 86 एमुलेटर HAXM के तहत चल रहा
    • एक एपीआई 19 है, तो उसी स्थिति
    • दो एपीआई 19 भौतिक उपकरणों के तहत चल रहा - एक Asus गोली और एक आकाशगंगा 5 - चल रहा है Dalvik के तहत।
+0

यह बहुत समय पहले था और अब मैं कहीं और काम करता हूं। हालांकि, मुझे यह याद है और उस समय, अगर मैं 0/NULL लौटा तो यह कुत्ता धीमा था, लेकिन अगर मैंने कुछ और लौटाया (उदाहरण के लिए एक खाली सरणी) यह नहीं था। मुझे नहीं पता कि मेरी समस्या क्या थी, लेकिन मैं गारंटी दे सकता हूं कि 200 9 में जो जेवीएम मैं उपयोग कर रहा था वह उतना ही नहीं है जितना आप 2015 में इस्तेमाल कर रहे थे। क्या यह मेरा जेवीएम था? क्या यह मेरी विन्यास थी? क्या यह मेरा जेएनआई सेटअप था? हम कभी नहीं जानते, लेकिन मुझे पता है कि 0/NULL लौटने से यह वास्तव में धीमा हो गया है। मुझे याद नहीं है कि मैंने इसे अंत में कैसे हल किया। मुझे लगता है कि मैंने या तो एक खाली सरणी या एक 'शून्य' ऑब्जेक्ट उदाहरण लौटाया। – Dan

+0

हालांकि दाल्विक अलग है, मैंने सोचा? एक के लिए, दलविक एक पंजीकृत-आधारित वीएम और ओरेकल (इस क्यू, सन के समय) जेवीएम स्टैक-आधारित है। मैं अब एक और जेवीएम पर पुनः प्रयास करने की योजना नहीं बना रहा हूं, लेकिन मैं व्यक्तिगत रूप से दलविक के तहत समान परिणामों की अपेक्षा नहीं करता हूं। – Dan

+1

हाय @ डैन! हाँ, यह पूर्ण ज्ञान बनाता है। जब मैंने यह लिखा तो मैं दलविक का उपयोग कर रहा था, और आजकल यह एक अलग है, जिसे कला कहा जाता है। यह समझा सकता है, यह सच है। मैंने तदनुसार अपना संपादन खंड अपडेट किया। – Shlublu

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