2012-12-31 36 views
7

संपादित करें: मुझे गार्ड शामिल करने के बारे में पता है, लेकिन इसमें समस्याएं शामिल हैं। मैं वास्तविक संकलित और पहले से जुड़े कोड के बारे में बात कर रहा हूं जो स्थैतिक पुस्तकालय में बेक्ड हो जाता है।सी ++ पुस्तकालयों का उपयोग करते समय एक ही कोड सहित कैसे बचें?

मैं सी ++ में अपने लिए एक सामान्य उद्देश्य उपयोगिता पुस्तकालय बना रहा हूं।

मैं जो फ़ंक्शन बना रहा हूं, printFile, string, cout और मानक लाइब्रेरी के ऐसे अन्य सदस्यों की आवश्यकता है।

मैं चिंतित हूँ कि जब पुस्तकालय संकलित किया गया है, और फिर एक और परियोजना है कि यह भी string और cout, string और cout के लिए कोड का उपयोग करता दोहराया जाएगा से जुड़ा हुआ: यह दोनों पुस्तकालय द्विआधारी कार्यक्रम है में prelinked हो जाएगा इसके साथ जुड़ा हुआ है, और यह फिर से परियोजना से जुड़ा होगा जो स्वयं का उपयोग करता है।

पुस्तकालय इस तरह संरचित है:

  1. एक libname.hpp फ़ाइल प्रोग्रामर जो लाइब्रेरी का उपयोग करता अपनी परियोजनाओं में #include माना जाता है नहीं है।
  2. प्रत्येक कार्य के लिए fnamelibname.hpp में घोषित किया गया है, इसमें एक फ़ाइल fname.cpp लागू है।
  3. सभी fname.cpp फ़ाइलें भी #include "libname.hpp"
  4. लाइब्रेरी स्वयं libname.a में संकलित है जिसे /usr/lib/ पर कॉपी किया गया है।

क्या यह भी होगा?
यदि हां, तो क्या यह एक समस्या है?
यदि हां, तो मैं इससे कैसे बच सकता हूं?

उत्तर

3

मैं चिंतित हूँ कि जब पुस्तकालय संकलित किया गया है, और फिर एक और परियोजना है कि यह भी स्ट्रिंग और अदालत, स्ट्रिंग और अदालत के लिए कोड

दोहराया जाएगा का उपयोग करता है से जुड़ा हुआ

चिंता मत करो: कोई आधुनिक संकलन प्रणाली ऐसा नहीं करेगी। टेम्पलेट फ़ंक्शंस के लिए कोड ऑब्जेक्ट फ़ाइलों में उत्सर्जित होता है, लेकिन लिंकर डुप्लिकेट प्रविष्टियों को छोड़ देता है।

0

हां, मानक लाइब्रेरी चीज़ों के लिए कोड डुप्लिकेट किया जाएगा। यह एक समस्या हो सकती है यदि उदाहरण के लिए आप एक std :: स्ट्रिंग वापस कर देते हैं या अपनी विधियों में से एक में पैरामीटर के रूप में लेते हैं। उपयोगकर्ता के मुकाबले आपके मानक लाइब्रेरी कार्यान्वयन में इसका एक अलग लेआउट हो सकता है।

+1

ठीक है, मैं समझता हूं। हालांकि, "इस से कैसे बचें" मेरे प्रश्न का एक बड़ा हिस्सा है। – corazza

+0

अब मुझे एहसास हुआ कि मैं दो अलग-अलग मुद्दों को मिला रहा था: कोड डुप्लिकेशन और मानक लाइब्रेरी क्लास लेआउट। दूसरा एक मुद्दा नहीं है यदि आप अपने प्रोग्राम को उसी कंपाइलर के साथ संकलित कर रहे हैं जिसका उपयोग आप लाइब्रेरी को संकलित करने के लिए करते थे, जो आपका मामला प्रतीत होता है। पहले के रूप में, इसका परिणाम बड़ा कोड हो सकता है लेकिन वास्तव में अन्यथा कोई समस्या नहीं है। – user1610015

3

मानक सी ++ लाइब्रेरी की लाइब्रेरी परिभाषाएं आपकी स्थिर रूप से लाइब्रेरी में दिखाई नहीं देगी जबतक कि आप उन्हें स्पष्ट रूप से वहां शामिल नहीं करते हैं (यानी, आप मानक सी ++ लाइब्रेरी से ऑब्जेक्ट फ़ाइलों को निकालते हैं और उन्हें अपनी लाइब्रेरी में शामिल करते हैं)। स्टेटिक लाइब्रेरी बिल्कुल जुड़े नहीं हैं और अन्य पुस्तकालयों के संदर्भ में अनिर्धारित संदर्भ होंगे। एक स्थिर पुस्तकालय पुस्तकालय द्वारा प्रदान किए गए प्रतीकों को परिभाषित करने वाली ऑब्जेक्ट फ़ाइलों का संग्रह है। शीर्षकों से आने वाली परिभाषाएं, उदाहरण के लिए, इनलाइन फ़ंक्शंस और टेम्पलेट इंस्टॉलेशन, इस तरह परिभाषित की जाएंगी कि एकाधिक अनुवाद इकाइयों में एकाधिक परिभाषाएं संघर्ष नहीं करेंगी। जहां कोड वास्तव में रेखांकित नहीं किया गया है, यह "कमजोर" प्रतीकों को परिभाषित करेगा जिसके परिणामस्वरूप डुप्लिकेट को अनदेखा किया जा सकता है या लिंक समय पर हटा दिया जा सकता है।

एकमात्र वास्तविक चिंता यह है कि निष्पादन योग्य में लिखे गए पुस्तकालयों को संगत लाइब्रेरी परिभाषाओं का उपयोग करने की आवश्यकता होती है। हेडर फ़ाइलों में रहने वाले कोड की पर्याप्त मात्रा के साथ, मानक सी ++ लाइब्रेरी हेडर (सी लाइब्रेरी हेडर के सापेक्ष जिसमें बहुत कम कोड होता है) सहित सी ++ हेडर फ़ाइलों में अपेक्षाकृत लगातार परिवर्तन होते हैं।

0

यह शायद ही कभी अभ्यास में एक समस्या है।

static हेडर फ़ाइलों में परिभाषित कार्यों और इनलाइन टेम्पलेट किए गए कार्यों के लिए, इस बारे में चिंता करने की कोई बात नहीं है: प्रत्येक संकलन इकाई की अपनी प्रति प्राप्त होती है (उदाहरण के लिए .a लाइब्रेरी में पहले से ही कई अज्ञात प्रतियां हो सकती हैं)। यह ठीक है क्योंकि इन परिभाषाओं को निर्यात नहीं किया जाता है, इसलिए लिंकर को उनके बारे में चिंता करने की आवश्यकता नहीं है।

गैर-स्थैतिक संबंधों के साथ घोषित कार्यों के लिए, चाहे आपको कोई समस्या हो, इस पर निर्भर करता है कि आप .a लाइब्रेरी को कैसे लिंक करते हैं।

जब आप लाइब्रेरी बनाते हैं, तो आप मानक C++ लाइब्रेरी में लिंक नहीं करेंगे। बनाई गई लाइब्रेरी में मानक C++ लाइब्रेरी के अपरिभाषित संदर्भ होंगे। अंतिम निष्पादन योग्य बाइनरी बनाने से पहले इन्हें हल किया जाना चाहिए। डिफ़ॉल्ट रूप से उस अंतिम बाइनरी को जोड़ने के दौरान आमतौर पर यह स्वचालित रूप से किया जाता है (कंपाइलर के आधार पर)।

ऐसे समय होते हैं जब लोग मानक सी ++ लाइब्रेरी में एक स्थिर लाइब्रेरी में लिंक करते हैं। यदि आप कई स्थैतिक पुस्तकालयों के खिलाफ लिंक कर रहे हैं जो प्रत्येक एक और लाइब्रेरी (मानक सी ++ लाइब्रेरी की तरह) एम्बेड करते हैं, तो उन एम्बेडेड लाइब्रेरीज़ में कोई अंतर होने पर परेशानी की उम्मीद करें। सौभाग्य से, यह कम से कम gcc टूलचेन के साथ एक दुर्लभ समस्या है। यह माइक्रोसॉफ्ट के उपकरणों के साथ more frequent problem है।

कुछ मामलों में, एक या अधिक विरोधाभासी स्थिर पुस्तकालयों को एक गतिशील पुस्तकालय में बनाना एक कामकाज है। इस तरह से प्रत्येक गतिशील पुस्तकालय स्थिर रूप से समस्याग्रस्त पुस्तकालय की अपनी प्रतिलिपि बना सकते हैं। जब तक गतिशील लाइब्रेरी समस्याग्रस्त लाइब्रेरी से प्रतीकों को निर्यात नहीं करती है और वहां कोई मेमोरी लेआउट असंगतता नहीं होती है, आमतौर पर कोई परेशानी नहीं होती है।