2012-02-09 16 views
12

मैं सी ++/सीएलआई में संसाधन प्रबंधन के बारे में बेहद उलझन में हूं। मैंने सोचा कि मेरे पास एक हैंडल था (कोई इरादा नहीं था), लेकिन मैं auto_gcroot<T> कक्षा में हेडर फाइलों के माध्यम से देखकर ठोकर खाई, जिसके कारण एक Google खोज हुई, फिर दिन पढ़ने के दस्तावेज़ीकरण का बेहतर हिस्सा, और अब भ्रम। तो मैंने सोचा कि मैं समुदाय की ओर रुख करूंगा।सी ++/सीएलआई संसाधन प्रबंधन भ्रम

मेरे प्रश्न auto_handle/stack semantics, और auto_gcroot/gcroot के बीच अंतर को लेकर चिंतित हैं।

  1. auto_handle: मेरी समझ यह है कि यह एक प्रबंधित फ़ंक्शन में बनाए गए प्रबंधित ऑब्जेक्ट को साफ़ कर देगा। मेरा भ्रम यह है कि कचरा कलेक्टर हमारे लिए ऐसा नहीं करना चाहिए? क्या वह प्रबंधित कोड का पूरा बिंदु नहीं था? अधिक विशिष्ट होना करने के लिए:

    //Everything that follows is managed code 
    void WillThisLeak(void) 
    { 
        String ^str = gcnew String ^(); 
        //Did I just leak memory? Or will GC clean this up? what if an exception is thrown? 
    } 
    
    void NotGoingToLeak(void) 
    { 
        String ^str = gcnew String^(); 
        delete str; 
        //Guaranteed not to leak, but is this necessary? 
    } 
    
    void AlsoNotGoingToLeak(void) 
    { 
        auto_handle<String ^> str = gcnew String^(); 
        //Also Guaranteed not to leak, but is this necessary? 
    } 
    
    void DidntEvenKnowICouldDoThisUntilToday(void) 
    { 
        String str(); 
        //Also Guaranteed not to leak, but is this necessary? 
    } 
    

    अब यह मेरे लिए कोई मतलब होता अगर यह सी कीवर्ड का उपयोग # के लिए एक स्थानापन्न था, और यह केवल बिटमैप की तरह संसाधन प्रधान प्रकार के साथ उपयोग के लिए सिफारिश की गई थी, लेकिन इस नहीं है कहीं भी उल्लेख किया डॉक्स में बहुत डर Ive im इस पूरे समय अब ​​

  2. auto_gcroot

मैं इसे एक देशी कार्य करने के लिए एक तर्क के रूप प्रदान कर सकता हूँ स्मृति लीक कर दिया गया? प्रतिलिपि पर क्या होगा?

void function(void) 
    { 
     auto_gcroot<Bitmap ^> bmp = //load bitmap from somewhere 
     manipulateBmp(bmp); 
     pictureBox.Image = bmp; //Is my Bitmap now disposed of by auto_gcroot? 
    } 

    #pragma unmanaged 

    void maipulateBmp(auto_gcroot<Bitmap ^> bmp) 
    { 
     //Do stuff to bmp 
     //destructor for bmp is now called right? does this call dispose? 
    } 

क्या यह काम करेगा यदि मैं इसके बजाय एक जीक्रूट का उपयोग करता?

इसके अलावा, auto_handle और auto_gcroot होने का क्या फायदा है? ऐसा लगता है जैसे वे समान चीजें करते हैं।

मुझे इतना कम समझने के लिए कुछ गलत समझना चाहिए, इसलिए एक अच्छी व्याख्या बहुत अच्छी होगी। इन प्रकारों के उचित उपयोग के बारे में भी कोई मार्गदर्शन, जहां मैं इस सामान को जानने के लिए जा सकता हूं, और मैं उन्हें ढूंढ सकने वाले किसी और अच्छे अभ्यास/स्थानों की बहुत सराहना करता हूं।

बहुत बहुत शुक्रिया, मैक्स

+0

मैं यहाँ रूपों में से सबसे अधिक उपयोग कभी नहीं: मैं हमेशा प्रबंधित वस्तुओं के लिए संदर्भ का उपयोग और मैं हमेशा जीसी उन्हें साफ कर देना मेरे लिए। मैं कभी-कभी 'gcroot' का उपयोग करता हूं, लेकिन शायद ही कभी (जब मैं चाहता हूं कि .NET बंद/प्रतिनिधि को C++ फ़ंक्शन ऑब्जेक्ट्स में लपेटें और जब तक मुझे इसकी आवश्यकता हो, तब तक एक हैंडल रखना सुनिश्चित करें)। –

+0

यह auto_ptr <> प्रबंधित दुनिया में लाने के लिए काफी भारी गुमराह प्रयास है। एसटीएल/सीएलआर पुस्तकालय के रूप में मूर्खतापूर्ण के रूप में। करने के लिए सबसे अच्छी बात सिर्फ उनके बारे में भूल जाओ। –

उत्तर

17
  1. याद रखें delete प्रबंधित वस्तु पर बुलाया सी # में निपटान बुला लिए समान है। तो आप सही हैं, कि auto_handle आपको C12 में using कथन के साथ क्या करने की सुविधा देता है। यह सुनिश्चित करता है कि delete दायरे के अंत में बुलाया जाता है। इसलिए, नहीं, आप प्रबंधित स्मृति को लीक नहीं कर रहे हैं यदि आप auto_handle का उपयोग नहीं करते हैं (कचरा कलेक्टर इसका ख्याल रखता है), तो आप बस निपटने में विफल रहे हैं। ऑटो-हैंडल का उपयोग करने की कोई आवश्यकता नहीं है यदि आपके साथ काम करने वाले प्रकार IDISposable लागू नहीं करते हैं।

  2. gcroot का उपयोग तब किया जाता है जब आप एक देशी वर्ग के अंदर एक प्रबंधित प्रकार को पकड़ना चाहते हैं। आप टोपी ^ प्रतीक का उपयोग कर सीधे एक मूल प्रकार में एक मिश्रित प्रकार की घोषणा नहीं कर सकते हैं। आपको एक gcroot का उपयोग करना होगा। यह एक "कचरा एकत्रित रूट" है। इसलिए, जबकि gcroot (एक मूल वस्तु) रहता है, कचरा कलेक्टर इस वस्तु को इकट्ठा नहीं कर सकता है। जब gcroot नष्ट हो जाता है, यह संदर्भ को जाने देता है, और कचरा कलेक्टर वस्तु एकत्र करने के लिए स्वतंत्र है (माना जाता है कि इसमें कोई अन्य संदर्भ नहीं है)। आप उपर्युक्त तरीके से एक विधि में एक मुक्त खड़े gcroot घोषित करें - जब भी आप कर सकते हैं टोपी ^ वाक्यविन्यास का उपयोग करें।

तो आप auto_gcroot का उपयोग कब करेंगे?इसका उपयोग तब किया जाएगा जब आपको मूल वर्ग के अंदर एक मैंगेड प्रकार को पकड़ने की आवश्यकता होती है और प्रबंधित प्रकार IDISposable लागू करने के लिए होता है। Auto_gcroot के विनाश पर, यह 2 चीजें करेगा: प्रबंधित प्रकार पर कॉल हटाएं (इसे एक डिस्प्ले कॉल के रूप में सोचें - कोई स्मृति मुक्त नहीं है) और संदर्भ मुक्त करें (इसलिए प्रकार कचरा एकत्र किया जा सकता है)।

उम्मीद है कि यह मदद करता है!

कुछ संदर्भों:

http://msdn.microsoft.com/en-us/library/aa730837(v=vs.80).aspx

http://msdn.microsoft.com/en-us/library/481fa11f(v=vs.80).aspx

http://www.codeproject.com/Articles/14520/C-CLI-Library-classes-for-interop-scenarios

+1

आखिर में कोई जो समझ में आता है! –

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