2010-09-14 9 views
5

नीचे दिए गए सी # में स्वचालन-संगत COM लाइब्रेरी पर विचार करें। यह एक सामान्य कॉम पैटर्न का पालन करता है जिसमें एक दृश्यमान फैक्ट्री कोक्लस फूफैक्टरी है जो आईसीआरएटफूओ को कार्यान्वित करता है जो टाइप IFoo का ऑब्जेक्ट बनाता है। FooFactory टाइप लाइब्रेरी में केवल कोक्लास है। (कारखाना पैटर्न COM के साथ विशेष रूप से उपयोगी है, क्योंकि यह पैरामीटरयुक्त कन्स्ट्रक्टरों की अनुमति नहीं देता है)।यह सी # कॉम क्लास वीबीस्क्रिप्ट से प्रयोग योग्य क्यों है लेकिन जेस्क्रिप्ट नहीं है?

नीचे कोड में, मुझे लगता है कि मैं से jscriptलौटे IFoo इंटरफ़ेस उपयोग नहीं कर सकते जब तक कि मैं FooImpl वर्ग ComVisible (टिप्पणी की लाइनों uncommenting द्वारा बनाने की खोज कर रहा हूँ, यह उस में एक coclass के रूप में प्रकट करने के लिए कारण बनता है पुस्तकालय टाइप करें)। वीबीस्क्रिप्ट से इसे एक्सेस करने में ऐसी कोई समस्या नहीं है।

है यही कारण है कि, मैं इस VBScript रन कर सकते हैं:

set ff = CreateObject("jstest.FooFactory") 
set foo = ff.CreateFoo(0) 
foo.Foo 

लेकिन इस कार्यात्मक रूप से समान JScript, विफल रहता है त्रुटि "सी के साथ: \ अस्थायी \ jstest \ jstest.js (4, 1) Microsoft JScript रनटाइम त्रुटि: 'foo' अशक्त या नहीं एक वस्तु है ":

var ff = new ActiveXObject("jstest.FooFactory"); 
var foo = ff.CreateFoo(0) 
//WScript.Stdout.WriteLine(null==foo) 
foo.Foo(); 

अगर मैं लाइन uncomment, मैं देख सकता है कि रिक्त == foo गलत है।

ऐसा क्यों होता है? क्या यह एक बग है? ध्यान दें कि मुझे लगता है कि यह एक समस्या है जेस्क्रिप्ट और सी #/नेट-विशिष्ट कार्यान्वयन (संभवत: आईडीस्पैच) का संयोजन है, क्योंकि मेरे पास अन्य समान COM सर्वर हैं - सी ++ में कार्यान्वित - जो इस समस्या को जेस्क्रिप्ट से प्रदर्शित नहीं करते हैं।

समस्या नीचे जाती है यदि मैं नीचे दिए गए कोड में टिप्पणी की गई रेखाओं को अनदेखा करता हूं, तो FooImpl को कोकलास के रूप में दिखाई देता है - लेकिन मैं विशेष रूप से ऐसा नहीं करना चाहता क्योंकि मैं कार्यान्वयन विवरण का खुलासा नहीं करना चाहता हूं। एक कामकाज FooImpl ComVisible बनाने के लिए प्रतीत होता है, लेकिन इसके कन्स्ट्रक्टर आंतरिक को चिह्नित करता है, जो ग्राहकों को सहकारी करने में सक्षम होने से रोकता है, लेकिन यह शायद ही सुरुचिपूर्ण है।

मैं विजुअल स्टूडियो 2005, .NET 2 के साथ WinXP SP3 पर चल रहा हूं, और वर्चुअलबॉक्स (विंडोज स्क्रिप्ट होस्ट 5.7 के साथ दोनों) पर TinyXP के पूरी तरह से ताजा इंस्टॉल पर इस मुद्दे को पुन: उत्पन्न करने में सक्षम हूं, और साथ ही विंडोज 7 अल्टीमेट .नेट एसडीके 2.0, 3.0, 3.5 और 4.0 (डब्ल्यूएसएच 5.8) का उपयोग कर। सभी ओएस 32-बिट थे।

पुस्तकालय कोड:

using System; 
using System.Runtime.InteropServices; 

[assembly: ComVisible(false)] 

namespace jstest 
{ 
    [ComVisible(true)] 
    public interface ICreateFoos 
    { 
     IFoo CreateFoo(int importantNumber); 
    } 

    [ComVisible(true)] 
    public interface IFoo 
    { 
     void Foo(); 
    } 

    [ComVisible(true)] 
    public class FooFactory : ICreateFoos 
    { 
     public IFoo CreateFoo(int importantNumber) 
     { // in *this* version, we don't use importantNumber yet 
      return new FooImpl(); 
     } 
    } 

    //[ComVisible(true)] 
    public class FooImpl : IFoo 
    { 
     public void Foo() 
     { 
      Console.WriteLine("Foo"); 
     } 
    } 
} 

आप संकलन और रजिस्टर कर सकते हैं के खिलाफ IFoo वस्तु से लौटे QueryInterface कहा जाता है जब यह

csc /target:library jstest.cs 
regasm /codebase jstest.dll 
+0

बीटीडब्ल्यू - कृपया टिप्पणी करें कि क्या आपने इस मुद्दे को पुन: पेश करने का प्रयास किया है और ऐसा करने में सफल/विफल रहा है। – bacar

+0

वीएस -2010 (सी # एक्सप्रेस) और विंडोज एक्सपी एसपी 3 के साथ पुन: उत्पादित। – arx

उत्तर

5

साथ (आप के रूप में व्यवस्थापक regasm को चलाने के लिए हो सकता है) ID12patch GUID के लिए CreateFoo यह E_NOINTERFACEदेता है जब तक कॉमविज़िबल वास्तविक कार्यान्वयन कक्षा के लिए सेट किया गया है।

जब jscript Foo विधि यह QueryInterface इस विशिष्ट GUID के साथ सहित कई बार, कॉल कॉल करने के लिए तैयार करता है, और यह Invoke इस्तेमाल करने की कोशिश नहीं कर रहा है के बाद से एक त्रुटि रिटर्न है।

VBScriptFoo विधि यह नहीं जांच इंटरफ़ेस IDispatch का समर्थन करता है करता है कॉल करने के लिए तैयार करता है जब। QueryInterface को एक बार, IDISpatchEx के लिए GUID के साथ बुलाया जाता है, लेकिन ऐसा लगता है कि IDISpatch समर्थित होगा।

+2

नोट: vbscript यह समझने के लिए पर्याप्त स्मार्ट है कि लौटा इंटरफ़ेस (IFoo) IDISpatch को बढ़ाता है और इसलिए इसे QueryInterface को कॉल करने की आवश्यकता नहीं है। यदि एक ही वस्तु को IFoo के बजाय एक अज्ञात के रूप में वापस कर दिया जाता है तो VB * करता है * IDISpatch'd GUID के साथ QueryInterface को कॉल करता है। –

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