सी / सी ++। लिनक्स पर जीसीसी में काम करते समय एम्बेडेड एप्लिकेशन संसाधनों का उपयोग कैसे करें

मैं किसी तरह लिनक्स एम्बेडेड संसाधनों का उपयोग करना चाहता था, इसके अलावा, स्वचालित रूप से। सामान्य तौर पर, कार्य यह है:


  1. C ++ में एक ग्रहण परियोजना कार्यक्रम है।
  2. ओएस: लिनक्स उबंटू। संकलक: जी ++
  3. प्रोजेक्ट बाहरी फ़ाइलों से डेटा का उपयोग करता है: स्थानीयकरण स्ट्रिंग्स, SQL क्वेरीज़, चित्र, ध्वनियाँ आदि।
  4. सभी संसाधनों को निष्पादन योग्य फ़ाइल में एम्बेड किया जाना चाहिए, क्योंकि कार्यक्रम को पोर्टेबल के रूप में वितरित करने की योजना है।
  5. इसके अलावा, मैं चाहता हूं कि प्रक्रिया यथासंभव स्वचालित हो, क्योंकि आलस्य।

शुरू करने के लिए, मंचों पर एक खोज ने समस्या को हल करने के कई संभावित तरीके प्रदान किए। जो लोग सबसे सार्वभौमिक पाए गए उनमें से, विचार मुझे " --format=binary " लिंकर पैरामीटर " ld " का उपयोग करने के लिए लग रहा था। फोरम के पदों ने फार्म की एक टीम का वादा किया:

 g++ -Wl,--format=binary -Wl,my.res -Wl,--format=default 

फ़ाइल "my.res" को एप्लिकेशन से लिंक करेगा और दो अक्षर बनाएगा - _binary_my_res_start और _binary_my_res_end , जो क्रमशः, लिंक किए गए फ़ाइल में मौजूद बहुत डेटा की शुरुआत और अंत दर्शाता है। इसलिए, C ++ से डेटा एक्सेस करना कुछ इस तरह किया जा सकता है:
 extern const uint8_t my_res_start[] asm("_binary_my_res_start"); extern const uint8_t my_res_end[] asm("_binary_my_res_end"); 

लेकिन वहाँ यह था। हम सबकुछ लिखते हैं जैसा कि यह होना चाहिए, और कंपाइलर खुश नहीं है। प्रतीक «_binary_my_res_start» , आप देखते हैं, नहीं पाया जा सकता है। खैर, कुछ भी नहीं, हमारी मदद करने के लिए nm । हम निम्नलिखित कमांड लिखते हैं:

 nm MyProgramm |grep -w -o -P -e '_binary_[\w\d_]+' 

और हम प्राप्त करते हैं:

 _binary__home_unknown_workspace_MyProgramm_res_my_res_sql_end _binary__home_unknown_workspace_MyProgramm_res_my_res_sql_start 

यह पता चला है कि प्रतीक के नाम में इसका पूरा रास्ता शामिल है, जो भविष्य में, हेडर फ़ाइल के निरंतर पुनर्लेखन की आवश्यकता को जन्म दे सकता है जिसमें संसाधनों के लिंक होते हैं। यदि निम्न स्क्रिप्ट ग्रहण प्रोजेक्ट सेटिंग्स में PostBuild घटना में जोड़ा जाता है, तो समस्या हल हो गई है:

 #!/bin/bash OUTPUT=$1/resources.h printf '#ifndef __RESOURCES_H__\n' > "$OUTPUT" printf '#define __RESOURCES_H__\n\n' >> "$OUTPUT" printf '#include <inttypes.h>\n\n' >> "$OUTPUT" SYMBOLS=$(nm NewsParser |grep -w -o -P -e '_binary_[\w\d_]+') >> "$OUTPUT" VAR_SIZES_LIST='' for SYMBOL in $SYMBOLS do VAR_NAME=$(echo $SYMBOL | grep -o -P -e 'res_[\w\d_]+'|cut -c 5-) if [[ -z $(echo $SYMBOL|grep _size) ]] then printf '\textern const uint8_t '$VAR_NAME'[]\tasm("'$SYMBOL'");\n\n' >> "$OUTPUT" else START_VAR=$(echo $VAR_NAME|rev|cut -c 5-|rev)'start' END_VAR=$(echo $VAR_NAME|rev|cut -c 5-|rev)'end' VAR_SIZES_LIST=$VAR_SIZES_LIST$(printf '\\tconst uint64_t '$VAR_NAME'\\t=\\t'$END_VAR' - '$START_VAR';\\n\\n') fi done printf "$VAR_SIZES_LIST" >> "$OUTPUT" printf '#endif\n' >> "$OUTPUT" printf 'File '$OUTPUT' is generated.\n' 

एक्लिप्स प्रोजेक्ट सेटिंग्स में PostBuild घटना के लिए, जो "update_resource.sh" स्क्रिप्ट को कैसे जोड़ें, प्रोजेक्ट की जड़ में है।


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

लेकिन यह, अभी के लिए, यह सब नहीं है। आखिरकार, प्रत्येक नए संसाधन को एक परियोजना में जोड़ने से एक आकार का विज्ञापन बन जाएगा। और इस समस्या को एक स्क्रिप्ट की मदद से भी जोड़ा जा सकता है, केवल लिंकिंग स्टेज पर:

 FLAGS=$1 OUTPUT_FLAG=$2 OUTPUT_PREFIX=$3 OUTPUT=$4 INPUTS=$5 RESOURCE_PATH=$6 RESOURCES='' for res_file in $(ls $RESOURCE_PATH/*) do RESOURCES=$RESOURCES' '-Wl,$res_file echo ' '$res_file'   ' done g++ $FLAGS $OUTPUT_FLAG $OUTPUT_PREFIX$OUTPUT $INPUTS -Wl,--format=binary $RESOURCES -Wl,--format=default 

ग्रहण परियोजना सेटिंग्स में एक कस्टम स्क्रिप्ट के साथ मानक लिंकर की कॉल को कैसे बदलें।


  • लाल रंग में जगह को चित्र में चिह्नित किया गया है, जहां लिंकर को कॉल करने के लिए मानक कमांड के बजाय, स्क्रिप्ट "link.sh" का पथ परियोजना की जड़ में स्थित है।
  • चित्र में हरा एक ऐसा स्थान है जिसमें एक और लिंकर को सामान्य लिंकर मापदंडों में जोड़ा जाता है, जो स्क्रिप्ट को संसाधनों के साथ निर्देशिका का स्थान बताता है।
  • इसके अलावा , दोहरे मापदंडों के साथ शेष मापदंडों को लपेटना नहीं भूलना महत्वपूर्ण है ताकि वे गलती से गलत क्रम में रिक्त स्थान के साथ टूट न जाएं जिसमें स्क्रिप्ट उनके लिए इंतजार कर रही है।


बहुत बढ़िया। अब सभी फाइलें जो "res" उपनिर्देशिका में हैं वे स्वयं प्रत्येक विधानसभा के दौरान संसाधनों में गिर जाएंगी।

Source: https://habr.com/ru/post/hi468399/


All Articles