2012-02-08 10 views
17

मैं समझता हूँ कि CLR कुछ मामलों में प्रमुखता करने की जरूरत है, लेकिन मान लीजिए कि मैं करते हैं:"प्रबंधित-से-मूल संक्रमण" के दौरान वास्तव में क्या होता है?

using System.Runtime.InteropServices; 
using System.Security; 

[SuppressUnmanagedCodeSecurity] 
static class Program 
{ 
    [DllImport("kernel32.dll", SetLastError = false)] 
    static extern int GetVersion(); 

    static void Main() 
    { 
     for (; ;) 
      GetVersion(); 
    } 
} 

जब मैं एक डिबगर के साथ इस कार्यक्रम में तोड़, मैं हमेशा देखें:

यह देखते हुए कि कोई मार्शलिंग नहीं किया जाना चाहिए (दाएं?), क्या कोई इस बात को समझ सकता है कि इस "प्रबंधित-से-मूल संक्रमण" में क्यों हो रहा है, और यह आवश्यक क्यों है?

+6

हो सकता है कि कॉल स्टैक में है कि रेखा सिर्फ जानकारीपूर्ण है, तुम्हें पता है जब आप –

+0

@DavidHeffernan तरीके से संक्रमित जाने के लिए: यहाँ एक उदाहरण है ओह ....... मुझे लगता है कि भी काम करता है लगता है .. लेकिन मुझे लगता है कि कुछ और भी हो रहा है (हालांकि मुझे गलत सिद्ध होना अच्छा लगेगा!)। – Mehrdad

+0

@ डेविडहेफरन: यह दिलचस्प है कि यह 'kernel32.dll' से 'mscoree.dll' तक जाने पर एक ही बात नहीं कहता है, हालांकि ... इससे मुझे संदेह होता है कि वास्तव में कुछ चल रहा है। – Mehrdad

उत्तर

10

पहले कॉल स्टैक को स्थापित करने की आवश्यकता है ताकि एक STDCALL हो सके। यह Win32 के लिए कॉलिंग सम्मेलन है।

अगला रनटाइम एक तथाकथित निष्पादन फ्रेम को दबाएगा। कई अलग-अलग प्रकार के फ्रेम हैं: सुरक्षा asserts, जीसी संरक्षित क्षेत्रों, देशी कोड कॉल, ...

रनटाइम इस तरह के फ्रेम का उपयोग करता है कि वर्तमान में देशी कोड चल रहा है। इसका संभावित समवर्ती कचरा संग्रह और शायद अन्य सामान के लिए प्रभाव पड़ता है। यह डीबगर में भी मदद करता है।

तो वास्तव में यहां बहुत कुछ नहीं हो रहा है। यह एक सुंदर पतला कोड पथ है।

+3

+1 यह एक शानदार जवाब है। – Mehrdad

0

चूंकि आप एक डीएल कॉल कर रहे हैं। इसे प्रबंधित वातावरण से बाहर जाने की जरूरत है। यह विंडोज कोर में जा रहा है। आप .NET बाधा तोड़ रहे हैं और विंडोज कोड में जा रहे हैं जो .NET के समान नहीं चलता है।

+12

कोई मजाक नहीं !! ... – Mehrdad

+1

बहुत जानकारीपूर्ण नहीं है। आप सिर्फ सवाल फिर से कर रहे हैं। :) – jalf

+2

@jalf लेकिन ".NET बाधा तोड़ना" एक अच्छा rephrasing है। – phoog

1

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

लेकिन मुझे लगता है कि आप संक्रमण के चारों ओर डिस्सेप्लोरर्स का निरीक्षण करके आसानी से पता लगाना चाहिए। देखें कि यह कुछ असामान्य करता है या नहीं।

+0

डिस्सेप्लिब्स का निरीक्षण करना मुश्किल है: वीएस मुझे बताता है कि मेरे सी # कोड में निर्देश '0xFFEFBFAC' कॉल है, लेकिन उस पते पर कुछ भी नहीं है - जब मैं उस फ़ंक्शन में कदम करता हूं, तो यह स्वचालित रूप से '_GetVersionStub @ 0' पर जाता है, जो '75834437' पर है। तो यह स्पष्ट रूप से कुछ कोड छोड़ रहा है। हो सकता है कि मैं इसे WinDbg के साथ कर सकता हूं? यकीन नहीं है, मैं इसे आजमा सकता हूं और देख सकता हूं। – Mehrdad

2

मार्शलिंग परत के अलावा, जो आपके लिए पैरामीटर बदलने और कॉलिंग सम्मेलनों को समझने के लिए ज़िम्मेदार है, रनटाइम को आंतरिक स्थिति को स्थिर रखने के लिए कुछ और चीजें करने की आवश्यकता है।

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

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

तो मुख्य रूप से यह स्टैक हैंडलिंग और प्रकार की मार्शलिंग है, जिसमें कुछ सुरक्षा सामग्री फेंक दी गई हैं। हालांकि यह बड़ी मात्रा में सामान नहीं है, हालांकि छोटे देशी तरीकों को कॉल करने के खिलाफ एक महत्वपूर्ण बाधा का प्रतिनिधित्व करता है। उदाहरण के लिए, एक अनुकूलित गणित पुस्तकालय में पी/इनवॉक करने का प्रयास शायद ही कभी प्रदर्शन जीत में होता है, क्योंकि ओवरहेड किसी भी संभावित लाभ को अस्वीकार करने के लिए पर्याप्त है।कुछ प्रदर्शन प्रोफाइलिंग परिणामों पर चर्चा की जाती है here

2

मुझे एहसास हुआ कि इसका उत्तर दिया गया है, लेकिन मुझे आश्चर्य है कि किसी ने भी सुझाव नहीं दिया है कि आप डीबग विंडो में बाहरी कोड दिखाएं। यदि आप [Native to Managed Transition] लाइन पर राइट क्लिक करें और Show External Code विकल्प पर टिकटें, तो आप देखेंगे कि संक्रमण में कौन सी .NET विधियां बुलाई जा रही हैं। यह आपको एक बेहतर विचार दे सकता है।

Displaying a Native to Managed Transition

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