डायनेमिक लिंकिंग - लिनक्स बनाम। खिड़कियाँ


10

विंडोज के तहत, जब मैं MSVC में एक DLL प्रोजेक्ट में C / C ++ कोड संकलित करता हूं तो मुझे 2 फाइलें मिल रही हैं:

  1. MyDll.dll
  2. MyDll.lib

जहाँ तक मैं समझता हूँ कि MyDll.libकुछ प्रकार के पॉइंटर्स टेबल हैं जो dll में फ़ंक्शंस स्थानों को दर्शाते हैं। इस dll का उपयोग करते समय, एक exe फ़ाइल में कहें, MyDll.libलिंकेज के दौरान exe फ़ाइल में एम्बेडेड है ताकि रनटाइम में यह "पता" हो जाए कि फ़ंक्शन कहाँ स्थित हैं MyDll.dllऔर उनका उपयोग कर सकते हैं।

लेकिन अगर मैं लिनक्स के तहत समान कोड संकलित करता हूं तो मुझे केवल एक फाइल MySo.soबिना MySo.a( libलिनक्स में फाइल के समतुल्य ) मिल रही है, तो लिनक्स के तहत एक निष्पादन योग्य फ़ाइल कैसे जानती MySo.soहै कि लिंक के दौरान इसमें कुछ भी नहीं होने पर फ़ंक्शन कहाँ स्थित हैं ?

जवाबों:


1

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

MySo.a, अगर बनाया गया है, तो वास्तव में विंडोज पर उपयोग किए जाने वाले "प्रतीक लुकअप टेबल" के बजाय प्रतीकों को सीधे बाइनरी में जोड़ा जाएगा।

रस्टीक्स का जवाब विंडोज पर प्रक्रिया को मेरी तुलना में अधिक अच्छी तरह से समझाता है; विंडोज का उपयोग किए हुए मुझे एक लंबा समय हो गया है।


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

@ युगर ने उस हिस्से को हटा दिया, मैं वैसे भी तिनके को पकड़ रहा था।
एसएस ऐनी

4

MSVC लिंकर एक ऑब्जेक्ट फ़ाइल (.obj) और ऑब्जेक्ट लाइब्रेरी (.lib) को एक साथ जोड़ने के लिए लिंक कर सकता है।

एक DLL के साथ लिंक करने के लिए, MSVC में प्रक्रिया एक तथाकथित आयात पुस्तकालय (.LIB) का उपयोग करना है जो C फ़ंक्शन नामों और DLL के निर्यात तालिका (DLL में एक फ़ंक्शन नाम से निर्यात किया जा सकता है) के बीच गोंद के रूप में कार्य करता है क्रमिक द्वारा - बाद को अक्सर अनिर्दिष्ट एपीआई के लिए उपयोग किया जाता था)।

हालाँकि, ज्यादातर मामलों में DLL निर्यात तालिका में सभी फ़ंक्शन नाम होते हैं और इस प्रकार आयात पुस्तकालय (.LIB) में बड़े पैमाने पर निरर्थक जानकारी होती है (" आयात फ़ंक्शन ABC -> निर्यात फ़ंक्शन ABC ", आदि)।
यह एक मौजूदा .LIB से .LIB उत्पन्न करना भी संभव है ।

अन्य प्लेटफ़ॉर्म पर लिंकर्स में यह "फ़ीचर" नहीं है और यह डायनेमिक लाइब्रेरी से सीधे लिंक कर सकता है।


"अन्य प्लेटफ़ॉर्म पर लिंकर्स में यह सुविधा नहीं है" - विलंबित लोडिंग और अन्य अच्छाइयों को प्राप्त करने के लिए हालांकि (जैसे कि लिनक्स के लिए Implib.so ऐसा करता है) इसे लागू करना आसान है ।
युग

@ युगर: इसीलिए "फीचर" कोट्स में है - यह वह चीज नहीं है जो आप आमतौर पर करना चाहते हैं और यह अतिरिक्त काम है जो आपको विंडोज पर करना चाहिए।
क्रिस डोड

1

जो अंतर आप देख रहे हैं वह कार्यान्वयन विस्तार से अधिक है - हुड के तहत लिनक्स और विंडोज दोनों समान रूप से काम करते हैं - आप कोड एक स्टब फ़ंक्शन को कॉल करते हैं जो आपके निष्पादन योग्य में सांख्यिकीय रूप से जुड़ा हुआ है और यदि आवश्यक हो तो देरी के मामले में यह स्टबल DLL / shlib को लोड करता है लोड हो रहा है , अन्यथा कार्यक्रम शुरू होने पर पुस्तकालय लोड होता है) और (पहले कॉल पर) प्रतीक को GetProcAddress/ के माध्यम से हल करता है dlsym

एकमात्र अंतर यह है कि लिनक्स पर ये स्टब फ़ंक्शंस (जिन्हें पीएलटी स्टब्स कहा जाता है) गतिशील रूप से उत्पन्न होते हैं जब आप अपने ऐप को डायनेमिक लाइब्रेरी से जोड़ते हैं (लाइब्रेरी में उन्हें उत्पन्न करने के लिए पर्याप्त जानकारी होती है), जबकि लिनक्स पर वे डीएलएल के उत्पन्न होने पर स्वयं उत्पन्न होते हैं। एक अलग .libफ़ाइल में बनाया गया ।

दो दृष्टिकोण इतने समान हैं कि वास्तव में लिनक्स पर विंडोज आयात पुस्तकालयों की नकल करना संभव है ( Implib.so परियोजना देखें )।


0

लिनक्स पर, आप MySo.soलिंकर को पास करते हैं और यह लिंक चरण के लिए केवल उसी चीज को निकालने में सक्षम होता है, जिसे उस संदर्भ में रखा जाता है, जिसे MySo.soरन टाइम में जरूरत होती है।


-3

.dllया .so, साझा कर रहे हैं libs (क्रम में जुड़े हुए), जबकि .aऔर .libएक स्थिर पुस्तकालय (संकलन समय में जुड़े हुए) है। यह विंडोज और लिनक्स के बीच कोई अंतर नहीं है।

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

यदि हम एक dll का उपयोग करते हैं, या हम अपने स्वयं के बाइनरी से भी एक फ़ंक्शन कहते हैं, तो एक सरल और स्पष्ट तरीका है। उदाहरण के लिए, C में, हम देखते हैं कि:

int example(int x) {
  ...do_something...
}

int ret = example(42);

हालाँकि, asm स्तर पर, कई अंतर हो सकते हैं। उदाहरण के लिए, x86 पर, एक callopcode निष्पादित किया जाता है, और 42स्टैक पर दिया जाता है। या कुछ रजिस्टरों में। या कहीं भी। कोई नहीं जानता कि डीएल लिखने से पहले , इसका उपयोग कैसे किया जाएगा। या परियोजनाएं इसका उपयोग कैसे करना चाहती हैं, संभव है कि एक संकलक (या किसी भाषा में!) के साथ लिखा जाए जो अब भी मौजूद नहीं है (या यह dll के डेवलपर्स के लिए अज्ञात है)।

उदाहरण के लिए, डिफ़ॉल्ट रूप से, सी और पास्कल दोनों स्टैक से तर्क (और रिटर्न मान प्राप्त करते हैं) - लेकिन वे इसे अलग-अलग क्रम में कर रहे हैं । आप कुछ - कंपाइलर-निर्भर - अनुकूलन द्वारा रजिस्टरों में अपने कार्यों के बीच तर्कों का आदान-प्रदान भी कर सकते हैं।

जैसा कि आप ठीक से देखते हैं, विंडोज कस्टम यह है कि एक dll का निर्माण, हम एक न्यूनतम .a/ इसके .libसाथ भी बनाते हैं । यह न्यूनतम स्थिर पुस्तकालय केवल एक आवरण है, इसके माध्यम से उस dll के प्रतीकों (कार्यों) तक पहुंचा जाता है। यह आवश्यक एएसएम-स्तरीय कॉलिंग रूपांतरण बनाता है।

इसका लाभ संगतता है। इसका नुकसान यह है कि यदि आपके पास केवल एक .dll है, तो आपके पास यह पता लगाने के लिए एक कठिन समय हो सकता है कि इसके कार्यों को कैसे बुलाया जाना चाहिए। यह dlls का उपयोग हैकिंग कार्य करता है, यदि dll का डेवलपर आपको नहीं देता है.a । इस प्रकार, यह मुख्य रूप से बंद होने के उद्देश्यों को पूरा करता है, उदाहरण के लिए एसडीके के लिए अतिरिक्त नकदी प्राप्त करना आसान है।

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

लिनक्स में, dlls का बाइनरी इंटरफ़ेस मानक है और C कन्वेंशन का अनुसरण करता है। इस प्रकार, कोई .aआवश्यकता नहीं है और साझा किए गए कामों के बीच द्विआधारी संगतता है, बदले में हमारे पास Microsoft कस्टम के फायदे नहीं हैं।


1
कृपया एक सबूत प्रदान करें कि स्टब फ़ंक्शन तर्क क्रम को बदल सकता है। मैंने इसके बारे में पहले कभी नहीं सुना है और यह विश्वास करना मुश्किल है, यह देखते हुए कि ओवरहेड कितना बड़ा प्रदर्शन होगा।
युगर

@yugr एक साधारण रजिस्टर / स्टैक रीऑर्डरिंग एक प्रदर्शन ओवरहेड नहीं है। यदि आप msvc संकलित द्वैध से msvc संकलित dll का उपयोग करते हैं, तो स्पष्ट रूप से बहुत अधिक नहीं होगा, लेकिन यह हो सकता है।
पीटर - मोनिका

1
हम इस पर बहस कर सकते हैं लेकिन यदि आप सही हैं तो प्रूफलिंक प्रदान करना आसान होना चाहिए कि स्टब फ़ंक्शंस तर्कों के गैर-तुच्छ प्रसंस्करण में सक्षम हैं (और सिर्फ डमी ट्रैंपोलिन से अधिक हो)।
yugr

@ युगर स्टब्स में डीएल के फ़ंक्शन हस्ताक्षरों तक पहुंच है, जो गैर-तुच्छ प्रसंस्करण तुच्छ बनाता है।
पीटर - मोनिका

1
मैं केवल आपको सुझाव देता हूं कि आप अपना उत्तर कुछ प्रूफलिंक के साथ पूरा करें कि आयात पुस्तकालय क्या करते हैं (क्योंकि कुछ दावे संदिग्ध हैं)।
युग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.