2012-05-10 11 views
5

से "स्ट्रिंग" पैरामीटर मार्शलिंग एक दिलचस्प समस्या में भाग गया कि मैं सोच रहा था कि कोई भी समझाने में मदद कर सकता है। मैंने पूरे इंटरनेट पर खोज करने की कोशिश की है और इस समस्या का उत्तर नहीं मिल रहा है। जबकि हमारे पास समाधान है, अन्य लोग एक ही समस्या में भाग सकते हैं, और चूंकि यह यादृच्छिक था, इसलिए इसे ट्रैक करना बहुत मुश्किल है।सी #

हमारे पास एक ऐसा एप्लिकेशन है जो कंप्यूटर को कॉर्पोरेट नेटवर्क से जुड़े होने पर यादृच्छिक रूप से विफल रहता है (नेटवर्क पर बहुत सारी जानकारी नहीं है)। जब हम कंप्यूटर को हमारे पर्यावरण में लाए तो यह ठीक काम करता था। विफलता काफी यादृच्छिक है, लेकिन जैसा कि सबसे अच्छा एक अप्रबंधित तीसरी पार्टी के लिए सी # से कॉल के दौरान हुई DLL विक्रेताओं के रूप में मैं यह पता लगाने सकता है। मैं क्या है पता लगाने पीठ (केवल एक जोड़े प्रणाली ईवेंट लॉग में निशान प्रदान की विफलताओं) में से एक अप्रबंधित DLL के लिए कॉल में मापदंडों के मार्शलिंग दौरान RtlMoveMemory समारोह में ntdll.dll में एक विफलता को इंगित करता है।

कॉल अप्रबंधित कार्य करने के लिए किया गया था:

ThirdParty.CxxxAutomationWrapper clientDLL = new ThirdParty.CxxxAutomationWrapper() ; 

object Parameter1 ; 
    : 
string theValue = "abcde" ; 
Parameter1 = theValue ; 
    : 
if (Parameter1 is string) 
{ 
    int returnCode = clientDLL.function (Parameter1 as string) ; 
} 

कॉल समय-समय पर ग्राहकों को कंप्यूटर पर विफल रहता है, लेकिन हमेशा जब दृश्य स्टूडियो (2010) में चलने काम करता है। पैरामीटर 1 का मान सही ढंग से सेट है (कभी शून्य नहीं)।

जब से मैं करने के लिए कॉल बदल दिया है:

String parameter1String = Parameter1.ToString() ; 
int returnCode = clientDLL.function (parameter1String) ; 

सब कुछ ठीक काम किया है। पैरामीटर 1 का मान बहुत नियंत्रित है और इस कोड को निष्पादित करने से पहले शून्य नहीं है।

इंटरफ़ेस किया जा रहा बुलाया (clientDLL.function) के रूप में परिभाषित किया गया है: [? सीमित]

HRESULT function ([in] BSTR parameter, 
        [out, retval] long *ret); 
के साथ मेरी

की समझ ग # में बयान 'के रूप में', मुझे समझ नहीं आता क्यों का पहला संस्करण यह असफल रहा। क्या कोई यह समझाने में मदद कर सकता है कि "स्ट्रिंग" के रूप में निर्दिष्ट पैरामीटर के साथ बुलाए जाने पर यह विफल क्यों होता है?

+0

समस्या को स्पष्ट करने में सहायता के लिए प्राप्त उत्तरों के जवाब में मूल पोस्ट को अपडेट किया गया। अपडेट्स में यह दिखाया गया है कि कैसे पैरामीटर 1 घोषित किया गया है और असाइन किया गया है, और ट्यूडर द्वारा सुझाए गए कॉल के आस-पास एक if (पैरामीटर 1 स्ट्रिंग) डालना है। –

+0

क्या आप लॉग इन करने का प्रयास कर सकते हैं कि 'पैरामीटर 1' के कौन से मान क्रैश होते हैं? क्या आप कोई पैटर्न देख सकते हैं? – Tudor

+0

मैंने उपरोक्त दिखाए गए सटीक कोड को कोड किया है, इसे "abcde" के साथ प्रारंभ करने वाले स्ट्रिंग वेरिएबल को असाइनमेंट को हार्डकोड करना और उस चर को पैरामीटर 1 पर परीक्षण करना (अगर पैरामीटर 1 स्ट्रिंग है) और यह अभी भी विजुअल स्टूडियो में ठीक काम करता है लेकिन बाहर विफल रहता है वीएस (कभी-कभी) का। –

उत्तर

5

क्योंकि obj as string और obj.ToString() समान नहीं हैं। पहले किसी प्रयास किए डाली है (एक तरह से (string)obj की तरह है, लेकिन जो विफलता पर null रिटर्न) है, जबकि सेकंड के लिए एक विधि वस्तु के एक स्ट्रिंग प्रतिनिधित्व लौटने कॉल है।

प्रैक्टिकल रूप से आप स्ट्रिंग के साथ संगत होने के बावजूद किसी ऑब्जेक्ट का स्ट्रिंग प्रस्तुति प्राप्त कर सकते हैं, लेकिन अगर वे संगत नहीं हैं तो कास्ट विफल हो जाएगी।

सरल उदाहरण:

object obj = new object(); // simple object 
Console.WriteLine(obj.ToString()); // prints System.Object 
Console.WriteLine((obj as string) == null); // True: obj is not a string! 
+0

मैंने तब से अपना नमूना कोड अपडेट किया है यह दिखाने के लिए कि पैरामीटर 1 में हमेशा एक वैध स्ट्रिंग ऑब्जेक्ट होता है। इसके अलावा मुझे त्रुटि की यादृच्छिकता और समस्या यह है कि विजुअल स्टूडियो के भीतर कोई समस्या नहीं चल रही है। –

+0

@ रिचर्ड बॉसमैन: तो आप निश्चित हैं कि 'पैरामीटर 1' हमेशा वैध स्ट्रिंग है? यदि आप कभी-कभी गलती से गैर-स्ट्रिंग पास कर रहे होते हैं, तो मैं उस परिस्थिति को देख सकता हूं, जैसे कि 'स्ट्रिंग' विफल रहता है, लेकिन 'ToString' नहीं होता है। – Tudor

+0

हां। अगर यह नहीं था, मुझे विश्वास है कि यह 1) हमेशा असफल होगा 2) विजुअल स्टूडियो के भीतर विफल। इस बिंदु से पहले पैरामीटर कई बार चेक किया गया है। उपरोक्त संदर्भित कोड एक डीएलएल में है। कोड एक प्रबंधित डीएलएल में है। स्ट्रिंग मूल रूप से प्रबंधित डीएलएल में एक अप्रबंधित सी ++ डीएलएल से गुजरती है। –

2

Parameter1.ToString() एक स्ट्रिंग के लिए किसी भी .NET ऑब्जेक्ट (System.String अर्थात् उदाहरण) प्रस्तुत करना होगा। Parameter1 as stringnull वापस करेगा यदि Parameter1 शून्य है या यदि यह System.String का उदाहरण नहीं है। यदि यह एक वर्ग है जो वास्तव में एक होने की बजाय स्ट्रिंग को लपेटती है, तो आप null के साथ समाप्त हो जाएंगे।

न तो पाठ्यक्रम के हर मामले में काम करेगा। यदि आपके पास System.String का उदाहरण है जो null है, तो Parameter1 as string सही ढंग से null लौटाएगा, जबकि Parameter1.ToString()NullReferenceException फेंक देगा।

एक सुरक्षित दृष्टिकोण होगा: Convert.ToString(Parameter1)

+0

प्रतिक्रिया के लिए धन्यवाद। मैंने तब से मूल पोस्ट को अपडेट किया है यह दिखाने के लिए कि पैरामीटर 1 हमेशा एक वैध स्ट्रिंग है। –

0

Parameter1 as string जहां .ToString()

string foo = Parameter1.ToString(); 

है तथ्य यह है कि पैरामीटर 1 सीधे एक स्ट्रिंग के लिए castable नहीं है, यह असफल रहने के लिए reson है

string foo 
try 
{ 
    foo = (string)Parameter1; 
} 
catch 
{ 
    foo = null; 
} 

के रूप में सोचा जा सकता है।