दिलचस्प पोस्ट
सी # एकाधिक विरासत है चाहिए? टेम्पलेट मित्र एंड्रॉइड रनऑनयूआईथ्रेड स्पष्टीकरण MVC में मानक डेटाटैबल्स प्रदर्शित करना एंड्रॉइड एप्लिकेशन में 'अब' पर सेट डेट टाइम टाइम के साथ एक एसक्यूएलआईटी रिकॉर्ड कैसे सम्मिलित करें? सिस्टम.in से पढ़ना – जावा कोणीय 2 बाह्य आदानों तर्क या पैरामीटर? तीर के साथ भाषण बबल कैसे विंडोज 7 64 बिट पर theano के साथ सेटअप cuDnn MySQL में ओरेकल के रोविइड के समतुल्य फिक्स्ड डिवेल में फिट करने के लिए जावास्क्रिप्ट स्केल टेक्स्ट लिब निर्देशिका से जार फ़ाइलों को लोड करने का आदेश AngularJS: $ q -> आस्थगित एपीआई चीजों के आदेश (जीवन चक्र) और जो डाइजेक्ट को आमंत्रित करता है? मैं एक एंकर टैग के लिए एक क्लिक कैसे अनुकरण कर सकता हूं?

जीसीसी के साथ सी / सी ++: स्थायी रूप से संसाधन फ़ाइलों को निष्पादन योग्य / लाइब्रेरी में जोड़ें

क्या किसी के पास कोई विचार है कि जीसीसी के उपयोग से किसी भी संसाधन फ़ाइल को सही ढंग से कैसे निष्पादन योग्य या साझा लाइब्रेरी फ़ाइल में संकलित किया जा सकता है?

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

अगर यह संभव है (और मुझे लगता है कि ऐसा इसलिए है क्योंकि विंडोज के लिए दृश्य सी ++ भी ऐसा कर सकता है), मैं अपने द्विआधारी फ़ाइलों को कैसे लोड कर सकता हूँ? निष्पादन योग्य खुद को पार्स करता है, फ़ाइल ढूंढें और इसके बारे में डेटा निकालें?

शायद जीसीसी के लिए कोई विकल्प नहीं है जो मैंने अभी तक नहीं देखा है खोज इंजनों का उपयोग करना वास्तव में सही चीजें नहीं निकलता था

मुझे साझा पुस्तकालयों और सामान्य ELF-निष्पादनयोग्य के लिए काम करने के लिए इसकी आवश्यकता होगी

किसी भी मदद की सराहना की है

वेब के समाधान से एकत्रित समाधान "जीसीसी के साथ सी / सी ++: स्थायी रूप से संसाधन फ़ाइलों को निष्पादन योग्य / लाइब्रेरी में जोड़ें"

छविमैजिक के साथ:

convert file.png data.h 

जैसे कुछ देता है:

 /* data.h (PNM). */ static unsigned char MagickImage[] = { 0x50, 0x36, 0x0A, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4D, 0x50, 0x0A, 0x32, 0x37, 0x37, 0x20, 0x31, 0x36, 0x32, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, .... 

अन्य कोड के साथ संगतता के लिए आप फिर से एक "नियमित" FILE * ऑब्जेक्ट प्राप्त करने के लिए या फिर एक iostream बनाने के लिए std::stringstream करने के लिए std::stringstream का उपयोग कर सकते हैं। std::stringstream हालांकि इस के लिए अच्छा नहीं है और आप निश्चित रूप से केवल एक सूचक का उपयोग कर सकते हैं कहीं भी आप एक iterator का उपयोग कर सकते हैं

यदि आप इसे automake के साथ प्रयोग कर रहे हैं तो BUILT_SOURCES को उचित रूप से सेट करने के लिए मत भूलें।

यह इस तरह से करने के बारे में अच्छी बात है:

  1. आप पाठ निकालते हैं, इसलिए यह संस्करण नियंत्रण और पैच समझदार रूप से हो सकता है
  2. यह प्रत्येक प्लेटफॉर्म पर पोर्टेबल और अच्छी तरह से परिभाषित है

अद्यतन मैं जॉन रिप्ले के विधानसभा नियंत्रण को पसंद करने के लिए विकसित किया है। .incbin आधारित समाधान प्रदान करता है और अब उस पर एक प्रकार का उपयोग करें।

मैं objcopy (जीएनयू binutils) का प्रयोग किया है जो बाध्यकारी डेटा foo-data.bin से बाइनरी डेटा को निष्पादन योग्य के डेटा अनुभाग में लिंक करने के लिए उपयोग किया है:

 objcopy -B i386 -I binary -O elf32-i386 foo-data.bin foo-data.o 

यह आपको एक foo-data.o ऑब्जेक्ट फ़ाइल देता है जिसे आप अपने निष्पादन योग्य में जोड़ सकते हैं। सी इंटरफ़ेस कुछ ऐसा दिखता है

 /** created from binary via objcopy */ extern uint8_t foo_data[] asm("_binary_foo_data_bin_start"); extern uint8_t foo_data_size[] asm("_binary_foo_data_bin_size"); extern uint8_t foo_data_end[] asm("_binary_foo_data_bin_end"); 

तो आप सामान की तरह कर सकते हैं

 for (uint8_t *byte=foo_data; byte<foo_data_end; ++byte) { transmit_single_byte(*byte); } 

या

 size_t foo_size = (size_t)((void *)foo_data_size); void *foo_copy = malloc(foo_size); assert(foo_copy); memcpy(foo_copy, foo_data, foo_size); 

यदि आपके लक्षित वास्तुकला में विशेष बाधाएं हैं जहां स्थिर और चर डेटा संग्रहीत किया गया है, या आप उस डेटा को .text खंड में संग्रहीत करना चाहते हैं, तो इसे अपने प्रोग्राम कोड के समान स्मृति प्रकार में फिट करने के लिए, आप objcopy पैरामीटर के साथ खेल सकते हैं कुछ और।

आप ld लिंकर का उपयोग करके निष्पादन योग्य में बाइनरी फ़ाइलों को एम्बेड कर सकते हैं। उदाहरण के लिए, यदि आपके पास फाइल foo.bar तो आप इसे ld लिए निम्न कमांड को जोड़ने में एक्ज़ीक्यूटेबल में एम्बेड कर सकते हैं

 --format=binary foo.bar --format=default 

यदि आप gcc माध्यम से ld इस्तेमाल कर रहे हैं तो आपको जोड़ना -Wl

 -Wl,--format=binary -Wl,foo.bar -Wl,--format=default 

यहां --format=binary linker को बताता है कि निम्न फाइल बाइनरी है और --format=default डिफ़ॉल्ट इनपुट स्वरूप में वापस स्विच करती है (यह उपयोगी है अगर आप foo.bar बाद अन्य इनपुट फाइल निर्दिष्ट करेंगे)।

फिर आप कोड से अपनी फ़ाइल की सामग्री तक पहुंच सकते हैं:

 extern uint8_t data[] asm("_binary_foo_bar_start"); extern uint8_t data_end[] asm("_binary_foo_bar_end"); 

"_binary_foo_bar_size" नामक चिन्ह भी है मुझे लगता है कि यह uintptr_t प्रकार है लेकिन मैंने इसे जांच नहीं की।

आप अपने सभी संसाधनों को एक ज़िप फ़ाइल में डाल सकते हैं और निष्पादन योग्य फ़ाइल के अंत में जोड़ सकते हैं :

 g++ foo.c -o foo0 zip -r resources.zip resources/ cat foo0 resources.zip >foo 

यह काम करता है, क्योंकि) सबसे अधिक निष्पादन योग्य छवि प्रारूपों पर ध्यान नहीं दिया जाता है कि छवि के पीछे अतिरिक्त डेटा है और ख) ज़िप फ़ाइल के अंत में फ़ाइल हस्ताक्षर को संग्रहीत करता है। इसका मतलब है, आपके निष्पादन योग्य इस के बाद एक नियमित ज़िप फ़ाइल है (आपके अग्रिम एक्जीक्यूटेबल को छोड़कर, जो ज़िप को नियंत्रित कर सकता है), जो कि लिब्ज़िप के साथ खोला और पढ़ा जा सकता है

http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967 से :

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

और वहाँ है, यह बचाव के लिए 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 पर ऑब्जेक्ट फाइल) में होनी चाहिए। –बाइनरी-आर्किटेक्चर विकल्प objcopy को बताता है कि आउटपुट फाइल को x86 पर "रन" करना है। यह आवश्यक है ताकि ld फ़ाइल को x 86 के लिए अन्य फाइलों से जोड़ने के लिए स्वीकार करे। ऐसा लगता होगा कि आउटपुट स्वरूप को "एलफ 32-आई -386" के रूप में निर्दिष्ट करते हुए यह निर्दिष्ट होगा, लेकिन ऐसा नहीं है।

अब जब कि हमारे पास एक ऑब्जेक्ट फाइल है, हम इसे लिंक करने के लिए केवल इसे शामिल करने की आवश्यकता है:

 # gcc main.c data.o 

जब हम परिणाम चलाते हैं तो हम आउटपुट के लिए प्रार्थना करते हैं:

 # ./a.out Hello world 

बेशक, मैंने अभी तक पूरी कहानी नहीं बताई है, न ही आपको मुख्य दिखाया है। जब objcopy उपरोक्त रूपांतरण करता है तो यह परिवर्तित वस्तु फ़ाइल में कुछ "लिंकर" चिह्न जोड़ता है:

 _binary_data_txt_start _binary_data_txt_end 

लिंक करने के बाद, ये प्रतीक एम्बेडेड फ़ाइल के आरंभ और अंत को निर्दिष्ट करते हैं। प्रतीक नाम बाइनरी के अंतराल के द्वारा और फाइल नाम में _start या _ending को जोड़ते हैं। यदि फ़ाइल नाम में कोई भी वर्ण शामिल है जो प्रतीक नाम में अमान्य होगा, तो वे अंडरस्कोर में परिवर्तित हो जाते हैं (जैसे 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_bar_t के रूप में यदि डेटा फ़ू सलाखों के किसी भी सरणी थे। यदि एम्बेडेड डेटा एकसमान नहीं है, तो चर शायद सबसे अधिक सुविधाजनक है: इसका पता लगाएं और सूचक को उचित प्रकार के रूप में डालें जैसा कि आप डेटा को पार करते हैं

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

विधानसभा (x 86 / आर्म):

  .section .rodata .global thing .type thing, @object .align 4 thing: .incbin "meh.bin" thing_end: .global thing_size .type thing_size, @object .align 4 thing_size: .int thing_end - thing 

सी:

 #include <stdio.h> extern char thing[]; extern unsigned thing_size; int main() { printf("%p %u\n", thing, thing_size); return 0; } 

जो भी आप उपयोग करते हैं, सभी संसाधनों को उत्पन्न करने के लिए एक स्क्रिप्ट बनाने के लिए सबसे अच्छा है, और सभी के लिए अच्छा / समान प्रतीक नाम हैं

क्या मैं जोड़ सकता हूं कि जॉन रिप्ले की विधि संभवत: यहाँ एक बड़ा कारण है – संरेखण। यदि आप एक मानक objcopy या "ld -r -b binary -o foo.o foo.txt" करते हैं और फिर objdump -x के साथ परिणामी ऑब्जेक्ट को देखें तो यह दिखता है कि ब्लॉक के संरेखण 0 पर सेट है। यदि आप चाहते हैं संरेखण के लिए बाइनरी डेटा के अलावा अन्य के लिए सही है, मैं कल्पना नहीं कर सकता यह एक अच्छी बात है

यहां सभी पोस्ट पढ़ना और इंटरनेट में मैंने एक निष्कर्ष दिया है कि संसाधनों के लिए कोई उपकरण नहीं है, जो है:

1) कोड में उपयोग करने में आसान।

2) स्वचालित (सीएमके / मेक में आसानी से शामिल होना)

3) क्रॉस-प्लेटफॉर्म

मैंने खुद को उपकरण लिखने का फैसला किया है कोड यहां उपलब्ध है। https://github.com/orex/cpp_rsc

इसे सेमीके के साथ प्रयोग करने के लिए बहुत आसान है।

आपको अपने CMakeLists.txt फ़ाइल को ऐसे कोड में जोड़ना चाहिए।

 file(DOWNLOAD https://raw.github.com/orex/cpp_rsc/master/cmake/modules/cpp_resource.cmake ${CMAKE_BINARY_DIR}/cmake/modules/cpp_resource.cmake) set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}/cmake/modules) include(cpp_resource) find_resource_compiler() add_resource(pt_rsc) #Add target pt_rsc link_resource_file(pt_rsc FILE <file_name1> VARIABLE <variable_name1> [TEXT]) #Adds resource files link_resource_file(pt_rsc FILE <file_name2> VARIABLE <variable_name2> [TEXT]) ... #Get file to link and "resource.h" folder #Unfortunately it is not possible with CMake add custom target in add_executable files list. get_property(RSC_CPP_FILE TARGET pt_rsc PROPERTY _AR_SRC_FILE) get_property(RSC_H_DIR TARGET pt_rsc PROPERTY _AR_H_DIR) add_executable(<your_executable> <your_source_files> ${RSC_CPP_FILE}) 

वास्तविक उदाहरण, दृष्टिकोण का उपयोग करके यहां डाउनलोड किया जा सकता है, https://bitbucket.org/orex/periodic_table