2010-07-06 16 views
5

मेरे पास एक एमएस सी ++ प्रोजेक्ट है (चलो इसे प्रोजेक्ट ए कहते हैं) कि मैं वर्तमान में एक स्थिर पुस्तकालय (.lib) के रूप में संकलित हूं। यह एक वैश्विक परिवर्तनीय foo परिभाषित करता है। मेरे पास दो अन्य परियोजनाएं हैं जो अलग-अलग संकलित करती हैं (क्रमशः उन्हें बी और सी कहते हैं) और प्रत्येक साझा साझा लाइब्रेरी ए को जोड़ती है। बी और सी दोनों ही डीएल हैं जो एक ही प्रक्रिया में लोड होते हैं। मैं एक ही प्रक्रिया में बी और सी के बीच ए से foo का एक उदाहरण साझा करना चाहता हूं: एक सिंगलटन। मुझे यकीन नहीं है कि परियोजना ए के साथ सिंगलटन पैटर्न को कैसे पूरा किया जाए क्योंकि यह स्थिर रूप से बी और सी में संकलित है। यदि मैं बी और सी दोनों में बाहरी रूप में foo घोषित करता हूं, तो मैं बी और सी में अलग-अलग उदाहरणों के साथ समाप्त होता हूं। मानक, सरल सिंगलटन क्लास पैटर्न का उपयोग एक स्थिर getInstance विधि के साथ दो स्थैतिक फू इंस्टॉलेशन में होता है।सी ++ स्थिर पुस्तकालय में साझा वैश्विक चर

क्या इसे पूरा करने का कोई तरीका है जबकि परियोजना ए को बी और सी में स्थिर रूप से संकलित किया गया है? या मुझे ए डीएलएल बनाना है?

+0

* "अगर मैं बी और सी दोनों में बाहरी के रूप में foo घोषित करता हूं, तो मैं बी और सी में विभिन्न उदाहरणों के साथ समाप्त होता हूं।" * - क्या यह वाकई सच है? –

+0

यह सच प्रतीत होता है - यह व्यवहार है जब मैं डीबगिंग करते समय प्रोग्राम के माध्यम से कदम उठाता हूं। मैं दो बार बुलाए जाने वाले फू के लिए कन्स्ट्रक्टर देखता हूं और बाहरी चर के पते g_Foo दो मॉड्यूल बी और सी में अलग होते हैं। क्या यह मामला नहीं होना चाहिए? – Zach

+0

संभावित डुप्लिकेट [सी ++ में प्रक्रिया-वैश्विक चर को कैसे कार्यान्वित करें?] (Http://stackoverflow.com/questions/669989/how-to-implement-process-global-variable-in-c) – Zach

उत्तर

4

हां, आपको एक साझा डीएलएल बनाना है, या फिर इसे बी और सी में बाहरी के रूप में परिभाषित करना है और सभी तीनों को स्थिर रूप से लिंक करना है।

+0

क्या आप "तीनों स्थिर रूप से लिंक" से क्या मतलब रखते हैं, इसका विस्तार कर सकते हैं? मैं वर्तमान में बी और सी दोनों में स्थिर रूप से लिंक कर रहा हूं और बी और सी में फू बाहरी घोषित कर रहा हूं, फिर भी मैं रनटाइम पर foo की कई परिभाषाओं के साथ समाप्त होता हूं। मुझे लगता है कि आप कह रहे हैं कि मुझे ए और बी को स्थिर रूप से सी (या ए और सी को सांख्यिकीय रूप से बी) में जोड़ने की आवश्यकता होगी, या ए, बी, और सी को अन्य लाइब्रेरी में स्थिर रूप से लिंक करना होगा। क्या यह सही है? धन्यवाद! – Zach

+0

"आखिरी निष्पादन योग्य" के साथ विकल्प "अन्य लाइब्रेरी" को छोड़कर आखिरी वाला। किसी भी पुस्तकालय को एक साथ लिंक न करें। इसके बजाय, अपने अंतिम निष्पादन योग्य के साथ स्थिर रूप से ए, बी, और सी लिंक करें। बी या सी में उपयोग किए जाने वाले ए से किसी भी प्रतीक को बी और सी में बाहरी के रूप में घोषित किया जाना चाहिए, लेकिन परिभाषित नहीं किया जाना चाहिए। यदि आप ए, बी, और सी को किसी अन्य साझा लाइब्रेरी में लिंक करते हैं, तो आपको बस यह सुनिश्चित करना होगा कि यह लाइब्रेरी ए से सिंगलटन को एन्सेप्लेट करता है, क्योंकि यदि ए को निष्पादन योग्य रूप से स्थिर रूप से जोड़ा गया है और निष्पादन योग्य ए के स्थिर डेटा को सीधे एक्सेस करता है, तो यह lib की तुलना में एक अलग प्रति प्राप्त होगा। –

2

नहीं - वे साझा नहीं किए जाते हैं।

रिक्टर से 'विंडोज सी/सी के माध्यम से ++' (p583):

एक प्रक्रिया अपने पता स्थान अंतरिक्ष में एक DLL छवि फ़ाइल नक्शे है, प्रणाली वैश्विक और स्थिर डेटा के उदाहरण बनाता है परिवर्तनीय भी।

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

+0

आपका अवलोकन सामान्य रूप से सही है, लेकिन आपने ओपी द्वारा एक महत्वपूर्ण दावा का निरीक्षण किया: "* बी और सी दोनों डीएल हैं जो एक ही प्रक्रिया में ** लोड हो गए हैं **। *" तो डीएलएल के साथ इसे साझा किया जाएगा। यहां मुद्दा स्थिर लिंकिंग है। – Christophe

+0

वैसे, यहां समझाया गया है कि प्रक्रियाओं में साझा करना आसानी से हासिल किया जा सकता है: http://stackoverflow.com/a/7705793/3723423 – Christophe

0

मैं वास्तव में इस समस्या को मिलता है (उचित Mutex बहिष्कार के साथ, निश्चित रूप से।):

मैं एक है .EXE बीएलआईबी से जुड़ा हुआ है। मेरे पास सीडीएलएल भी बीएलआईबी से जुड़ा हुआ है।

आप देख सकते हैं, इन दोनों कार्यक्रम B.LIB

अब साथ जुड़े हुए हैं, जरूरत पड़ने पर, A.exe लोड C.DLL जाना। लोड होने के बाद, एएक्सईई और सीडीएलएल प्रत्येक ने कोड और डेटा के लिए बीएलआईबी को अलग किया है

समस्या बीडीआईबी "फंताम" से पहले ही लोड हो सकती है ताकि पहले से लोड किए गए उपयोग का उपयोग किया जा सके। A.exe?

मुझे नहीं लगता। यह खिड़की से एक सीमा है। लिनक्स में आप कर सकते हैं, अगर मुझे सही याद है। यह जीसीसी के एफपीआईसी विकल्प द्वारा माना जाता था। लेकिन पक्का नहीं।

एएक्सईई और सीडीएलएल के साथ बीएलआईबी में संग्रहीत वैश्विक/स्थिर डेटा साझा करने का समाधान साझा वर्ग/इंटरफेस का उपयोग करना है। आपका एएक्सईई एडीईईई में संग्रहीत बीआईएलबी को डेटा/इंटरफेस पॉइंटर के साथ सीडीएलएल को इंटरफेस भेजता है।

दूसरे शब्दों में, यदि आपके सीडीएलएल को बीएलआईबी में स्थिर चर के सेट/साझा स्थिति की आवश्यकता है, तो आपके एएक्सई को बीएलआईबी के साथ डेटा एक्सचेंज की अनुमति देने के लिए इंटरफेस के साथ प्रारंभिक सीडीएलएल होना चाहिए। A.EXE।

सभी मामले में, B.LIB C.DLL में संग्रहीत वैश्विक कार्यक्रम ब्लोट A.EXE और C.DLL

में B.LIB से डुप्लिकेट कोड की वजह से वैश्विक सूजन को कम करने के लिए जारी रखने आपको अपने एएलआईबी को अधिक डीडीएलएल, ई में विभाजित करना होगा।डीएलएल जो एएक्सईई द्वारा लोड किया गया है और आपके सीडीएलएल

ब्लोएटेड कोड को शून्य तक कम करने के लिए, आपको पूर्ण स्वतंत्र इंटरफ़ेस विधि का उपयोग करना होगा।

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