मुझे पता है कि CreateFile द्वारा दिया गया अमान्य मान INVALID_HANDLE_VALUE है। लेकिन चूंकि मैं भी आरएआईआई का उपयोग करना पसंद करता हूं, इसलिए यह एक साझा_प्टर (जैसे: shared_ptr<void> handle (CreateFile(args),&CloseHandle)
) में हैंडल बंद होने के लिए हैंडल को छूने के लिए बहुत मोहक है। आरएआईआई करने के लिए इस त्वरित और आसान तरीके से मेरी एकमात्र चिंता यह है कि यदि CreateFile हैंडल मान के रूप में NULL को वापस कर सकता है।क्या निर्माण कभी भी वापस लौटा सकता है?
उत्तर
NULL
मान्य संभाल मान नहीं है। आप इस तथ्य से यह समझ सकते हैं कि विफलता इंगित करने के लिए कुछ विंडोज एपीआई फ़ंक्शन NULL
लौटाते हैं। चूंकि हैंडल का निपटान करने के लिए एक ही फ़ंक्शन है, CloseHandle
, यह NULL
मान्य है HANDLE
मान मान्य नहीं है। इसलिए CreateFile
कभी भी NULL
वापस नहीं लौटा सकता है।
रेमंड चेन ने इस विषय पर छूने वाले ब्लॉग लेख को लिखा: Why are HANDLE return values so inconsistent?।
अब, मुझे shared_ptr<>
के बारे में कुछ भी पता नहीं है, इसलिए इस बारे में कोई टिप्पणी नहीं करना चाहिये कि आपका विचार उचित है या नहीं। मैं केवल आपके द्वारा पूछे गए सीधे प्रश्न का उत्तर दे रहा हूं।
मुझे पता नहीं था कि 'NULL' उन कार्यों से भी वापस नहीं किया जा सकता है जिनके लिए "अमान्य" वापसी मान 'INVALID_HANDLE_VALUE' है। क्या आपको यकीन है कि ऐसा है? आपका तर्क यह है कि इस तरह के 'क्लोजहैंडल' द्वारा पता लगाया जा सकता है कि जब अवैध हैंडल पास हो जाता है, इससे कोई फर्क नहीं पड़ता कि कौन सा फ़ंक्शन इसे वापस कर देता है (जब तक यह कर्नेल हैंडल हो)। लेकिन OTOH 'CloseHandle' ** ** पास ** के पास अवैध अमान्य मानों को ले जाने के लिए ** नहीं है। – valdo
@ valdo मेरा तर्क यह है कि 'CloseHandle' यह नहीं जानता कि अमान्य हैंडल CreateFile या अन्य API से आया है जो' NULL' का उपयोग इसके वापसी मान के रूप में करता है। एक और आसान तर्क यह था कि यदि 'CreateFile'' NULL' लौटा, तो दूसरा फ़ंक्शन सिग्नल विफलता कैसे हो सकता है? –
ठीक है, मैं आपके तर्क को समझ गया, और यह शायद सही है। हालांकि * सैद्धांतिक रूप से * यह कुछ भी साबित नहीं करता है। मानक 'क्लोजहैंडल' के मुताबिक यह समझने की ज़रूरत नहीं है कि आपने इसे एक अवैध संभाल पास कर दिया है और किसी भी नुकसान के बिना चुपचाप असफल हो जाता है, जैसे कि किसी अन्य (असंबंधित) संसाधन को बंद करना। यह तुम्हारी समस्या है। 'CreateXXXX' के वापसी मूल्य की जांच करना और हैंडल अमान्य होने पर' CloseHandle' को कॉल न करना आपकी ज़िम्मेदारी है। हालांकि, व्यावहारिक रूप से बोलते हुए, मेरा मानना है कि 'नूल' और 'INVALID_HANDLE_VALUE' दोनों गैर-हैंडल मान के रूप में आरक्षित हैं। – valdo
एक सामान्य तरीके से वैधता के लिए हैंडल का परीक्षण करते समय, NULL
और INVALID_HANDLE_VALUE
दोनों की जांच करें।
लेकिन मुझे नहीं लगता कि आरएआईआई के पास CreateFile
NULL
वापस कर सकता है या नहीं। HANDLE
साझा पॉइंटर के साथ काम करने के लिए आपको वैधता परीक्षण और अस्वीकार करने के लिए कस्टम कोड प्रदान करने की आवश्यकता होगी, इसलिए आप इन चेक के नियंत्रण में हैं, साझा पॉइंटर क्लास नहीं।
दूसरे शब्दों में, यह कोई फर्क नहीं पड़ता कि यह किसी साझा सूचक में है या आप सामान्य HANDLE
का उपयोग करते हैं, तो चेक बिल्कुल वही हैं, और आपको उन्हें किसी भी तरह से प्रदान करना होगा।
यह वास्तव में 'क्लोजहैंडल' को 'न्यूल' या 'INVALID_HANDLE_VALUE' से गुजरने के लिए सौम्य है। यह एक त्रुटि होगी, लेकिन इससे कोई नुकसान नहीं होगा। मैं मानता हूं कि मैं इस तरह से 'हैंडल' लपेटूंगा। एक bespoke 'RAII' वर्ग नौकरी अच्छी तरह से किया जाएगा। मुझे यकीन है कि एक गजियन बार किया गया है। +1 –
@ डेविड हेफरनान मैं अच्छी तरह से जानता हूं कि अधिक संपूर्ण समाधान आपके स्वयं के हैंडल प्रबंधन वर्ग को लिखना होगा। चलिए इस दिशा में एक कदम मानते हैं। – Dan
क्यों मुझे परवाह है कि CreateFile NULL वापस कर सकता है और उसे RAII के साथ क्या करना है। मुझे चिंतित था कि यदि शेयर शून्य था तो share_ptr कस्टम विनाशक को कॉल नहीं कर सकता है ..कोड पर गहराई से देखने पर (कम से कम बढ़ावा देने के लिए) ऐसा लगता है कि यह वैसे भी करता है .. अगर कस्टम सृजन फ़ंक्शंस का उपयोग करना जो एक shared_ptr को साझा_ptr के बीच अंतर करता है जिसमें कुछ भी नहीं है जिसमें शून्य संभाल होता है तो परेशानी होगी – Dan
CreateFile कभी भी NULL
देता है। मेरा सुझाव है कि आप पहले से ही बनाए गए रैपर ATL::CAtlFile
का उपयोग करें और shared_ptr
पर आधारित एक नया न करें।
अच्छा और अच्छा है, लेकिन मान लें कि मैं वास्तव में हैंडल बंद करने से पहले अपने कस्टम विनाशक में परीक्षण कोड में जोड़ना चाहता था। – Dan
@Dan: ठीक है, तो आप CAtlFile का उत्तराधिकारी हो सकते हैं और आप विनाशक में कोड का परीक्षण कर सकते हैं। हैंडल के लिए IMHO shader_ptr बदसूरत लग रहा है। –
हाँ अच्छी तरह से IMHO अटलांट COM के प्रबंधन के अलावा कुछ भी बदसूरत है। – Dan
- 1. postgresql फ़ंक्शन से कुछ भी वापस नहीं लौटा रहा है?
- 2. scala.util.Random.nextInt(): Int कभी-कभी नकारात्मक मान वापस कर सकता है?
- 3. PostgreSQL ट्रिगर कुछ भी वापस नहीं लौटा रहा है
- 4. सेट टाइमटाइम कभी भी आईडी के रूप में 0 लौटा सकता है?
- 5. SystemClock.uptimeMillis() कभी भी कैसे लपेट सकता है?
- 6. document.getElementbyId() वापस लौटा
- 7. क्या एक HTTP विकल्प अनुरोध 204 लौटा सकता है या इसे हमेशा 200 वापस करना चाहिए?
- 8. Thread.sleep() कभी वापस
- 9. यादृच्छिक हो सकता है। रेन्डिंट (1,10) कभी वापस 11?
- 10. ऑब्जेक्ट। गेटटाइप() कभी वापस शून्य हो सकता है?
- 11. पाइथन: क्यों इंस्टेंस वापस लौटा सकता है, जब इसे सही वापस करना चाहिए?
- 12. क्यों TCusomWinSocket.ReceiveBuf कभी वापस नहीं आता है?
- 13. क्या एक रननेबल एक मूल्य लौटा सकता है?
- 14. इसे वापस करने से बचने के लिए एक निर्माता क्या मूल्य लौटा सकता है?
- 15. (1 +) कभी भी एक समारोह कैसे हो सकता है?
- 16. क्या कोई भी कभी रिबन नियंत्रण का उपयोग करता है?
- 17. क्या सी ++ फ़ंक्शन एक से अधिक मान लौटा सकता है?
- 18. एएसपी.नेट पेपैल आईपीएन वापस लौटा रहा है लेकिन आईपीएन
- 19. क्या जावा नक्शा -1 का आकार लौटा सकता है?
- 20. क्या डेल्फी कभी-कभी टेक्स्ट फॉर्म फाइलों (डीएफएम) को बाइनरी प्रारूप में वापस लाता है?
- 21. IMetadataAware.OnMetadataCreated को कभी भी
- 22. टाइपऑफ (फू) कभी वापस क्यों नहीं आएगा?
- 23. कभी भी यूडीपी सॉकेट को लिखना ब्लॉक कर सकता है?
- 24. गिट वर्कफ़्लो आप कभी भी
- 25. इरादा सेवा कभी भी
- 26. आईफोन: UIAplplicationWillResignActiveNotification कभी भी
- 27. पिक्चर कैलबैक.ऑनचित्रचित्र कभी भी
- 28. सतह निर्मित() कभी भी
- 29. क्या उपयोगकर्ता नाम कभी भी संवेदनशील हैं?
- 30. क्या जर्सी अनुरोध एक पॉलिमॉर्फिक इकाई लौटा सकता है?
ध्यान दें कि आपको ऐसा कुछ करने का प्रयास करते समय सावधान रहना होगा। देखें: http://stackoverflow.com/questions/1562421/making-a-handle-raii-compliant-using-shared-ptr-with-a- कस्टम-deleter – tenfour
इस तरह के संसाधन के लिए आरएआईआई रैपर बनाना ठीक है । हालांकि 'shared_ptr' का उपयोग न करें जबतक कि आपको ** वास्तव में ** साझा करने की आवश्यकता न हो। यह एक विशाल ओवरकिल है ('shared_ptr' आंतरिक रूप से संदर्भ गणना के लिए ढेर पर एक अतिरिक्त मेमोरी आवंटित करता है), साथ ही आपके पास सुविधाजनक पहुंच नहीं होगी, जैसे कि 'हैंडल' पर सीधी कास्टिंग, क्योंकि' shared_ptr' जानबूझकर इसे रोकता है। – valdo
उत्कृष्ट अंक। unique_ptr शायद इस स्तर पर प्रयास करने के लिए एक बेहतर तरीका होगा। – Dan