2010-11-11 12 views
6

मान लीजिए आप एक कामयाब वर्ग कि एक देशी समारोह सूचक और यह हाथ मूल कोड को के लिए एक प्रतिनिधि सदस्य धर्मान्तरित है। मान लें कि वर्ग/प्रतिनिधि दायरे में रहता है और मूल कोड के जीवनकाल (ताकि स्पष्ट रूप से जी सी द्वारा नष्ट नहीं किया जाएगा) के लिए नहीं बदलता है। इस स्थिति में किसी अन्य समस्या के बारे में क्या पता होना चाहिए? उदाहरण के लिए, यह संभव जीसी प्रतिनिधि या वास्तविक विधि प्रतिनिधि को संदर्भित करता है के लिए कदम और एक पहुँच उल्लंघन के साथ अपने मूल कोड को छोड़ने के लिए के लिए है?खतरों से कार्य करने के संकेत दिए गए

+0

"दायरे में रहता है" आपके प्रश्न में अन्य दावों के साथ सार्थक नहीं है । –

उत्तर

2

ऐसा लगता है कि प्रतिनिधि/कार्य के स्मृति स्थान को पिन करना संभव है, लेकिन यह .NET GC: compacting का एक बड़ा लाभ बाधित करता है।

एक बार जीसी स्वीप हो जाने के बाद, प्रत्येक ऑब्जेक्ट को स्मृति में स्थानांतरित करने के लिए स्थानांतरित किया जाता है। यह दोनों पहुंच और आवंटन को तेज़ी से बनाता है कि अगर ढेर खंडित हो जाए तो यह होगा। आप ढेर में जगह में एक वस्तु पिन करने के लिए है, तो जीसी यह आस-पास काम करने के लिए होगा और अगर यह कई बार किया गया था, यह कुछ nontrivial ढेर विखंडन का कारण बन सकता। (वैसे, इसे रॉन वॉरहोलिक द्वारा लिखे गए आलेख में जीसीएचंडल के साथ संबोधित किया गया है। मुझे यकीन नहीं है कि यह प्रबंधित सी ++ के बाहर उपलब्ध है।)

2

मैं नेट विशेषज्ञ नहीं हूं, लेकिन मुझे लगता है कि आपको यहां एक नज़र रखना चाहिए: Marshal Callbacks and Delegates Using C++ Interop

सूचना है कि यह संभव है, लेकिन जरूरी नहीं , प्रतिनिधि pin_ptr का उपयोग कर इसे फिर से स्थित या कचरा कलेक्टर द्वारा का निपटारा किया जा रहा से रोकने के लिए पिन करने के लिए। समय से पहले कचरा संग्रहण से संरक्षण की जरूरत है, लेकिन पिन करने का अधिक संरक्षण से आवश्यक है, के रूप में यह संग्रह से बचाता है, लेकिन यह भी स्थानांतरण होने से बचाता है प्रदान करता है।

+0

निम्न उदाहरण पिछले उदाहरण के समान है, लेकिन इस मामले में प्रदान की जाती समारोह सूचक अप्रबंधित API द्वारा संग्रहीत किया जाता है, तो यह किसी भी समय लागू किया जा सकता है, की आवश्यकता होती है कि कचरा संग्रहण के लिए समय की एक मनमाना लंबाई के लिए दबा दिया जाना। नतीजतन, निम्न उदाहरण, समारोह दायरे से स्वतंत्र दूसरी जगह जाने से रोकने के लिए प्रतिनिधि GCHandle के एक वैश्विक उदाहरण का उपयोग करता है। जैसा कि पहले उदाहरण में चर्चा की गई है, इन उदाहरणों के लिए pin_ptr का उपयोग करना अनावश्यक है, लेकिन इस मामले में वैसे भी काम नहीं करेगा, क्योंकि pin_ptr का दायरा एक ही कार्य तक सीमित है। – NoSenseEtAl

2

जीसी प्रतिनिधि को स्थानांतरित कर सकता है, लेकिन मूल कोड प्रतिनिधि प्रतिनिधि नहीं है। इसलिए जब तक प्रतिनिधि एकत्र नहीं किया जाता है तब तक फ़ंक्शन पॉइंटर वैध रहेगा।

ध्यान दें कि वस्तु में एकत्र होने से रोकने के लिए "दायरे में होना" पर्याप्त नहीं है। इसका उपयोग किया जाना चाहिए (संभवतः GC.KeepAlive पर कॉल करके)।

+0

सुनिश्चित नहीं हैं कि मैं का पालन करें, प्रतिनिधि एक प्रबंधित विधि है कि मूल कोड से पुकारा जाता है लपेटता है, लेकिन के लिए +1 "के प्रयोग की जाने वाली है" – insipid

2

एक त्वरित खोज इस मुद्दे पर कुछ Microsoft guidance बताती है। लेख प्रबंधित सी ++ के लिए है लेकिन मार्गदर्शन सीएलआर पर किसी भी भाषा के लिए होना चाहिए।

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

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