से http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967 :
मुझे हाल ही में एक निष्पादन योग्य में एक फ़ाइल एम्बेड करने की आवश्यकता थी। चूंकि मैं कमांड लाइन पर gcc, et al के साथ काम कर रहा हूं, न कि एक फैंसी RAD टूल के साथ जो यह सब जादुई तरीके से होता है, इसलिए यह तुरंत मेरे लिए स्पष्ट नहीं था कि यह कैसे किया जाए। नेट पर खोज करने वाले एक बिट ने एक हैक पाया जो अनिवार्य रूप से इसे निष्पादन योग्य के अंत में बिल्ली बना देता था और फिर यह समझ में नहीं आता कि यह जानकारी के एक समूह पर आधारित था जिसके बारे में मैं जानना नहीं चाहता था। लगता है जैसे वहाँ एक बेहतर तरीका होना चाहिए ...
और वहाँ है, यह बचाव के लिए objcopy है। objcopy एक प्रारूप से दूसरे में ऑब्जेक्ट फ़ाइलों या निष्पादन योग्य को रूपांतरित करता है। एक प्रारूप जो इसे समझता है वह "बाइनरी" है, जो मूल रूप से किसी भी फ़ाइल है जो कि उस अन्य स्वरूपों में से एक में नहीं है जिसे वह समझता है। तो आपने शायद इस विचार की कल्पना की है: उस फ़ाइल को रूपांतरित करें जिसे हम ऑब्जेक्ट फ़ाइल में एम्बेड करना चाहते हैं, फिर इसे बस हमारे बाकी कोड के साथ जोड़ा जा सकता है।
मान लें कि हमारे पास एक फ़ाइल नाम data.txt है जिसे हम अपने निष्पादन योग्य में एम्बेड करना चाहते हैं:
# cat data.txt
Hello world
इसे एक ऑब्जेक्ट फ़ाइल में परिवर्तित करने के लिए जिसे हम अपने प्रोग्राम से जोड़ सकते हैं, हम सिर्फ ".o" फ़ाइल का उत्पादन करने के लिए objcopy का उपयोग करते हैं।
# objcopy --input binary \
--output elf32-i386 \
--binary-architecture i386 data.txt data.o
यह objcopy बताता है कि हमारी इनपुट फ़ाइल "बाइनरी" प्रारूप में है, कि हमारी आउटपुट फाइल "elf32-i386" प्रारूप में होनी चाहिए (x86 पर ऑब्जेक्ट फाइलें)। --Binary- आर्किटेक्चर विकल्प objcopy को बताता है कि आउटपुट फ़ाइल x86 पर "रन" करने के लिए है। यह आवश्यक है ताकि ld फ़ाइल को x86 के लिए अन्य फ़ाइलों के साथ लिंक करने के लिए स्वीकार कर ले। किसी को लगता है कि आउटपुट प्रारूप को "elf32-i386" के रूप में निर्दिष्ट करने से इसका अर्थ होगा, लेकिन ऐसा नहीं है।
अब जब हमारे पास एक ऑब्जेक्ट फाइल है तो हमें केवल इसे शामिल करना होगा जब हम लिंकर को चलाते हैं:
# gcc main.c data.o
जब हम परिणाम चलाते हैं तो हमें आउटपुट के लिए प्रार्थना की जाती है:
# ./a.out
Hello world
बेशक, मैंने पूरी कहानी अभी तक नहीं बताई है, और न ही आपको मुख्य। जब objcopy उपरोक्त रूपांतरण करता है तो यह परिवर्तित ऑब्जेक्ट फ़ाइल में कुछ "लिंकर" प्रतीकों को जोड़ता है:
_binary_data_txt_start
_binary_data_txt_end
लिंक करने के बाद, ये प्रतीक एम्बेडेड फ़ाइल की शुरुआत और अंत निर्दिष्ट करते हैं। प्रतीक नाम द्विआधारी prepending और फ़ाइल नाम के लिए _start या _end द्वारा बनाए गए हैं । यदि फ़ाइल नाम में कोई भी वर्ण है जो प्रतीक नाम में अमान्य होगा तो वे अंडरस्कोर में बदल जाते हैं (जैसे data.txt data_txt हो जाता है)। यदि आप इन प्रतीकों का उपयोग करते समय लिंक किए गए नाम प्राप्त करते हैं, तो ऑब्जेक्ट फ़ाइल पर एक हेक्सडंप-सी करें और उन नामों के लिए डंप के अंत को देखें जो ऑबजॉपी ने चुने थे।
कोड वास्तव में एम्बेडेड फ़ाइल का उपयोग करने के लिए अब यथोचित स्पष्ट होना चाहिए:
#include <stdio.h>
extern char _binary_data_txt_start;
extern char _binary_data_txt_end;
main()
{
char* p = &_binary_data_txt_start;
while ( p != &_binary_data_txt_end ) putchar(*p++);
}
एक महत्वपूर्ण और सूक्ष्म बात यह है कि ऑब्जेक्ट फ़ाइल में जोड़े गए प्रतीक "चर" नहीं हैं। उनके पास कोई डेटा नहीं है, बल्कि, उनका पता उनका मूल्य है। मैं उन्हें टाइप चार के रूप में घोषित करता हूं क्योंकि यह इस उदाहरण के लिए सुविधाजनक है: एम्बेडेड डेटा चरित्र डेटा है। हालाँकि, आप उन्हें कुछ भी घोषित कर सकते हैं, जैसे कि डेटा पूर्णांक का एक सरणी है, या यदि डेटा foo बार के किसी भी सरणी के रूप में संरचनात्मक foo_bar_t है। यदि एम्बेडेड डेटा एक समान नहीं है, तो संभवत: चार सबसे सुविधाजनक है: अपना पता लें और सूचक को उचित प्रकार से डालें जैसे कि आप डेटा को पार करते हैं।