2009-04-18 14 views
9

MSDN पर मैं दो विशेषताओं के लिए निम्नलिखित विवरण मिल गया है:DllImport - PreserverSig और SetLastError विशेषताओं

PreserveSig सत्य पर PreserveSig क्षेत्र सेट सीधे HRESULT या retval मूल्यों के साथ अप्रबंधित हस्ताक्षर अनुवाद करने के लिए; HRESULT या retval मानों को अपवादों में स्वचालित रूप से परिवर्तित करने के लिए इसे गलत पर सेट करें। डिफ़ॉल्ट रूप से, PreserveSig फ़ील्ड सत्य है।

SetLastError फोन करने वाले Marshal.GetLastWin32Error एपीआई समारोह का उपयोग करने के निर्धारित करने के लिए विधि निष्पादित करते समय एक त्रुटि हो गई सक्षम बनाता है। विजुअल बेसिक में, डिफ़ॉल्ट सत्य है (जो कुछ ओवरहेड जोड़ता है); सी # और सी ++ में, डिफ़ॉल्ट गलत है।

मेरा प्रश्न है: ये दोनों एक दूसरे से कैसे संबंधित हैं? मान लीजिए कि मेरे पास PreserveSig को 'झूठा' पर सेट किया गया है - इसका मतलब है कि मुझे HRESULT को अपवाद में परिवर्तित करना चाहिए - यदि अप्रबंधित फ़ंक्शन पूर्णांक देता है तो यह इंगित करता है कि त्रुटि या कोई त्रुटि नहीं हुई है, तो इसे अपवाद में कैसे अनुवादित किया जा सकता है?

यदि मैं किसी भी तरह PreserveSig का उपयोग करके अपवाद निकालने में कामयाब रहा तो मुझे GetLastWin32Error विधि को कॉल करने की आवश्यकता क्यों है?

तरह पी का संबंध

उत्तर

14

Win32 कार्यों लगभग एक HRESULT वापस कभी नहीं। इसके बजाय वे BOOL लौटाते हैं या त्रुटि इंगित करने के लिए विशेष मानों का उपयोग करते हैं (उदा। CreateFileINVALID_HANDLE_VALUE लौटाता है)। वे त्रुटि कोड को प्रति-थ्रेड चर में संग्रहीत करते हैं, जिसे आप GetLastError() के साथ पढ़ सकते हैं। SetLastError=true देशी फ़ंक्शन रिटर्न के बाद इस चर को पढ़ने के लिए मार्शलर को निर्देश देता है, और त्रुटि कोड को दबाता है जहां आप इसे Marshal.GetLastWin32Error() के साथ पढ़ सकते हैं। विचार यह है कि .NET रनटाइम उन दृश्यों के पीछे अन्य Win32 फ़ंक्शंस को कॉल कर सकता है जो आपके पी/इनवॉक कॉल से त्रुटि कोड को गड़बड़ कर देते हैं इससे पहले कि आप इसका निरीक्षण कर सकें।

कार्य जो HRESULT (या समतुल्य, उदा। NTSTATUS) लौटाते हैं, Win32 फ़ंक्शंस की तुलना में अमूर्तता के एक अलग स्तर से संबंधित हैं। आम तौर पर ये फ़ंक्शन COM-related (Win32 से ऊपर) या ntdll (Win32 के नीचे) से हैं, इसलिए वे Win32 अंतिम-त्रुटि कोड का उपयोग नहीं करते हैं (हालांकि वे आंतरिक रूप से Win32 फ़ंक्शंस को कॉल कर सकते हैं)।

PreserveSig=false वापसी HRESULT जाँच करने के लिए marshaler निर्देश देता है और अगर यह एक सफलता कोड नहीं है, बना सकते हैं और HRESULT युक्त एक अपवाद फेंकने के लिए। आपके DllImport एड फ़ंक्शन की प्रबंधित घोषणा के बाद void इसके रिटर्न प्रकार के रूप में है।

याद रखें, सी # या वीबी कंपाइलर DllImport एड फ़ंक्शन के अप्रबंधित हस्ताक्षर की जांच नहीं कर सकता है, इसलिए इसे जो कुछ भी आप बताते हैं उसे भरोसा करना है। यदि आप PreserveSig=false फ़ंक्शन पर डालते हैं जो HRESULT के अलावा कुछ देता है, तो आपको अजीब परिणाम मिलेंगे (उदा। यादृच्छिक अपवाद)। यदि आप एक ऐसे फ़ंक्शन पर SetLastError=true डालते हैं जो अंतिम Win32 त्रुटि कोड सेट नहीं करता है, तो आपको एक उपयोगी त्रुटि कोड के बजाय कचरा मिल जाएगा।

+0

मुझे COM ऑब्जेक्ट्स के साथ अनुभव नहीं है इसलिए मुझे विधि हस्ताक्षर बनाने के संबंध में एक और प्रश्न पूछने दें। सवाल यह है: जब मैं देखता हूं कि COM फ़ंक्शन HRESULT लौटाता है, तो मैं अपनी विधि को शून्य लौटने के रूप में चिह्नित कर सकता हूं और PreserveSig = false (जैसा कि आपने कहा था) सेट कर सकते हैं, या PreserveSig = true सेट कर सकते हैं और मैन्युअल रूप से लौटाए गए कोड की जांच करने के लिए IntPtr लौटने के रूप में मेरी विधि को चिह्नित कर सकते हैं? – pkolodziej

+0

हां, यह सही है, सिवाय इसके कि HRESULT UIU32 हैं, IntPtrs नहीं। –

+0

धन्यवाद - आप बहुत उपयोगी रहे हैं। – pkolodziej

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