2009-06-03 10 views
12

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

तो मेरा सवाल यह है कि मैं एमएफसी, .NET, C#, WTL, या ATL पर निर्भर किए बिना COM ऑब्जेक्ट बनाने के लिए सी में आईडीस्पैच का उपयोग कैसे कर सकता हूं। मुझे विश्वास है कि अगर मैं ऐसा करता हूं तो मैं बिना किसी समस्या के अपने कोड को संकलित कर पाऊंगा।

उत्तर

15

में सी ++ इंटरफेस बनाना संभव है। कोडप्रोजेक्ट पर "सादा सी में सीओ" नामक एक अच्छा आलेख है।

यहां the link to Part 1 है।

उस लेख में COM इन सी के साथ काम करने और लेखक के बाद के अनुवर्ती अनुमोदन (मुझे लगता है कि श्रृंखला में 3 या 4 हैं) के साथ काम करने की बहुत अच्छी जानकारी है।

संपादित करें:
मैं गलत था, 8 भाग हैं!

Part 2
Part 3
Part 4
Part 5
Part 6
Part 7
Part 8

+0

यह वास्तव में एक बहुत अच्छा ट्यूटोरियल है, मैं इसे देख रहा था, और पहला भाग बताता है कि COM ऑब्जेक्ट बनाने के लिए, जो मेरे पास पहले से है, समस्या यह है कि मेरी COM ऑब्जेक्ट सी # में लिखा गया है, मैंने ट्यूटोरियल में देखा है कि आपको एक शामिल (.h) फ़ाइल बनाने की आवश्यकता है जिसमें आपको अपने COM ऑब्जेक्ट में VTable's, GUID और संरचनाएं निर्दिष्ट करनी होंगी, अब, क्या मैं यह कर सकता हूं भले ही मेरा COM ऑब्जेक्ट सी # है? – Vic

+0

हम्म - मुझे लगता है कि यह संभव है, क्या आप रजिस्ट्री में अपना सी # COM ऑब्जेक्ट पंजीकृत करते हैं? मुझे लगता है कि यह सब आवश्यक है। COM एक द्विआधारी मानक है, इसलिए वीटीबल इस पर ध्यान दिए बिना कि यह सी #, सी ++, वीबी आदि में लागू किया गया है या नहीं। –

3

सामान्यतः, एक सी ++ आईडीस्पैच इंटरफ़ेस फ़ंक्शन पॉइंटर्स की एक तालिका है। सी में, यह कुछ ऐसा दिखाई देगा:

typedef struct { 
    HRESULT(*pQueryInterface)(void* this, REFIID riid, void **ppvObject); 
    ULONG(*pAddRef)(void* this); 
    ULONG(*pRelease)(void* this); 
    HRESULT(*pGetTypeInfoCount)(void* this, unsigned int* pctInfo); 
    HRESULT(*pGetTypeInfo)(void* this, unsigned int iTInfo,LCID lcid, ITypeInfo** ppTInfo); 
    HRESULT(*pGetIDsOfNames)(void* this, REFIID riid, OLECHAR** rgszNames, unsigned int cNames, LCID lcid, DISPID* rgDispId); 
HRESULT(*pInvoke)(void* this, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, unsigned int* puArgErr); 
} IDispatch_in_C; 

नोट हर विधि पहले पैरामीटर के रूप में एक इस सूचक है, और आप इस तरह के ITypeInfo, REFIID, DISPID, आदि के रूप में अधिक प्रकार को परिभाषित करने की आवश्यकता होगी कि है कि, आदि

तो, यह एक बड़ा काम है। लेकिन शुद्ध सी

+2

ध्यान दें कि आपको यह सुनिश्चित करने की ज़रूरत है कि आपके कॉलिंग सम्मेलन मेल खाते हैं अन्यथा आपके पैरामीटर पासिंग ऑर्डर और स्टैक क्लीनअप ठीक से काम नहीं करेगा। सुनिश्चित करें कि इन विधियों को 'stdcall' कॉलिंग सम्मेलन का उपयोग करने के रूप में घोषित किया गया है। –

+0

यह इस तथ्य को स्पष्ट रूप से समझाता नहीं है कि सी ++ में आईडीस्पेच इस स्केल का उपयोग करता है, इसलिए यह इसे एक्सेल के माध्यम से पास करता है, न कि स्टैक पर; जबकि सी में यह ढेर के माध्यम से गुजरता है और ecx नहीं; जबकि यदि आप सी या सी ++ का उपयोग कर रहे हैं तो CoCreateInstance परवाह नहीं है। कोई मतलब नहीं है कि गलत कॉलिंग सम्मेलन के कारण संस्करणों में से कोई एक विफल क्यों नहीं होता है। जैसा ऊपर बताया गया है, आपका उदाहरण cdecl को डिफ़ॉल्ट करता है जबकि कॉम stdcall की अपेक्षा करता है, इसलिए आप स्टैक को दो बार प्रभावी ढंग से दूषित करने की सफाई करते हैं। – Dmitry

3

इसके अलावा, आप disphelper लाइब्रेरी का उपयोग कर सकते हैं।

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