2009-12-24 9 views
10

क्या यह सी ++ में एक डीएलएल विकसित करने के लिए मान्य है जो साझा पॉइंटर्स को बढ़ावा देता है और उन्हें पैरामीटर के रूप में उपयोग करता है?क्या DLL इंटरफ़ेस में boost :: साझा पीआरटी का उपयोग करना ठीक है?

तो, क्या इस तरह के कार्यों को निर्यात करना ठीक है?

1.) boost::shared_ptr<Connection> startConnection(); 
2.) void sendToConnection(boost::shared_ptr<Connection> conn, byte* data, int len); 

विशेष में: DLL सीमाओं या पार संदर्भ गिनती काम की आवश्यकता है कि exe होगा करता है और एक ही क्रम का उपयोग DLL?

उद्देश्य स्वामित्व स्वामित्व वाली समस्याओं से निपटने का इरादा है। इसलिए ऑब्जेक्ट हटा दिया जाता है जब दोनों डीएल और एक्सई इसका संदर्भ नहीं देते हैं।

उत्तर

10

प्रभावी सी ++ (तीसरा संस्करण) में स्कॉट मेयर्स के अनुसार, साझा_प्टर डीएल सीमाओं में सुरक्षित हैं। Shared_ptr ऑब्जेक्ट इसे बनाए गए डीएलएल से विनाशक को पॉइंटर रखता है।

मद 18 वह राज्यों में अपनी पुस्तक में, पार DLL समस्या " tr1 का एक विशेष रूप से अच्छा सुविधा :: shared_ptr कि यह स्वचालित रूप से एक और संभावित ग्राहक त्रुटि, समाप्त करने के लिए अपने प्रति-सूचक Deleter का उपयोग करता है" " यह समस्या तब होती है जब किसी ऑब्जेक्ट को गतिशील रूप से लिंक्ड लाइब्रेरी (डीएलएल) में नए का उपयोग करके बनाया जाता है लेकिन एक अलग DLL में हटा दिया जाता है। पर कई प्लेटफॉर्म, ऐसे क्रॉस-डीएलएल नए/हटाए गए जोड़े रनटाइम त्रुटियों के कारण होते हैं। tr1 :: shared_ptr समस्या से बचें, क्योंकि इसका डिफ़ॉल्ट डिलीटर उसी DLL से हटा देता है जहां tr1 :: shared_ptr बनाया गया है। "

टिम लेशेर के पास देखने के लिए एक दिलचस्प गॉचा है, हालांकि, वह here का उल्लेख करता है। आपको यह सुनिश्चित करने की ज़रूरत है कि साझा_प्टर बनाने वाले डीएलएल को साझा_प्टर अंततः दायरे से बाहर होने से पहले अनलोड नहीं किया जाता है। मैं कहूंगा कि ज्यादातर मामलों में यह कुछ ऐसा नहीं है जिसे आप देखना चाहते हैं, लेकिन यदि आप डीएलएस बना रहे हैं जो कम से कम युग्मित हो जाएंगे तो मैं एक साझा_प्टर का उपयोग करने के खिलाफ अनुशंसा करता हूं।

एक और संभावित नकारात्मक पक्ष यह सुनिश्चित कर रहा है कि दोनों पक्ष बूस्ट लाइब्रेरी के संगत संस्करणों के साथ बनाए गए हैं। बूस्ट का shared_ptr लंबे समय तक स्थिर रहा है। कम से कम 1.34 यह tr1 संगत रहा है।

+2

सावधानी: यदि आप स्थिर सीआरटी को जोड़ रहे हैं तो आपको समस्याएं होंगी। प्रत्येक मॉड्यूल जो सीआरटी से स्थिर रूप से जुड़ा हुआ है, उसका अपना ढेर हो जाता है। यदि सभी मॉड्यूल डीएलएल सीआरटी से लिंक करते हैं तो वे सभी एक ढेर साझा करेंगे। – Zac

2

डीएलएल आमतौर पर संसाधनों का मालिक नहीं है - संसाधनों का स्वामित्व उन प्रक्रियाओं के स्वामित्व में होता है जो डीएलएल का उपयोग करते हैं। आप शायद एक सादा सूचक लौटने से बेहतर हैं, जिसे आप कॉलिंग पक्ष पर साझा पॉइंटर में स्टोर करते हैं। लेकिन अधिक जानकारी के बिना इस बारे में 100% निश्चित होना मुश्किल है।

4

मेरी राय में, यदि यह मानक में नहीं है और यह आपकी लाइब्रेरी द्वारा प्रदान की गई वस्तु/तंत्र नहीं है, तो यह लाइब्रेरी में इंटरफ़ेस का हिस्सा नहीं होना चाहिए। आप संदर्भ गणना करने के लिए अपना स्वयं का ऑब्जेक्ट बना सकते हैं, और शायद नीचे बूस्ट का उपयोग करें, लेकिन इसे स्पष्ट रूप से इंटरफ़ेस में प्रकट नहीं किया जाना चाहिए।

2

यदि आप एक डीएल इंटरफेस से कच्चे पॉइंटर्स का पर्दाफाश करते हैं तो कुछ देखने के लिए कुछ। यह आपको साझा डीएलआर सीआरटी का उपयोग करने के लिए मजबूर करता है, एक सीआरटी में आवंटित स्मृति को एक अलग सीआरटी में हटाया नहीं जा सकता है। यदि आप अपने सभी मॉड्यूल में साझा डीएलआर सीआरटी का उपयोग करते हैं (डीएलएल & एक्सई) तो आप ठीक हैं, अगर आप सीआरटी को पार नहीं करेंगे और दुनिया खराब हो जाएगी, तो वे सभी एक ही ढेर साझा करते हैं।

उस मुद्दे के अलावा, मैं स्वीकृत उत्तर से सहमत हूं। निर्माण कारखाने को क्लाइंट कोड के लिए स्वामित्व & जीवन चक्र प्रबंधन को परिभाषित नहीं करना चाहिए।

+0

आप कैसे सुनिश्चित कर सकते हैं कि exe और dll साझा dll CRT का उपयोग कर रहा है? इसके लिए कंपाइलर झंडे क्या हैं? –

0

नहीं, यह नहीं है।

boost::shared_ptr<T> का लेआउट डीएलएल सीमा के दोनों किनारों पर समान नहीं हो सकता है। (लेआउट संकलक संस्करण, पैकिंग प्रागमा, और अन्य कंपाइलर विकल्पों के साथ-साथ बूस्ट स्रोत कोड के वास्तविक संस्करण से प्रभावित है।)

केवल "मानक लेआउट" (सी ++ 11 में एक नई अवधारणा, से संबंधित पुराना "पीओडी = सादा पुराना डेटा" अवधारणा) प्रकार अलग-अलग निर्मित मॉड्यूल के बीच सुरक्षित रूप से पारित किया जा सकता है।

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