2011-11-20 11 views
6

मैं ITaskTrigger :: GetTriggerString विधि (http://msdn.microsoft.com/en-us/library/windows/desktop/aa381866(v=vs.85).aspx पर परिभाषित) के लिए एक पिनवोक लिखने की कोशिश कर रहा हूं। यदि आप पृष्ठ को देखते हैं, तो यह कहता है कि विधि का कॉलर पहले तर्क के माध्यम से संदर्भित एलपीडब्लूआर के स्मृति (कोटास्कमेम फ्री के माध्यम से) को मुक्त करने के लिए ज़िम्मेदार है। जबकि मैं इसे मैन्युअल रूप से .NET में कर सकता था या आईसी कस्टममर्शलर का उपयोग करके अपना कस्टम मार्शलर लिख सकता था, तो मैं सोच रहा था कि उस विशेष तर्क के लिए मार्शलए (UnmanagedType.LPWStr) विशेषता का उपयोग करने से स्मृति उचित रूप से मुक्त हो जाएगा।मार्शलएएस (UnmanagedType.LPWStr) क्लीनअप मेमोरी का उपयोग करेगा?

कोई भी कुछ अंतर्दृष्टि प्रदान कर सकता है?

+0

COM इंटरऑप के साथ गतिशील प्रकार के साथ काम करने में देखो - यह स्थिर टाइपिंग की तुलना में चीजों को बहुत आसान बना सकता है और स्मृति प्रबंधन का भी ख्याल रखता है। – weismat

+0

क्या आपके पास उस अंतिम बिट के लिए कोई संदर्भ है? सी # पहले से ही COM इंटरऑप के लिए मेमोरी प्रबंधन करता है, और हमेशा होता है। डायनामिक प्रकार से निपटने के दौरान चीजों को आसान बनाते हैं, उदाहरण के लिए, एक आईडीस्पैच इंटरफ़ेस लेकिन क्या वास्तव में स्थिर इंटरऑप प्रकारों की तुलना में उनके पास अलग-अलग मेमोरी प्रबंधन सुविधाएं होती हैं? –

उत्तर

6

पहली चीजें पहले: आप COM इंटरऑप के बारे में बात कर रहे हैं (ITaskTrigger एक COM इंटरफ़ेस है), पी/Invoke नहीं। दोनों के लिए अलग-अलग इंटरऑप नियम हैं, इसलिए उन्हें सीधे रखना महत्वपूर्ण है। उदाहरण के लिए, आपको पूरे इंटरफ़ेस के लिए सी # इंटरऑप रैपर को परिभाषित करने की आवश्यकता होगी, न कि केवल इच्छित विधि। ये आपको शुरू करना चाहिए: pinvoke.net

संक्षिप्त उत्तर यह है कि आप भाग्यशाली हैं, क्योंकि सीएलआर को आपके लिए चीजों का सही ढंग से देखभाल करना चाहिए।

लंबे उत्तर में पैरा इंटरफ़ेस कोड के मार्शलिंग के विभिन्न प्रकार शामिल हैं, पैरामीटर प्रकार, दिशानिर्देशों और आपके इंटरऑप हस्ताक्षर में जो विशेषताओं को जोड़ते हैं, उसके आधार पर।

इस मामले में, कॉल पर प्राप्त पैरामीटर प्रकार MarshalAs(UnmanagedType.LPWSTR) विशेषता के साथ "out string" पैरामीटर है। जब एक COM सर्वर उस कॉल को उजागर करता है जिसमें LPWSTR स्ट्रिंग प्रकार का "आउट" पैरामीटर होता है, तो यह मानते हुए कि सर्वर सौदा का अंत रख रहा है, यह CoTaskMemAlloc() के साथ मेमोरी बफर आवंटित करेगा और इसे आपके पास वापस कर देगा। (यदि यह BSTR की तरह एक अलग स्ट्रिंग प्रकार था, तो विशिष्ट मेमोरी आवंटन कॉल अलग हो सकता है, लेकिन मूल अवधारणा समान है।) इस बिंदु पर, जब आप इसकी आवश्यकता नहीं रखते हैं तो उस स्मृति को साफ करने के लिए आप ज़िम्मेदार हैं, मिलान CoTaskMemFree() कॉल का उपयोग कर।

इस आपरेशन एक विशेष प्रकार का एक "संदर्भ परिवर्तन" कहा जाता है: पैरामीटर आप में भेज रहे हैं पहले से ही एक संदर्भ पैरामीटर है, लेकिन COM सर्वर जा रहा है एक अलग संदर्भ के साथ बदलने। इस प्रक्रिया के लिए एक अच्छी व्याख्या this MSDN magazine article के "मेमोरी स्वामित्व" खंड में पाई जाती है। जैसा कि आप उस आलेख से देख सकते हैं, जब सीएलआर किसी संदर्भ प्रकार पर "आउट" पैरामीटर से डेटा वापस प्राप्त करता है, तो यह पहचानता है कि वह उस स्मृति को मुक्त करने की ज़िम्मेदारी ले रहा है। मार्शलिंग जो प्रबंधित कोड पर वापस कॉल करता है, यह MarshalAs विशेषता का उपयोग यह निर्धारित करने के लिए करता है कि यह COM में LPWSTR स्ट्रिंग-टाइप पॉइंटर है, और इसलिए इसे CoTaskMemAlloc() का उपयोग करके आवंटित किया जाना चाहिए। डेटा से प्रबंधित स्ट्रिंग बनाने के बाद, यह आपकी ओर से मूल बफर पर CoTaskMemFree() पर कॉल करेगा। आपके द्वारा वापस प्राप्त डेटा पूरी तरह से प्रबंधित हो जाएगा और आपको किसी स्वामित्व की समस्याओं से निपटना नहीं होगा।

+1

उत्तर के लिए धन्यवाद! यह पूरी तरह से स्पष्ट करता है। – wwahammy

+1

वास्तव में अच्छी व्याख्या, धन्यवाद। –

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