2010-01-04 12 views
7

मैं सी में कुछ मेमोरी आवंटित करना चाहता हूं और इसे जावा ऑब्जेक्ट इंस्टेंस से जोड़ता हूं, जैसे:जावा जेएनआई - जावा वस्तुओं के साथ सी में आवंटित संसाधनों को जोड़ना?

void configure(JNIEnv *object, jobject obj, ....) { 
    char *buf = new char[1024]; 
    // associated <buf> with <obj> somehow 
} 

और बाद में जावा ऑब्जेक्ट कचरा इकट्ठा होने पर स्मृति को मुक्त करें - मैं इसे कॉल करके ऐसा कर सकता हूं Xzx16 से jNI फ़ंक्शन जावा ऑब्जेक्ट का अंतिम रूप() विधि।

सवाल यह है कि, मैं जावा ऑब्जेक्ट के साथ सी पॉइंटर कैसे जोड़ूं? ऑब्जेक्ट में long फ़ील्ड रखें और पॉइंटर को long पर डालें? क्या कोई बेहतर तरीका है?

+2

डुप्ली: http://stackoverflow.com/questions/214699/jni-memory-management-using-the-invocation-api – falstro

+0

इस प्रश्न में सॉर्ट करें कि सी ऑब्जेक्ट को कैसे संबद्ध करें इस पर कोई चर्चा नहीं है जावा उदाहरण प्रस्तुत उदाहरण में सूचक को लंबे समय तक डाला जाता है। क्या यह एकमात्र तरीका है? – Viktor

उत्तर

16

आम तौर पर, यदि आप सी से जावा तक एक पॉइंटर स्थानांतरित करना चाहते हैं, तो long का उपयोग करने की अनुशंसा की जाती है ताकि प्लेटफ़ॉर्म 64 बिट्स के मामले में पॉइंटर मान को पकड़ने के लिए पर्याप्त बिट्स हों।

तो है, जो एक ByteBuffer उदाहरण है, जिसमें स्मृति सी के साथ साझा किया जा सकता है आप जावा की ओर से इस तरह के एक प्रत्यक्ष ByteBuffer आवंटित कर सकते हैं बनाता है ByteBuffer.allocateDirect() पर एक नजर है तो एक JNI कार्य करने के लिए एक jobject के रूप में यह गुजरती हैं और यह JNI समारोह के अंदर आप GetDirectBufferAddress फ़ंक्शन का उपयोग करते हैं।

एक और तरीका देशी पक्ष से NewDirectByteBuffer जेएनआई फ़ंक्शन के साथ मेमोरी के देशी क्षेत्र को लपेटना है। यह आपको jobject देता है जो आप जावा पक्ष में वापस जाते हैं (स्थानीय और वैश्विक संदर्भों पर ध्यान दें)। इस तथ्य पर ध्यान दें कि एक बार प्रत्यक्ष ByteBuffer जो मूल स्मृति को लपेटता है, आप मूल स्मृति के प्रबंधन के लिए अभी भी ज़िम्मेदार हैं: किसी बिंदु पर, आपको अपने मूल कोड में delete buf; पर कॉल करना होगा, जावा इसे नहीं करेगा तुम्हारे लिए।

+0

धन्यवाद! अगर मैं सही ढंग से समझता हूं, ByteBuffer.allocateDirect() का उपयोग कर सूचक को गुजरता है + स्मृति प्रबंधन; इस तरह बाइटबफर स्मृति का प्रबंधन करता है। – Viktor

+1

जावा पक्ष से प्रत्यक्ष बाइटबफर आवंटित करने से जावा को स्मृति के ब्लॉक आवंटित करने दें, जिसे 'अंतिम रूप देने' के दौरान रिलीज़ होने जा रहा है। केवल नकारात्मक बात यह है कि कचरा कलेक्टर गुजरता है जब आप बिल्कुल नहीं जानते हैं कि आप वास्तव में नहीं जानते कि स्मृति कब जारी की जाती है, इसके अलावा यह बफर के साथ समाप्त होने के बाद रिलीज़ होने जा रहा है। –

+0

+1 साफ! अच्छा उत्तर। – JesperE

0

जावा में देशी सूचक की कोई अवधारणा नहीं है, इसलिए इसे लंबे समय तक संग्रहीत करना एकमात्र वास्तविक विकल्प है। लेकिन सूचक को मुक्त करने के लिए आपको finalize पर भरोसा नहीं करना चाहिए; अंतिमकरण विधि संसाधनों की सफाई के साधन के रूप में अविश्वसनीय है। अधिक जानकारी के लिए this question देखें।

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