आपके द्वारा जुड़ा प्रश्न "लिंक बाइनरी विद लाइब्रेरीज़" कार्यक्षमता को संदर्भित करता है, जो कि एक एम्बेडेड बाइनरी से कुछ अलग है।
"लिंक बाइनरी विद लाइब्रेरीज़" का अर्थ है कि आप लिंकेज के संबंध में उससे क्या अपेक्षा करते हैं: भले ही बाइनरी एक स्थिर लाइब्रेरी, डायनेमिक लाइब्रेरी या फ्रेमवर्क है, लेकिन संकलन के बाद लिंक समय पर इसे आपके ऑब्जेक्ट कोड से जोड़ा जाएगा।
जब आप स्थैतिक पुस्तकालय के साथ जुड़ाव के बारे में सोचते हैं, तो जो होता है वह बहुत स्पष्ट होता है: लिंकर पुस्तकालय से कोड को कॉपी करता है (जैसेlibFoo.a
) को अपने आउटपुट बाइनरी में । आपकी आउटपुट फ़ाइल आकार में बढ़ती है, लेकिन रनटाइम पर किसी भी बाहरी निर्भरता को हल करने की आवश्यकता नहीं है। आपके द्वारा चलाए जाने के बाद आपके प्रोग्राम को चलाने के लिए (स्थैतिक पुस्तकालय के संबंध में) सब कुछ मौजूद है।
डायनेमिक लाइब्रेरी (.dylib, या सिस्टम-सप्लाई फ़्रेमवर्क) के साथ, उम्मीद यह है कि आप जिस लाइब्रेरी के खिलाफ लिंक कर रहे हैं, वह सिस्टम के डायनामिक-लाइब्रेरी लोडर पथ में कहीं मौजूद होगी जब आप अपना प्रोग्राम चलाते हैं। इस तरह से आपके पास सभी तृतीय पक्ष बाहरी पुस्तकालयों को अपने बाइनरी में कॉपी करने का ओवरहेड नहीं है, और कंप्यूटर पर सभी अलग-अलग प्रोग्राम जो उस लाइब्रेरी से लिंक करते हैं, वे इसे ढूंढने में सक्षम होंगे, जो न्यूनतम डिस्क स्थान बचाता है, लेकिन यह भी संभावित मेमोरी स्पेस, इस बात पर निर्भर करता है कि सिस्टम कैसे और कहां लाइब्रेरीज़ को कैश करता है।
एक ढांचा एक गतिशील पुस्तकालय की तरह होता है, लेकिन इसकी निर्देशिका संरचना (चित्र, ऑडियो, अन्य ढांचे, आदि) में संसाधन शामिल हो सकते हैं। इस स्थिति में एक साधारण स्टैटिक-लाइब्रेरी या .dylib फाइल नहीं कटेगी, इसलिए आपको किसी फ्रेमवर्क से लिंक करना पड़ सकता है, ताकि यह पता चल सके कि इसे ठीक से चलाने की आवश्यकता क्या है।
जब आप किसी थर्ड-पार्टी फ्रेमवर्क से लिंक करते हैं (ऐसा कुछ कहिए जिसे आपने गितूब से डाउनलोड किया है और खुद बनाया है), यह उस सिस्टम पर मौजूद नहीं हो सकता जिसे आप चलाने का इरादा रखते हैं। इस स्थिति में, आप केवल फ़्रेमवर्क से लिंक नहीं करेंगे, बल्कि "कॉपी फ्रेमवर्क" चरण का उपयोग करके इसे अपने एप्लिकेशन बंडल के अंदर एम्बेड करें। जब आपका प्रोग्राम चलता है, तो रनटाइम-लिंकर (उर्फ रिज़ॉल्वर) सिस्टम लोडर पथ के अलावा आपके बंडल के अंदर दिखेगा, एम्बेडेड फ्रेमवर्क ढूंढें, और इसे लिंक करें ताकि आपके ऐप में वह कोड हो जिसे चलाने के लिए इसकी आवश्यकता हो।
अंत में, क्या ठीक से "एम्बेडेड बाइनरी" एक निष्पादन योग्य है जिसे आप अपने एप्लिकेशन बंडल में एक कॉपी-फाइल चरण के माध्यम से एम्बेड करते हैं, और यह कि आप अपने आप को निष्पादित करते हैं, शायद एक कॉल के साथ popen()
या इसी तरह। एम्बेडेड बाइनरी को आपके प्रोग्राम द्वारा बुलाया जा सकता है, लेकिन यह इसके साथ जुड़ा नहीं है। यह पूरी तरह से बाहरी इकाई है (जैसे /bin
निर्देशिका में कार्यक्रम )।
व्यवहार में, सिस्टम द्वारा आपूर्ति की गई लाइब्रेरी और फ्रेमवर्क के लिए आप उनके खिलाफ लिंक करेंगे और आपको बस इतना करना होगा।
यदि आपको अपने द्वारा बनाए गए पुस्तकालय को लिंक करने की आवश्यकता है जो कि किसी भी एम्बेडेड संसाधनों की आवश्यकता नहीं है (यानी मौजूद होने के लिए एक रूपरेखा की आवश्यकता नहीं है), तो आप बस एक स्थैतिक पुस्तकालय के खिलाफ लिंक कर सकते हैं। यदि आप पाते हैं कि आपके प्रोग्राम में कई मॉड्यूल हैं जो एक ही लाइब्रेरी कोड का उपयोग करना चाहते हैं, तो इसे एक फ्रेमवर्क या डायनेमिक लाइब्रेरी में परिवर्तित करना और इसके खिलाफ लिंक करना अंतरिक्ष को बचा सकता है और सुविधाजनक हो सकता है (विशेषकर यदि मेमोरी उपयोग एक चिंता का विषय है)।
अंत में, फ्रेमवर्क में न केवल संसाधन, बल्कि हेडर और / या लाइसेंस फाइलें शामिल हो सकती हैं। इन फ़ाइलों को संप्रेषित करने के लिए एक फ्रेमवर्क का उपयोग करना वास्तव में एक सुविधाजनक वितरण तंत्र है इसलिए अक्सर आप एक फ्रेमवर्क को शामिल करना चाह सकते हैं ताकि ये चीजें आपके बाइनरी के साथ टैग हो सकें (यानी लाइसेंस की आवश्यकताएं इसे अनिवार्य बना सकती हैं)।
--- संपादित करें ---
एडम जॉन्स ने टिप्पणी के रूप में निम्नलिखित प्रश्न पोस्ट किया:
यह एक बेहतरीन जवाब है। हालाँकि, मैं अभी भी थोड़ा उलझन में हूँ। बाइनरी को स्वयं निष्पादित करने का क्या मतलब है? क्या आपका मतलब केवल एम्बेडेड फ्रेमवर्क कोड का उपयोग करना है? मुझे पता है कि आपने पोपेन () का उल्लेख किया है, लेकिन आप कह रहे हैं कि मेरा ऐप पोपेन () कह रहा है? मैं वास्तव में नहीं जानता कि इसका क्या मतलब है।
मैं कह रहा हूं कि एक एम्बेडेड बाइनरी आपके बंडल में सिर्फ एक ऑडियो फ़ाइल या छवि की तरह एक और संसाधन फ़ाइल है, हालांकि फ़ाइल एक निष्पादन योग्य कमांड-लाइन उपकरण है। popen()
समारोह ( man popen
अपने टर्मिनल से अधिक पढ़ने के लिए इसके बारे में) यदि आप किसी अन्य चल रहे प्रोग्राम से मनमाना कार्यक्रमों पर अमल करने देता है। system()
समारोह एक और तरीका है। अन्य लोग भी हैं, और मैं यहां एक ऐतिहासिक उदाहरण दूंगा, जो एम्बेडेड बाइनरी के उपयोग को थोड़ा और स्पष्ट कर सकता है:
जैसा कि आप शायद जानते हैं, जब आप मैक ओएस एक्स पर एक ऐप लॉन्च करते हैं, तो इसे वर्तमान उपयोगकर्ता के उपयोगकर्ता आईडी के साथ लॉन्च किया जाता है। अधिकांश सामान्य इंस्टॉलेशन के तहत, डिफ़ॉल्ट उपयोगकर्ता-पर-डेस्कटॉप admin
उपयोगकर्ता, जिसे उपयोगकर्ता आईडी दिया जाता है 501
।
यूनिक्स-आधारित ऑपरेटिंग सिस्टम पर केवल root
उपयोगकर्ता (यूजर आईडी 0
) की पूरी फाइल सिस्टम तक पूरी पहुंच है। कभी-कभी ऐसा होता है कि डेस्कटॉप उपयोगकर्ता द्वारा लॉन्च किए गए इंस्टॉलर प्रोग्राम को विशेषाधिकार प्राप्त निर्देशिका (उदाहरण के लिए ड्राइवर) में फ़ाइलें स्थापित करने की आवश्यकता होती है। इस मामले में, एप्लिकेशन प्रोग्राम को अपने विशेषाधिकारों को root
उपयोगकर्ता तक पहुंचाने की आवश्यकता है ताकि वह इन प्रतिबंधित निर्देशिकाओं में लिख सके।
ओएस एक्स 10.7 के माध्यम से ऑपरेटिंग सिस्टम में इसे सुविधाजनक बनाने के लिए, ऐप्पल ने अपने प्राधिकरण सेवा एपीआई फ़ंक्शन को प्रदान किया ऑथराइजेशन एक्सक्यूट वाइटप्राइवेज () (यह अब पदावनत कर दिया है, लेकिन अभी भी एक उपयोगी उदाहरण है)।
AuthorizationExecuteWithPrivileges()
एक तर्क के रूप में निष्पादित करने के लिए एक कमांड-लाइन टूल के लिए एक पथ के रूप में लिया गया root
। कमांड लाइन टूल एक निष्पादन योग्य शेल स्क्रिप्ट या संकलित बाइनरी था जिसे आपने अपने इंस्टॉल लॉजिक को चलाने के लिए लिखा था। यह टूल किसी अन्य संसाधन फ़ाइल की तरह ही आपके एप्लिकेशन बंडल के अंदर स्थापित किया गया था।
जब कहा जाता है, तो ओएस ने उपयोगकर्ता के पासवर्ड के लिए पूछते हुए एक प्राधिकरण संवाद स्थापित किया है (आपने इसे पहले देखा है!) और जब दर्ज किया root
गया तो आपके ऐप की ओर से प्रोग्राम निष्पादित करेगा । यह प्रक्रिया केवल popen()
स्वयं के साथ एक कार्यक्रम को निष्पादित करने के समान है , हालांकि popen()
अकेले आपको विशेषाधिकार वृद्धि का लाभ नहीं देता है।