2013-04-24 4 views
5

मैं एक एम्बेडेड सिस्टम (विशेष रूप से, पीएसओसी 5 का उपयोग कर पीएसओसी 5) के लिए कोड विकसित कर रहा हूं, और सी ++ में लिख रहा हूं।एंबेडेड प्लेटफ़ॉर्म पर Vtables को सही तरीके से कार्यान्वित क्यों नहीं किया जा रहा है?

मैं, सी ++ का उपयोग कर, पहले C++ में संकलन संकलक झंडा -x c++ का उपयोग कर बंद नई परिभाषित करने और ऑपरेटरों को हटाते हैं, यकीन है कि अपवाद बनाने संकलक झंडा -fno-exception साथ फेंक दिया नहीं कर रहे हैं के साथ सबसे अधिक बाधाओं पर काबू पाने के लिए हैं, लेकिन मैं आए हैं जब वर्चुअल फ़ंक्शंस का उपयोग करने की बात आती है तो ईंट की दीवार पर।

यदि मैं वर्चुअल फ़ंक्शन को आज़माता हूं और घोषित करता हूं, तो संकलक मुझे त्रुटि undefined reference to "vtable for __cxxabiv1::__class_type_info" देता है। इस के आसपास जाने का एकमात्र तरीका कंपाइलर ध्वज -fno-rtti का उपयोग करना है, जो त्रुटि को रोकता है और इसे सफलतापूर्वक संकलित करता है। हालांकि, अगर मैं ऐसा करता हूं, तो ओवरलोडेड वर्चुअल फ़ंक्शन चलाने की कोशिश करते समय एम्बेडेड प्रोग्राम क्रैश हो जाता है, और मुझे लगता है कि ऐसा इसलिए है क्योंकि vtable मौजूद नहीं है।

मुझे नहीं लगता कि आपको एम्बेडेड प्लेटफ़ॉर्म पर vtables को लागू करने में सक्षम क्यों नहीं होना चाहिए, क्योंकि यह सदस्य ऑब्जेक्ट से पहले या बाद में स्मृति में एक अतिरिक्त स्थान है (सटीक कंपाइलर के आधार पर)।

कारण मैं आभासी कार्यों का उपयोग करने के लिए कोशिश कर रहा हूँ है, क्योंकि मैं सी ++ के साथ FreeRTOS का उपयोग करना चाहते रहा हूँ, और अन्य लोगों को आभासी कार्यों का उपयोग कर (चर्चा के लिए http://www.freertos.org/FreeRTOS_Support_Forum_Archive/July_2010/freertos_Is_it_possible_create_freertos_task_in_c_3778071.html, और https://github.com/yuriykulikov/Event-driven_Framework_for_Embedded_Systems देख एक अच्छी तरह से लिखा एम्बेडेड सी ++ FreeRTOS के लिए द्वारा इस को लागू किया है ढांचा)

+0

आप अपनी निष्पादन योग्य/साझा लाइब्रेरी को कैसे जोड़ रहे हैं? – jxh

+2

क्या आप वाकई इस तथ्य के कारण हैं कि आप एक एम्बेडेड प्लेटफ़ॉर्म के लिए संकलित करते हैं? क्या आपने मानक प्लेटफ़ॉर्म पर कोड के प्रासंगिक हिस्सों को संकलित करने का प्रयास किया है? – jogojapan

+0

पीएसओसी आईडीई बिल्ड प्रक्रिया के हिस्से के रूप में लिंकर स्क्रिप्ट चलाता है। यह सुनिश्चित करने के लिए कि यह मानक C++ लाइब्रेरी से लिंक है, मैंने ध्वज '-lstdC++' ध्वज शामिल किया है। – gbmhunter

उत्तर

5

तथ्य यह है कि त्रुटि संदेश __cxxabiv1 नाम के एक वर्ग को संदर्भित करता है पता चलता है कि आप सही सी ++ क्रम अपने मंच के लिए रूप से लिंक हो नहीं कर रहे हैं। मुझे पीएसओसी के बारे में कुछ भी पता नहीं है, लेकिन अधिक "सामान्य" प्लेटफार्मों पर, g++ (resp। clang++) के बजाय लिंक-टाइम पर gcc (resp। clang) कमांड का उपयोग करने पर यह त्रुटि हो सकती है; या हाथ से चलने वाली परिस्थितियों में यदि आपने -lc++-stdlib=libc++ या -lstdc++-stdlib=libstdc++ के बिनाका उपयोग किया था।

अपने लिंकर कमांड लाइन की जांच करने के -v विकल्प का उपयोग करें, और वास्तव में जो सी ++ क्रम पुस्तकालय उस में खींच रही है पता लगाने के लिए प्रयास करें। यह शायद libcxxabi या libcxxrt की तरह कुछ नामित हो जाएगा।

This guy here पीएसओसी निर्माता में सी ++ संकलन के लिए चरण-दर-चरण निर्देश देता है; लेकिन उन्होंने कभी भी यह पता नहीं लगाया कि सी ++ रनटाइम लाइब्रेरी से कैसे लिंक किया जाए, इसलिए उनकी सभी युक्तियां इस बात पर केंद्रित हैं कि अपने कोड से 0+34 आईएमएस हटाएं (-fno-rtti, -fno-exceptions, ...)। मैं मानता हूं कि वास्तव में पीएसओसी के साथ सी ++ का उपयोग करने के तरीके के बारे में कोई जानकारी नहीं प्रतीत होती है।

इस विशिष्ट त्रुटि के लिए, आप हमेशा याद आ रही प्रतीक को परिभाषित कर सकता है की कोशिश अपने आप को:

// file "fix-link-errors.cpp" 
namespace __cxxabiv1 { 
    class __class_type_info { 
     virtual void dummy(); 
    }; 
    void __class_type_info::dummy() { } // causes the vtable to get created here 
}; 

या कई linkers ऐसे -C या --defsym के रूप में कमांड लाइन विकल्प के माध्यम से 0x0 के रूप में अपरिभाषित प्रतीकों को परिभाषित करने की क्षमता है । हालांकि, यह न केवल एक बुरा विचार है बल्कि असुविधाजनक है, क्योंकि आपको यह पता लगाना होगा कि vtable ऑब्जेक्ट का वास्तविक (उलझन) नाम क्या है, और लिंकर ने आपको यह नहीं बताया। (यह जीसीसी है, शायद यह __ZTVN10__cxxabiv117__class_type_infoE जैसा कुछ है।)

किसी भी "समाधान" का कोई भी भयानक दुर्घटनाओं का परिणाम होगा यदि कार्यक्रम ने को vtable के साथ कुछ भी करने की कोशिश की; लेकिन वे लिंकर को बंद कर देंगे, अगर आप सब की परवाह है और आपको पता था कि प्रोग्राम वास्तव में आरटीटीआई का उपयोग नहीं करेगा। लेकिन उस स्थिति में, यह आपके पूरे प्रोजेक्ट पर लगातार -fno-rtti का उपयोग करने के लिए पर्याप्त होना चाहिए।

-fno-rtti का उपयोग करते समय, विशेष रूप से, गलत क्या होता है?

संबंधित मुद्दे