2010-06-17 6 views
11

जब आप .NET कोड से COM ऑब्जेक्ट को इंटरफ़ेस करते हैं, तो VS इंटरऑप कक्षाओं के साथ एक इंटरऑप DLL बनाता है।इंटरऑप क्लास के माध्यम से बिना किसी COM ऑब्जेक्ट को .NET से एक्सेस क्यों करता है, कभी-कभी काम करता है?

उदाहरण:

आप एक foo.dll औजार एक COM पुस्तकालय फू, COM इंटरफेस "Ibar" के एक कार्यान्वयन शामिल है कि नहीं है। आप foo.dll को .NET प्रोजेक्ट में संदर्भ जोड़ते हैं। इन/बिन में, आप एक Interop.FooLib.dll देखेंगे। ऑब्जेक्ट ब्राउज़र में, आप Interop.FooLib देखेंगे, जिसके अंतर्गत आप FooLib देखेंगे, जिसके तहत आप बारक्लास देखेंगे, जिसके तहत आप उस बार और आईबार के तहत बेस प्रकार देखेंगे।

अपने .NET कोड में, एक चर घोषित करते समय, आप FooLib टाइप कर सकते हैं, और इंटेलिजेंस आपको बार या बारक्लास() के विकल्प देगा।

जो मैंने समझा, उससे कोई फर्क नहीं पड़ता कि आप एक परिवर्तनीय घोषणा में किस चीज का उपयोग करते हैं, लेकिन इससे कोई फर्क नहीं पड़ता कि आपने अपने कन्स्ट्रक्टर के लिए क्या उपयोग किया है।

है यही कारण है, इन दोनों को काम करना चाहिए:

FooLib.BarClass theBar = new FooLib.BarClass(); 
FooLib.Bar theBar = new FooLib.BarClass(); 

लेकिन यह काम नहीं करना चाहिए:

FooLib.Bar theBar = new FooLib.Bar(); 

यहाँ समस्या है। हमने बस एक अजीब बग को ट्रैक किया, जहां कोड कुछ ग्राहकों के लिए काम कर रहा था, और हमारे विकास और परीक्षण वातावरण में काम किया, एक ग्राहक साइट पर काम नहीं किया, बार() कन्स्ट्रक्टर का उपयोग कर प्रोग्रामर बन गया।

तो, क्या कोई भी समझा सकता है कि दो रचनाकारों, बार(), और बारक्लास() के बीच अंतर क्या है?

क्या कोई यह समझा सकता है कि बार() कन्स्ट्रक्टर क्यों काम करता है, कभी-कभी?

क्या कोई यह सुनिश्चित करने के लिए कोई तरीका प्रदान कर सकता है कि कोई भी गलती से गलत कन्स्ट्रक्टर को कॉल नहीं कर रहा है, कोड की हर पंक्ति को पढ़े बिना?

- जोड़ा -

यह सुझाव दिया गया है कि समस्या हमारे कॉम कार्यान्वयन में था। यह हम क्या कर रहे हैं:

आईडीएल:

[ 
    object, 
    uuid(...), 
    dual, 
    helpstring("IBar Interface"), 
    pointer_default(unique), 
    nonextensible 
] 
interface IBar : IDispatch 
{ 
    [id(1), helpstring("method barify")] 
     HRESULT barify([out, retval] VARIANT_BOOL *rVal); 
    // ... 
}; 
// ... 
[ 
    uuid(...), 
    version(1.0), 
    helpstring("Foo 1.0 Type Library") 
] 
library FooLib 
{ 
    importlib("stdole32.tlb"); 
    importlib("stdole2.tlb"); 
    // ... 
    [ 
     uuid(...), 
     helpstring("Bar Class") 
    ] 
    coclass Bar 
    { 
     [default] interface IBar; 
    }; 
    // ... 
}; 

कार्यान्वयन:

class ATL_NO_VTABLE CBar : 
    public CComObjectRootEx<CComSingleThreadModel>, 
    public CComCoClass<CBar, &CLSID_Bar>, 
    public IDispatchImpl<IBar, &IID_IBar, &LIBID_FooLib>, 
    public ISupportErrorInfoImpl <&IID_IBar> 
{ 
public: 
    CBar(); 

    DECLARE_REGISTRY_RESOURCEID(IDR_BAR) 

    DECLARE_PROTECT_FINAL_CONSTRUCT() 

    BEGIN_COM_MAP(CBar) 
     COM_INTERFACE_ENTRY(IBar) 
     COM_INTERFACE_ENTRY(IDispatch) 
     COM_INTERFACE_ENTRY(ISupportErrorInfo) 
    END_COM_MAP() 

    // ... 
}; 

- बाद में जोड़ा -

डिकंपाइल *, नेट परावर्तक के माध्यम से:

[ComImport, CoClass(typeof(BarClass)), Guid("...")] 
public interface Bar : IBar 
{ 
} 

* मैं नहीं करता ध्यान दें कि रिफ्लेक्टर यूआई इसे एक डिस्सेप्लर कहता है - अगर यह एचएलएल आउटपुट कर रहा है, तो यह एक डिकंपाइल है।

उत्तर

2

शानदार सवाल। बहुत से लोग आश्चर्यचकित हैं कि यह बिल्कुल काम करता है क्योंकि बार एक इंटरफ़ेस है और निश्चित रूप से आपको इंटरफ़ेस का नया उदाहरण बनाने में सक्षम नहीं होना चाहिए! लेकिन हालांकि मुझे कार्यान्वयन के बारे में कोई विशिष्ट जानकारी नहीं मिल रही है, मुझे एडम नाथन की COM इंटरऑप पुस्तक में पढ़ना याद है कि सी # CoClassAttribute के साथ चिह्नित COM इंटरफेस के लिए एक विशेष अपवाद बनाता है और कॉल को इसके बजाय कोक्लास के तत्काल में बदल देता है।

लेकिन मुझे नहीं पता कि यह कभी-कभी क्यों काम करेगा और कभी-कभी काम नहीं करेगा।

0

सिद्धांत में बार() कन्स्ट्रक्टर क्लास ऑब्जेक्ट की बजाय इंटरफ़ेस को स्पष्ट रूप से वापस कर रहा है। मैं बिल्कुल समझ नहीं पा रहा हूं कि .NET एक इंटरफ़ेस के निर्माण का समर्थन कैसे कर रहा है !?

किसी भी मामले में, आप बार() कन्स्ट्रक्टर पर क्लिक कर सकते हैं और Shift-F12 दबा सकते हैं। यह आपको कोड में कहीं और दिखाएगा जहां उस कन्स्ट्रक्टर का उपयोग किया जा रहा है। मैं किसी उपयोगकर्ता को इस कन्स्ट्रक्टर को अनजाने में कॉल करने से रोकने के तरीके के बारे में नहीं सोच सकता।

0

क्या आपने this question पर चर्चा पढ़ी है? यह वास्तव में इस मुद्दे पर चर्चा करता है जो मुझे लगता है।

+0

यह इस मुद्दे पर चर्चा करता है, लेकिन यह समझाता नहीं है कि यह एक मशीन पर एक और एक अलग तरीके से क्यों काम करेगा। क्या हम .NET में एक बग से निपट रहे हैं जो एक सर्विस पैक में तय किया गया था जिसे स्थापित नहीं किया गया है? –

+0

पर्याप्त समय दिया गया है कि आप शायद कारण को इंगित कर सकते हैं, यह ओएस एसपी/बगफिक्स भी बहुत अच्छा हो सकता है, या पूरी तरह से अलग हो सकता है ...: -/मैं आपके प्रश्न को ऊपर उठाने से ज्यादा नहीं कर सकता! –

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