2009-07-03 14 views
8

मैं एक एम्बेडेड ओएस के लिए अपवाद हैंडलिंग को लागू करने की कोशिश कर रहा हूं और मैं फेंक दिया गया "अपवाद" (उचित हैंडलर का चयन करने के लिए) के प्रकार का पता लगाने के लिए कैसे अटक गया हूं।सी ++ के लिए सबसे सरल आरटीटीआई कार्यान्वयन क्या है?

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

यह मानते हुए कि मेरा लक्ष्य एक एम्बेडेड सिस्टम है और इसी कारण से मैं अधिक कोड नहीं बना सकता, "रनटाइम टाइप सूचना" का सबसे छोटा कार्यान्वयन क्या है (या बनाना)?

- संपादित करें -

मैं संकलक पर काम नहीं कर रहा हूँ, यह एक ia32-जी है ++।

+1

क्या आप कंपाइलर या भाषा रनटाइम लिख रहे/संशोधित कर रहे हैं, या आप इसे कहां फिट करने जा रहे हैं? थोड़ा और संदर्भ अच्छा होगा। – jalf

+0

यदि आप स्मृति सीमित हैं, तो आपको आरटीटीआई सक्षम नहीं करना चाहिए, या यहां तक ​​कि अपवादों का उपयोग करने का प्रयास नहीं करना चाहिए।एक वैकल्पिक दृष्टिकोण बेहतर सोचो। –

+0

यदि कोई अपवाद फेंक दिया गया है, तो किसी भी तरह से फेंकने वाले नस्ट ने अपवाद प्रकार की जानकारी को एन्कोड किया है, इसलिए मैं नहीं देख सकता कि आपको कुछ "वैकल्पिक" विधि क्यों चाहिए। जैसे ही आधे ने कहा, हमें वास्तव में क्या करने की कोशिश कर रहे हैं, इस बारे में अधिक जानकारी दें। –

उत्तर

11

जैसा कि आप एक एम्बेडेड वातावरण में काम कर रहे हैं, आप संभवतः अत्यंत न्यूनतम समाधान का पक्ष लेते हैं और आप अपने कंपाइलर के बारे में गैर-मानक या गैर-पोर्टेबल तथ्यों का लाभ उठा सकते हैं।

यदि कोई कक्षा सी ++ में पॉलिमॉर्फिक (कम से कम एक वर्चुअल फ़ंक्शन है) है, तो संभवतः इसमें कहीं भी एम्बेडेड एक vtable के लिए पॉइंटर होता है। यह हो सकता है कि vtable सूचक स्मृति में ऑब्जेक्ट के लेआउट की शुरुआत में प्रकट होता है।

यह कई कंपाइलरों के बारे में सच है, जो सी ++ एबीआई - a related SO question here का उपयोग करते हैं।

void *get_vtable(void *obj) 
{ 
    return *(reinterpret_cast<void **>(obj)); 
} 

तो फिर तुम दो संकेत करने वाली वस्तुओं की vtables तुलना कर सकते हैं देखने के लिए अगर वे एक ही प्रकार को इंगित:

यदि हां, तो आप इस तरह vtable पर प्राप्त करने में सक्षम हो सकता है वस्तु का

तो एक "प्रकार स्विच" (जो है क्या मूल रूप से है पकड़) कुछ इस तरह करना होगा:

P p; 
Q q; 
if (get_vtable(caught) == get_vtable(&p)) 
{ 
    // it's a P... 
} 
else if (get_vtable(caught) == get_vtable(&q)) 
{ 
    // it's a Q... 
} 

आपको एक मैक्रो में उस पैटर्न को छिपाने सकता है।

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

ध्यान दें कि यह अपवाद हैंडलिंग में केवल एक छोटा सा अंश है। ढेर को अनदेखा करने का भी छोटा मामला है! जब आप हैंडलर पर कूदते हैं तो आपको ढेर पर सभी ऑब्जेक्ट्स के विनाशकों को कॉल करने की आवश्यकता होती है। यह सिर्फ setjmp/longjmp करने का मामला नहीं है।

+0

क्या आप पहले कोड में 'पीआरटी' पाने का कोई तरीका दिखा सकते हैं? और मैं 'ओबीजे' भूमिका भी समझ नहीं पाया। – freitass

+0

क्षमा करें, वह एक टाइपो था। यह सिर्फ एक बहुलक प्रकार के एक वस्तु के लिए एक सूचक है। –

2

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

+0

बेशक, आभासी कार्यों के अस्तित्व के लिए, आप शायद कुछ प्रकार के आभासी-फ़ंक्शन-पॉइंटर-टेबल का उपयोग करते हैं। जो किसी भी तरह से आरटीआई के लिए इस्तेमाल किया जा सकता है ... – gimpf

+0

हालांकि विशाल enum विधि से अधिक शामिल है;) – Goz

+0

इसे अपने पैड को कम क्रॉस प्लेटफ़ॉर्म भी जोड़ना चाहिए ... उन VTables को ढूंढना खूनी कड़ी मेहनत हो सकती है। – Goz

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