2010-07-09 13 views
5

मुझे पता है कि हम ICLassFactory इंटरफ़ेस प्राप्त करने के लिए CoLoadLibrary और DllGetClassObject का उपयोग कर सकते हैं और DLL को पंजीकृत किए बिना COM घटक इंटरफ़ेस प्राप्त कर सकते हैं।क्या EXE (आउट ऑफ़ प्रोसेस) COM सर्वर के लिए पंजीकरण-मुक्त सक्रियण संभव है?

लेकिन EXE में COM घटक के बारे में क्या? क्या कोई तरीका है कि मैं एक अलग फ़ाइल पथ प्रदान करके EXE-type COM सर्वर से COM घटक इंटरफ़ेस प्राप्त कर सकता हूं?

उत्तर

3

यदि आप वास्तविकregistration free COM का उपयोग करते हैं, तो आप इसे इन-प्रो और आउट-ऑफ-प्रो COM ऑब्जेक्ट्स दोनों के लिए काम करने में सक्षम होना चाहिए।

जैसा कि शार्पतोथ ने बताया, आप वास्तव में पंजीकरण मुक्त COM का उपयोग नहीं कर रहे हैं। इसके बजाय आप वास्तव में सक्रियण के दौरान उपयोग की जाने वाली कॉल को फोक करके अपना खुद का रोलिंग कर रहे हैं। आपका समाधान काम कर सकता है यदि आप अपने एप्लिकेशन और COM सर्वर को सक्रिय करते हैं जो आप सक्रिय कर रहे हैं लेकिन यह अन्यथा विफल होने की संभावना है।

+0

मुझे यकीन नहीं है कि पहला पैराग्राफ सत्य है, जिस लेख में यह लिंक है, आउट-ऑफ-प्रोसेस EXE सर्वर का एकमात्र उल्लेख यह कहना है कि उन्हें पंजीकरण-मुक्त COM के साथ उपयोग नहीं किया जा सकता है। यह धागा भी उपयोगी है और आरओटी के साथ मुद्दों को इंगित करता है जो पंजीकरण मुक्त COM जाहिर तौर पर प्रबंधन के लिए उपेक्षा करता है: http://social.msdn.microsoft.com/Forums/vstudio/en-US/3849f22d-c8b8-429e- a03a-37601411acec/registrationfree-exe-com-server- लगता है कि केवल मूल, इन-प्रोसेस (गैर-उन्नत) COM DLL ऑब्जेक्ट्स को reg-free तंत्र द्वारा समर्थित किया जाता है और कुछ और विदेशी के लिए आपको अपना खुद का रोल करना पड़ता है । –

+0

लिंक-केवल उत्तर वास्तव में खराब हैं क्योंकि लिंक के गायब होने की प्रवृत्ति है ... इस उत्तर में से एक की तरह। – Stephane

1

आप पॉइंटर के रूप में फ़ंक्शन कॉल में COM घटक पास कर सकते हैं।

तो मान लीजिए कि आप अपने EXE में किसी ऑब्जेक्ट को कार्यान्वित करते हैं, और यह एक डीएलएल से एक और COM ऑब्जेक्ट लोड करता है, तो आप डीएलएल से ऑब्जेक्ट पर EXE- आधारित ऑब्जेक्ट पास कर सकते हैं। लोड ऑब्जेक्ट को एक इंटरफ़ेस का समर्थन करने की आवश्यकता होगी जिसमें एक फ़ंक्शन है जो पॉइंटर स्वीकार करता है, उदा।

interface ILoadedObject 
{ 
    HRESULT GiveObject(IUnknown *pObj); 
}; 

DLL आधारित वस्तु को लागू करने वाली हैं, तो आप इसे अपने EXE से कॉल और यह एक वस्तु कि कहीं भी पंजीकृत नहीं है पारित कर सकते हैं, तो इस लक्ष्य को हासिल करने के लिए एक EXE में वस्तुओं रजिस्टर करने के लिए कोई जरूरत नहीं है ।

केवल आवश्यकताओं IUnknown के सही क्रियान्वयन पर कर रहे हैं: जब तक Release बार की सही संख्या बुलाया गया है वस्तु को नष्ट नहीं है, और यह सुनिश्चित करें कि QueryInterface वस्तु पर इंटरफेस की एक निश्चित सेट के बीच पार करने के लिए इस्तेमाल किया जा सकता और IUnknown के लिए पूछताछ हमेशा एक ही पता देता है।

दूसरी ओर, आप ऑब्जेक्ट्स के सर्वर के रूप में एक EXE पंजीकृत कर सकते हैं, लेकिन इसमें बहुत जटिलता शामिल है; COM को EXE चलाना शुरू करना है और फिर इसे विंडोज संदेश कतार के माध्यम से संदेश भेजना है। यह केवल ओएलई के लिए व्यापक रूप से उपयोग किया जाता है; यह काफी नाजुक हो सकता है।

अद्यतन

एक और पूरा समाधान एक वस्तु प्रकार का एक उदाहरण बनाने के लिए है, लेकिन EXE यह कैसे काम करता परिभाषित करने के लिए अनुमति देने के लिए एक मानक तरीका परिभाषित करने के लिए है। EXE लागू करना होगा:

interface IComponent; 

interface IEnvironment : IUnknown 
{ 
    HRESULT CreateInstance(REFCLSID clsid, IComponent **ppNew); 
} 

हर घटक इस इंटरफेस का समर्थन करना चाहिए: अब

interface IComponent : IUnknown 
{ 
    HRESULT SetEnvironment(IEnvironment *pEnv); 
} 

, मानक व्यवहार जहां EXE रजिस्ट्री का उपयोग करने के घटकों को खोजने के लिए चाहता है पाने के लिए, यह CreateInstance लागू कर सकते हैं इस तरह की विधि:

HRESULT Env::CreateInstance(REFCLSID clsid, IComponent **ppNew) 
{ 
    HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, 
        __uuidof(IComponent), (void **)&ppNew); 
    if (FAILED(hr)) 
     return hr; 

    (*ppNew)->SetEnvironment(this); 
    return S_OK; 
} 

लेकिन निश्चित रूप से यह इसे बदल सकता है और कुछ घटकों को "इंजेक्ट" कर सकता है। तो रजिस्ट्री के बजाय (या इसके अलावा), एक कॉन्फ़िगरेशन फ़ाइल का उपयोग किया जा सकता है।

क्योंकि हर घटक पर्यावरण के बारे में सूचित किया जाता है जब यह बनाई गई है, यह आगे घटक बनाने के लिए पर्यावरण का उपयोग कर सकते हैं::

या (के रूप में आपके द्वारा पूछे गए) EXE कुछ घटकों के निर्मित कार्यान्वयन हो सकता था
// inside some component: 
HRESULT Comp::SetEnvironment(IEnvironment *e) 
{ 
    m_env = e; // using a smart pointer for ref-counting 
    return S_OK; 
} 

// in some method of the component 

ComPtr<IComponent> button; 
m_env->CreateInstance(CLSID_Button, &button); 

// now query button for more useful interface... 

इसलिए जब भी कोई घटक बनाया जाता है, पर्यावरण (EXE में परिभाषित) वास्तव में नियंत्रित कर सकता है कि घटक का कार्यान्वयन कैसे पाया जाता है। प्रत्येक सृजन EXE के माध्यम से चला जाता है।

इसे कभी-कभी "निर्भरता इंजेक्शन" या "नियंत्रण में उलटा" कहा जाता है।

+0

धन्यवाद, मुझे नहीं पता कि मैं आपके समाधान को कितना समझता हूं, ऐसा लगता है कि यह एक वैकल्पिक तरीका है: 1. EXE प्रारंभ करें और ऑब्जेक्ट बिंदु को डीएलएल आधारित COM घटक पर रखें। 2. जब मुझे ऑब्जेक्ट EXE लागू घटक का उपयोग करने की आवश्यकता है, तो मुझे इसे डीएलएल घटक के माध्यम से प्राप्त करना चाहिए जो एक सूचक कंटेनर को लागू करता है जिसमें EXE फ़ाइलों में लागू घटक शामिल होता है। क्या मुझे यह मिला है? – Gohan

+0

मुझे लगता है कि मैं आपको समझता हूं और मुझे विश्वास है कि आपको यह मिल गया है। –

2

नहीं, आप नहीं कर सकते। आपको अपने प्रोग्राम और आउट-प्रो COM सर्वर के बीच COM सेटअप marshalling की आवश्यकता है। इसे प्राप्त करने के लिए आपको CoInitialize() और फिर CoCreateInstance() या CoGetClassObject() पर कॉल करना होगा।

पथ आप एक में proc सर्वर के साथ वर्णन - CoLoadLibrary() और फिर DllGetClassObject() बुला - वास्तव में एक गंदा हैक है - यह सामान्य COM तंत्र बाईपास और तो उदाहरण के लिए कोई मार्शलिंग में भले ही यह सूत्रण को संतुष्ट करने की जरूरत है शुरू होगा मॉडल आवश्यकताओं (एसटीए/एमटीए सामान)। इस तरह का गंदा हैक संभव है क्योंकि एक इन-प्रो सर्वर एक नियमित डीएलएल है जिसमें कई प्रसिद्ध कार्यों का खुलासा किया जाता है। आउट-प्रो COM सर्वर के लिए भी असंभव है - आपको उस मामले में COM पर भरोसा करना होगा।

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