2013-05-24 4 views
11

मेरे पास विंडोज साझा पुस्तकालयों (डीएलएल) बनाम लिनक्स साझा पुस्तकालयों (एसओएस) के बारे में एक त्वरित सवाल है।साझा पुस्तकालय: विंडोज बनाम लिनक्स विधि

ऐसा क्यों है कि जब आप Windows DLL बनाते हैं तो क्लाइंट प्रोग्राम को स्थिर लाइब्रेरी (.lib फ़ाइल) के विरुद्ध लिंक करने की आवश्यकता होती है, लेकिन लिनक्स में बनाए गए अनुप्रयोगों को ऐसी स्थिर लाइब्रेरी के विरुद्ध किसी भी लिंकिंग की आवश्यकता नहीं होती है।

क्या कोड कोड स्थानांतरण के साथ इसका कोई संबंध नहीं है? धन्यवाद।

+0

इसे * आयात लाइब्रेरी * कहा जाता है, और उपकरण डीएलएल से निकालने के लिए मौजूद हैं। –

उत्तर

16

वास्तव में कोड स्थानांतरण के साथ नहीं, यह एक बिल्कुल अलग मुद्दा है। यह आर्किटेक्चर में एक अंतर के बारे में है:

  • विंडोज़ में, एक डीएलएल निष्पादन योग्य (EXE) की तरह है। एक ईईई और डीएलएल के बीच मुख्य अंतर यह है कि EXE में एक प्रविष्टि बिंदु (मुख्य/विनमेन फ़ंक्शन) होता है और इसलिए इसका उपयोग प्रक्रिया शुरू करने के लिए किया जा सकता है, जबकि डीएलएल को केवल पूर्व-मौजूदा प्रक्रिया में लोड किया जा सकता है। लेकिन देखें (1)

  • लिनक्स में, एक स्थिर पुस्तकालय (.a) के समान काम करता है। मुख्य अंतर यह है कि .so फ़ाइल को चल रहे प्रोग्राम से जोड़ा जा सकता है, जबकि .a फ़ाइल को प्रोग्राम को संकलित करते समय ही जोड़ा जा सकता है।

इस दृष्टिकोण का एक परिणाम यह है कि लिनक्स में एक ही फ़ाइल का उपयोग प्रोग्राम बनाने और चलाने के लिए किया जा सकता है। लेकिन विंडोज़ में आपको प्रोग्राम को जोड़ने के लिए एक उचित लाइब्रेरी (एलआईबी) की आवश्यकता है। असल में एक डीएलएल से संबंधित lib जो आमतौर पर कार्यों के नाम से अधिक नहीं है, लिंकर को संतुष्ट करने के लिए, और स्थानांतरित करने के लिए स्टब्स। लेकिन देखें (2)

(1) ठीक है, डीएलएल के पास प्रवेश बिंदु भी है, लेकिन इसका उपयोग मुख्य कार्य के रूप में नहीं किया जाता है, जैसे कुछ प्रकार के प्रारंभिक/अंतिमकरण हुक।

(2) कुछ लिंकर्स कुछ सामान्य मामलों में, डीएलएल को अतिरिक्त एलआईबी फ़ाइल की आवश्यकता के बिना डीएलएल से लिंक करने के लिए सक्षम होने के लिए पर्याप्त स्मार्ट हैं। मुझे लगता है कि कम से कम MinGW लिंकर ऐसा कर सकता है।

+0

उस पूरी व्याख्या के लिए धन्यवाद। – QAH

+4

ए 'एसओ * एक स्थिर पुस्तकालय (' .a') से * पूरी तरह से * अलग है। – duskwuff

+0

@ डस्कवफ: यह प्रारूप में अलग है, लेकिन व्यवहार में इतना ज्यादा नहीं है। ए। एस को सिर्फ एए की तरह कार्य करने के लिए डिज़ाइन किया गया है, सिवाय इसके कि यह रनटाइम पर लिंक करता है। यहां तक ​​कि प्रतीक संकल्प और दृश्यता नियम लगभग समान हैं, ताकि एक कार्यक्रम को स्थिर दर्द से न्यूनतम दर्द के साथ गतिशील लिंकिंग से पोर्ट किया जा सके। – rodrigo

3

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

उदाहरण के लिए, यदि आप एक समारोह का नाम "foo" "bar.dll" नामक एक DLL में कॉल करने के लिए चाहता था, आप कोड इस प्रकार लिख सकते:

HINSTANCE hinst = LoadLibrary("bar.dll"); 
FARPROC foo = GetProcAddress(hinst, "foo"); 
foo(); 

और "foo" और "बार। डीएलएल "आसानी से मूल्य हो सकता है जो केवल रन टाइम पर स्थापित किए गए थे, कॉन्फ़िगरेशन फ़ाइल या किसी अन्य उपयोगकर्ता इनपुट के माध्यम से कहते हैं।

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

अधिकांश भाग के लिए, एक कंपाइलर स्वचालित रूप से इन पुस्तकालयों को उत्पन्न कर सकता है, इसलिए तकनीकी रूप से उन्हें केवल डीएलएल कार्यों से लिंक करने की आवश्यकता नहीं होती है। हालांकि, साझा चरों को जोड़ने पर यह एक अपवाद (जिसे मैं जानता हूं) है।

विंडोज डीएलएल में आप चर के साथ एक साझा डेटा सेगमेंट बना सकते हैं जिसे डीएलएल लोड करने वाली किसी भी प्रक्रिया द्वारा एक्सेस किया जा सकता है। उन चर के आकार और प्रकारों के बारे में जानकारी संबंधित स्थिर पुस्तकालय में संग्रहीत है, और अकेले डीएलएल से निर्धारित नहीं किया जा सकता है। उन चरों तक पहुंचने के लिए, क्लाइंट प्रोग्राम को उस DLL के लिए स्थिर लाइब्रेरी के विरुद्ध लिंक करना होगा।

जहां तक ​​मुझे पता है, लिनक्स साझा पुस्तकालय ऐसी अवधारणा का समर्थन नहीं करते हैं।

अद्यतन

मैं भी है कि विंडोज पर यह नहीं बल्कि नाम से जहां समारोह प्रवेश बिंदुओं केवल क्रमसूचक (संख्या) द्वारा निर्यात किया जाता है एक DLL बनाने के लिए संभव है उल्लेख करना चाहिए। इसे डेटा छिपाने के रूप में माना जा सकता है और आमतौर पर तब उपयोग किया जाएगा जब एक कार्यान्वयनकर्ता कुछ कार्यों को निजी बने रहना चाहता है।

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

+0

क्या आप साझा स्मृति के इस रूप के बारे में कुछ संदर्भ साझा करना चाहते हैं? –

+0

लोड लाइब्रेरी + GetProcAddress लिनक्स में dlopen + dlsym होगा, अक्सर "प्लगइन्स" लोड करने के लिए उपयोग किया जाता है। – grawity

+1

* "जहां तक ​​मुझे पता है, लिनक्स साझा पुस्तकालय ऐसी अवधारणा का समर्थन नहीं करते हैं" * - लिनक्स भी उन्हें है। ईएलएफ में 'जीएनयू_SHR' अनुभाग भी देखें। – jww

24

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

यह माइक्रोसॉफ्ट द्वारा एक ऐतिहासिक डिजाइन निर्णय है ताकि लिंकर डीएलएल संदर्भों को लिंक समय पर मौजूद डीएलएल के एक विशेष संस्करण के बिना निष्पादन योग्य में जोड़ सके। इसका कारण यह था कि डीएलएल के विभिन्न संस्करणों के साथ विंडोज के आसपास के विभिन्न संस्करण हमेशा रहे हैं। इसके अलावा माइक्रोसॉफ्ट ओएसबी के साथ ओएस/2 पर सहयोग कर रहा था और योजना यह थी कि विंडोज प्रोग्राम ओएस/2 पर भी निष्पादित किया जा सकता था। खैर, माइक्रोसॉफ्ट ने एनटी कर्नेल के आधार पर अपने पेशेवर ग्रेड ओएस को रोल करके ओएस/2 को "बैकस्टैब" करने का निर्णय लिया। लेकिन इसका मतलब यह था कि विकास के लिए आप डेवलपर्स को डीएलएल के सभी अलग-अलग प्रकारों के बिना सिस्टम डीएलएल के खिलाफ लिंक करने में सक्षम होना चाहते थे। इसके बजाय एक गतिशील लिंक "टेम्पलेट" का उपयोग डीएलएल और निष्पादन योग्य दोनों (पीई प्रारूप में दोनों) बनाने के लिए किया गया था, जो ये विशेष .lib फाइलें हैं, जो पुस्तकालयों में बिल्कुल नहीं हैं, बल्कि केवल प्रतीक और औपचारिक तालिकाओं (यह एक छोटा ज्ञात तथ्य है, लेकिन पीई बाइनरी प्रतीकों को न केवल एक स्ट्रिंग पहचानकर्ता द्वारा लोड किया जा सकता है, बल्कि एक पूर्णांक संख्या, तथाकथित ordinal द्वारा भी लोड किया जा सकता है)।

नियमों का एक दुष्प्रभाव यह है कि वे मानव पठनीय प्रतीकों को छिपाने की अनुमति देते हैं, ताकि आप डीएलएल का उपयोग केवल तभी कर सकें जब आप सामान्य → → फ़ंक्शन रिलेशनशिप को जानते हों।

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

यदि आप यूनिक्स साझा वस्तुओं के साथ प्रतीकों को छिपाना चाहते हैं, तो आप आमतौर पर एक ही struct का उपयोग करके सभी फ़ंक्शन पॉइंटर्स के साथ ऐसा करते हैं, और केवल नाम से इस संरचना का वैश्विक निरंतर उदाहरण निर्यात करते हैं, जिसमें एक बहुत स्पष्ट रूप से नामित पॉइंटर्स नहीं। हालांकि, आप विंडोज डीएलएल के साथ बिल्कुल वही कर सकते हैं।

टीएल; डीआर: इसका कारण तकनीकी नहीं है, बल्कि विपणन और वितरण निर्णय एक है।

+0

महान जवाब! यह स्वीकार्य उत्तर होना चाहिए। – damphat

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