मैं यूनिक्स प्रकार प्लेटफार्म पर सी ++ में COM के कस्टम कार्यान्वयन को कार्यान्वित करने के लिए देख रहा हूं ताकि मुझे गतिशील रूप से लोड ऑब्जेक्ट उन्मुख कोड को लिंक करने और लिंक करने की अनुमति मिल सके। मुझे लगता है कि यह कार्यक्षमता के समान सेट पर आधारित होगा जो POSIX लोड करने और डीएलएल यानी dlopen, dlsym और dlclose को कॉल करने के लिए प्रदान करता है।
अपने सबसे सरल स्तर पर, COM इंटरफेस के साथ लागू किया गया है। C++ में, यदि आप शुद्ध आभासी, या सार आधार वर्ग के विचार के साथ सहज महसूस कर रहे हैं, तो आप पहले से ही C++
struct IMyInterface {
void Method1() =0;
void Method2() =0;
};
COM क्रम अतिरिक्त सेवाओं है कि करने के लिए आवेदन का एक बहुत प्रदान करता है में एक इंटरफेस को परिभाषित करने के लिए कैसे पता खिड़कियां पर्यावरण लेकिन वास्तव में एक मिनी एप्लिकेशन में "मिनी" COM को कार्यान्वित करने की आवश्यकता नहीं होती है, जो पारंपरिक रूप से डलोपेन, डीएलएसआईएम इत्यादि की अनुमति से अधिक ओओ इंटरफ़ेस से कनेक्ट करने के साधन के रूप में
COM ऑब्जेक्ट्स को .dll में लागू किया जाता है। , .so या .dylib फ़ाइलें आपके प्लेटफ़ॉर्म के आधार पर। इन फ़ाइलों को कम से कम एक फ़ंक्शन को निर्यात करने की आवश्यकता है जो मानक है: DllGetClassObject
अपने पर्यावरण में आप इसे प्रोटोटाइप कर सकते हैं, हालांकि आप चाहते हैं कि विंडोज़ पर COM रनटाइम के साथ इंटरऑप करना स्पष्ट रूप से नाम और पैरामीटर को कॉम मानक के अनुरूप होना चाहिए ।
मूल विचार यह है कि यह एक GUID - 16 बाइट्स के लिए एक सूचक को पारित किया जाता है जो विशिष्ट रूप से किसी विशेष वस्तु को सौंपा जाता है, और यह बनाता है (GUID पर आधारित) और फैक्ट्री ऑब्जेक्ट के आईसीएलएएसफ़ैक्टरी * को देता है।
आईसीएलएएसफ़ैक्टरी :: CreateInstance विधि कहलाते समय ऑब्जेक्ट के उदाहरण बनाने के लिए, कॉम रनटाइम द्वारा कारखाने ऑब्जेक्ट का उपयोग किया जाता है।
तो, अब तक आप
- पारित कर दिया GUID में यह देखने के लिए जाँच करता है कि एक गतिशील पुस्तकालय कम से कम एक प्रतीक, नाम "DllGetClassObject" निर्यात (या उसके किसी भिन्न रूप)
- एक DllGetClassObject विधि है और जो वस्तु का अनुरोध किया जा रहा है, और फिर एक 'नई CSomeObjectClassFactory "
- एक CSomeObjectClassFactory कार्यान्वयन कि औजार (से निकला) IClassFactory करता है, और CreateInstance विधि के लिए' नई 'CSupportedObject के उदाहरण लागू करता है।
- CSomeSupportedObject जो IU अज्ञात से प्राप्त एक कस्टम, या COM परिभाषित इंटरफ़ेस लागू करता है। यह महत्वपूर्ण है क्योंकि IClassFactory :: CreateInstance को एक आईआईडी पारित किया जाता है (फिर से, इस समय एक इंटरफ़ेस को परिभाषित करने वाला 16byte अद्वितीय आईडी) कि उसे ऑब्जेक्ट पर QueryInterface की आवश्यकता होगी।
मैं समझता हूँ कॉम के सामान्य विचार है कि आप कुछ कार्यों से लिंक है कि IE QueryInterface, AddRef और एक आम dll (Kernel32.dll) जो तब अभिगम अंतरफलक जो सिर्फ एक मेज हैं करने की अनुमति देता में रिलीज फ़ंक्शन पॉइंटर्स का ऑब्जेक्ट पर पॉइंटर के साथ encapsulated जिसके लिए फ़ंक्शन पॉइंटर्स के साथ कॉल किया जाना चाहिए। इन कार्यों को अज्ञात के माध्यम से उजागर किया गया है जिन्हें आप का उत्तराधिकारी होना चाहिए।
असल में, COM OLE32.dll द्वारा कार्यान्वित किया गया है जो CoCreateInstance नामक "सी" एपीआई का खुलासा करता है। ऐप ने CoCreateInstance को एक GUID पास किया, जो इसे विंडोज रजिस्ट्री में दिखता है - जिसमें GUID का डीबी है -> "पथ से डीएल" मैपिंग। ओएलई/कॉम फिर डीएलएल लोड करता है (डीएलओपीएन) डीएलजी में गुजरता है, जो कि GUID में गुजरता है, यह सुनिश्चित करता है कि सफल होता है, ओएलई/कॉम फिर CreateInstance को कॉल करता है और परिणामी इंटरफ़ेस को ऐप पर देता है।
तो यह सब कैसे काम करता है? ऑब्जेक्ट उन्मुख कोड को गतिशील रूप से लिंक और लोड करने का कोई बेहतर तरीका है? एक डीएलएल से विरासत कैसे काम करती है - क्या बेस क्लास के लिए प्रत्येक कॉल को एक खुला सदस्य समारोह होना चाहिए यानी निजी/संरक्षित/जनता को केवल अनदेखा किया जाता है?
कक्षा में प्रत्येक विधि को "सजाए गए" प्रतीक के रूप में निर्यात करके डीएल/एस/डिलिब कार्यों से सी ++ कोड की निहित विरासत। विधि का नाम कक्षा के साथ सजाया गया है, और प्रत्येक पैरामीटर का प्रकार। यह वही तरीका है जो प्रतीकों को स्थिर पुस्तकालयों (.a या .lib फाइल iirc) से निर्यात किया जाता है। स्टेटिक या गतिशील पुस्तकालय, "निजी, संरक्षित आदि" हमेशा कंपाइलर द्वारा लागू किया जाता है, हेडर फ़ाइलों को पार्स कर रहा है, कभी भी लिंकर नहीं।
मैं काफी अच्छी तरह से सी में निपुण कर रहा हूँ ++ और टेम्पलेट मेटा प्रोग्रामिंग और पहले से ही एक पूरी तरह से चिंतनशील सी ++ प्रणाली यानी सदस्य गुण, सदस्य कार्य करता है और वैश्विक/स्थिर कार्यों को बढ़ावा देने का उपयोग करता है। DLLs कि लोड पर लोड किए गए हैं, कार्यावधि में dlopen के माध्यम से नहीं -
C++ वर्गों आमतौर पर केवल स्थिर लिंकेज के साथ DLLs से निर्यात किया जा सकता है। COM यह सुनिश्चित करके सी ++ इंटरफेस को गतिशील रूप से लोड करने की अनुमति देता है कि COM में उपयोग की जाने वाली सभी डेटाटाइप या तो पॉड प्रकार हैं, या शुद्ध वर्चुअल इंटरफेस हैं।यदि आप इस नियम को तोड़ते हैं, तो एक इंटरफ़ेस को परिभाषित करके जो किसी बूस्ट या किसी अन्य प्रकार की ऑब्जेक्ट को पारित करने का प्रयास करता है, आप जल्द ही ऐसी परिस्थिति में आ जाएंगे जहां संकलक/लिंकर को हेडर फ़ाइल से अधिक की आवश्यकता होगी ताकि यह पता चल सके कि क्या हो रहा है और आपका ध्यान से तैयार "कॉम" डीएल को कार्य करने के लिए स्थिर या अंतर्निहित रूप से लिंक करना होगा।
COM का दूसरा नियम किसी गतिशील लाइब्रेरी सीमा के पार किसी ऑब्जेक्ट का स्वामित्व कभी नहीं पास करता है। यानी किसी डीएलएल से इंटरफ़ेस या डेटा कभी वापस न करें, और ऐप को इसे हटाने की आवश्यकता है। इंटरफेस को सभी को अज्ञात, या कम से कम एक रिलीज() विधि को लागू करने की आवश्यकता है, जो ऑब्जेक्ट को इसे हटाने की अनुमति देता है। किसी भी लौटाए गए डेटा प्रकारों में भी एक प्रसिद्ध डी-आवंटक होना चाहिए - यदि आपके पास "CreateBlob" नामक विधि के साथ एक इंटरफेस है, तो शायद "DeleteBlob" नामक एक दोस्त विधि होनी चाहिए।