2012-07-26 17 views
5

मेरे पास एक बहुप्रचारित एप्लिकेशन है। मैं एक साझा पुस्तकालय में एक स्थिर सदस्य के साथ एक कक्षा घोषित करता हूं।एक स्थिर सदस्य के दो उदाहरण, यह कैसे हो सकता है?

विभिन्न पुस्तकालयों से अलग-अलग धागे से सदस्य का पता प्रिंट करना अलग-अलग परिणाम दिखाता है।

// घोषणा

template <class OBJECT> 
struct Container 
{ 
    static int m_member; 
}; 

template <class OBJECT> 
int Container<OBJECT>::m_member; 

// मुद्रण

cout << (void*) &Container<int>::m_member << endl; 

कि कैसे हो सकता है?

+0

जब आप विभिन्न पुस्तकालयों से अलग-अलग धागे कहते हैं तो आपका मतलब है कि आपके पास एक प्रक्रिया है जिसमें सदस्य तक पहुंचने वाले कई धागे हैं? जब मुझे सही याद है, मैंने सुना है कि साझा पुस्तकालय प्रति प्रक्रिया तत्काल हैं, इसलिए प्रत्येक प्रक्रिया का अपना संस्करण होता है (अन्य प्रक्रियाओं में हस्तक्षेप नहीं करने के लिए)। – Nobody

+1

आप "साझा लाइब्रेरी" को कैसे लिंक करते हैं? –

+0

यह कई धागे के साथ एक प्रक्रिया है। सदस्य हेडर फ़ाइल में परिभाषित किया गया है (मेरे असली कोड कंटेनर में टेम्पलेट किया गया है) लेकिन मुझे पूरा यकीन है कि यह समस्या नहीं है। – Ezra

उत्तर

4

यदि आपके पास अलग-अलग पुस्तकालय हैं, (मैं विभिन्न गतिशील पुस्तकालयों का अनुमान लगा रहा हूं), तो आपके पास कोड और स्थिर चर दोनों का कुछ डुप्लिकेशंस हो सकता है।

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

वैसे भी, आपको ऑपरेटिंग सिस्टम और आपके प्रोजेक्ट के लेआउट पर अधिक जानकारी देना चाहिए।

अद्यतन: आह, लेकिन आपकी कक्षा एक टेम्पलेट है! एक साझा पुस्तकालय में टेम्पलेट तत्काल एक अजीब जानवर हैं! यह सुनिश्चित करने के लिए कि आपकी कक्षा की केवल एक प्रति का उपयोग सभी प्रक्रियाओं में किया जाता है, आपको स्पष्ट रूप से टेम्पलेट को तुरंत चालू करना होगा और यह सुनिश्चित करना होगा कि यह तत्कालता SO में निर्यात की जाती है, और यह क्लाइंट कोड से उपयोग की जाती है। विवरण संकलक के साथ अलग अलग है, लेकिन आप देख सकते हैं कि std::string किया जाता है, उदाहरण के लिए:

हेडर फाइल में:

namespace std 
{ 
    extern template class basic_string<wchar_t>; 
} 

पुस्तकालय के स्रोत में:

namespace std 
{ 
    template class basic_string<wchar_t>; 
} 

स्वाभाविक रूप से आपको पहले से ही पता होना चाहिए कि आपके टेम्पलेट की तत्काल आवश्यकताएं क्या होंगी। जाहिर है, एसओ एक ऐसे क्षण का निर्यात नहीं कर सकता जो एक प्रकार का उपयोग करता है, जिसके बारे में कुछ भी नहीं जानता है।

अद्यतन: आह, लेकिन आप दो अलग अलग टेम्पलेट instantating पुस्तकालय हैं ... तो अगर दोनों पुस्तकालयों extern के रूप में स्पष्ट इन्स्टेन्शियशन परिभाषित साझा ELF जादू दोनों instantiations एक में विलय कर देना चाहिए।

किसी अन्य अद्यतन: टेम्पलेट्स और साझा वस्तुओं के साथ खेलने के बाद, यह आमतौर पर काम करता है। मेरा अनुमान है कि आप -fvisibility=hidden या इसी तरह के पुस्तकालयों को संकलित कर रहे हैं। अगर ऐसा है, यह सिर्फ लिखने के लिए पर्याप्त होगा:

template <class OBJECT> 
struct __attribute__((visibility("default"))) Container 
{ 
    static int m_member; 
}; 

गतिशील प्रतीक तालिका में प्रवेश के लिए टेम्पलेट के विशेषज्ञताओं बनाने के लिए, और इस तरह दोहराव से बचने के।

+0

मैं लिनक्स सेंटोस का उपयोग करता हूं, इसलिए SO। जहां तक ​​मुझे पता है, कंटेनर :: m_member का केवल एक उदाहरण होना चाहिए। – Ezra

+0

+1। हालांकि, मैंने आपके सुझावों का प्रयास किया है और अभी भी दो उदाहरण प्राप्त कर रहे हैं। अगर वह संकेत दे सकता है: जो पते मैं देख रहा हूं वे अलग-अलग लंबाई हैं: 0x61bdb0, 0x2aaaab92d5b0। मेरी मशीन 64 बिट है। – Ezra

+0

@Ezra: मैंने एक उदाहरण किया है और दृश्यता विकल्पों के साथ बस दोनों परिणाम (एक ही पता या अलग पते) प्राप्त करने में सक्षम था। आपको वास्तव में कुछ संकलित कोड और संकलक आदेश पोस्ट करना चाहिए जो आपकी समस्या को पुन: उत्पन्न करते हैं। – rodrigo