2008-09-17 20 views
15

अधिकांश परिपक्व सी ++ परियोजनाओं में प्रतिबिंब और विशेषता प्रणाली होती है, यानी उन गुणों को परिभाषित करने के लिए जिन्हें स्ट्रिंग द्वारा एक्सेस किया जा सकता है और स्वचालित रूप से क्रमबद्ध होते हैं। कम से कम कई सी ++ परियोजनाओं में मैंने भाग लिया पहिया को पुन: पेश करता था।सी ++ के लिए विशेषता और प्रतिबिंब पुस्तकालय?

आप सी ++ के लिए किसी भी अच्छा खुले स्रोत संग्रहालय जो प्रतिबिंब का समर्थन और कंटेनरों विशेषता जानते हैं, विशेष रूप से:

  • डिफाइनिंग RTTI और मैक्रो
  • RTTI तक पहुँचना के माध्यम से विशेषताओं और कोड
  • स्वचालित के माध्यम से जिम्मेदार बताते हैं गुणों का क्रमबद्धता
  • संशोधनों को विशेषता बनाने के लिए सुनना (उदाहरण के लिए OnValueChanged)

उत्तर

5

आप नीचे दिए गए दो टूल्स देख सकते हैं। मैंने कभी उनमें से किसी का भी उपयोग नहीं किया है, इसलिए मैं आपको यह नहीं बता सकता कि वे कैसे (im) व्यावहारिक हैं।

XRTTI:

Xrtti एक उपकरण और साथ सी ++ पुस्तकालय जो वर्गों और तरीकों इन कक्षाओं में हेरफेर करने के लिए और के बारे में प्रतिबिंब जानकारी का अधिक समृद्ध सेट उपलब्ध कराने के लिए सी ++ के मानक क्रम प्रकार प्रणाली फैली हुई है उनके सदस्य हैं।

OpenC++:

OpenC++ सी ++ दृश्यपटल पुस्तकालय (lexer + पार्सर + डोम/एमओपी) और स्रोत करने वाली स्रोत अनुवादक है। ओपनसी ++ सी ++ भाषा उपकरण, एक्सटेंशन, डोमेन विशिष्ट कंपाइलर अनुकूलन और रनटाइम मेटाबोजेक्ट प्रोटोकॉल के विकास को सक्षम बनाता है।

+0

XRTTI के पास अभी भी देर से लिनक्स वितरण के लिए एक अद्यतन संस्करण है। ओपनसी ++ बहुत पुराना प्रतीत होता है। – minghua

2

सामान्य नहीं है लेकिन क्यूटी मेटा कंपाइलर के माध्यम से इसका समर्थन करता है, और जीपीएल है। क्यूटी लोगों से बात करने से मेरी समझ यह थी कि शुद्ध सी ++ के साथ यह संभव नहीं है, इसलिए मोक की आवश्यकता है।

2

यह सामान्य रूप से सी ++ भाषा की कुख्यात कमजोरी है क्योंकि चीजों को प्रतिबिंबित करने के लिए मानकीकृत करने की आवश्यकता होगी पोर्टेबल और सार्थक मानक नहीं हैं। कॉलिंग सम्मेलन, वस्तु लेआउट, और प्रतीक उलझन में आते हैं, लेकिन अन्य भी हैं।

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

11

यह वही आपको मिलता है जब सी ++ प्रतिबिंब को पूरा करती है: डिबग कोड या अजीब निर्माण कदम

C++ meets Reflection

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

गंभीर रूप से, छोटी परियोजनाओं के लिए, बचत/लोड फ़ंक्शन (या स्ट्रीमिंग ऑपरेटरों का उपयोग करना) लिखना आसान होगा। वास्तव में, यह भी बड़ी परियोजनाओं के लिए हो सकता है - यह स्पष्ट है कि क्या हो रहा है और संरचना में बदलाव होने पर आपको आमतौर पर कोड बदलने की आवश्यकता होगी।

+1

जब तक मेरा ऐप पहले से ही क्यूटी का उपयोग नहीं करता है, तो मैं अपने प्रत्येक वर्ग के लिए स्ट्रीमिंग ऑपरेटरों को सहेजता हूं जिन्हें सहेजने की आवश्यकता होती है। – Branan

+0

+1: फोटो के लिए;) मजाक कर रहा है। मैं निष्कर्ष से सहमत हूं। हैंडकाफ्ट सीरियलिसर्स का उपयोग करें या किसी अन्य लंगेज का उपयोग करें :) – neuro

+0

+1: फोटो के लिए, वास्तव में, यह बहुत कुछ नहीं कहता है: डी – thecoshman

3

मैंने इन चीजों को थोड़ी देर के लिए देखा लेकिन वे बहुत भारी हैं। वे आपको विरासत का उपयोग करने, या अजीब रचनाकार इत्यादि से रोकने से रोक सकते हैं। अंत में वे सुविधा के बजाए बोझ का बहुत अधिक हो गए।

सदस्यों का खुलासा करने के लिए यह दृष्टिकोण काफी हल्का है और उदाहरण के लिए, "x" से 0 नामक सभी फ़ील्ड को क्रमबद्ध करने या सेट करने के लिए आपको कक्षा का पता लगाने देता है। यह भी स्थिर रूप से निर्धारित है इसलिए बहुत तेज़ है। बिल्ड प्रक्रिया के साथ गड़बड़ करने की चिंता करने के लिए लाइब्रेरी कोड या कोड-जेन की कोई परत नहीं है। यह नेस्टेड प्रकार के पदानुक्रमों के लिए सामान्यीकृत है।

इन संपादकों में से कुछ को स्वचालित करने के लिए अपने मैक्रोज़ को कुछ मैक्रोज़ के साथ सेट करें।

struct point 
{ 
    int x; 
    int y; 

    // add this to your classes 
    template <typename Visitor> 
    void visit(Visitor v) 
    { 
     v->visit(x, "x"); 
     v->visit(y, "y"); 
    } 
}; 


/** Outputs any type to standard output in key=value format */ 
struct stdout_visitor 
{ 
    template <typename T> 
    void visit(const T& rhs) 
    { 
     rhs.visit(this); 
    } 

    template <typename Scalar> 
    void visit (const Scalar& s, const char* name) 
    { 
      std::cout << name << " = " << s << " "; 
    } 
} 
+0

जबकि मुझे यह पसंद है, यह ध्यान दिया जाना चाहिए कि यह एक सामान्य समाधान नहीं है - उदा। जैसे ही वास्तविक स्थैतिक प्रकार ज्ञात नहीं होता है, यह टूट जाता है। –

+0

यह एक अच्छा तरीका है। मैंने एक बार प्रीप्रोसेसर बनाया जो आपके लिए 'विज़िट()' फ़ंक्शन टेम्पलेट उत्पन्न करता है। और फिर जेएसओएन, बाइनरी, टेक्स्ट इत्यादि को क्रमबद्ध और deserialize करने के लिए कुछ functors ... कोई बदसूरत मैक्रोज़। https://groups.google.com/d/msg/comp.lang.c++/Ila1Tn09mm4/nJVxl3SzpFUJ –

+0

धन्यवाद, यह इतना आसान और अच्छा विचार है। – user152508

11

एक नया C++ में प्रतिबिंब प्रदान करने के लिए एक पूरी तरह से अलग दृष्टिकोण का उपयोग कर परियोजना है: शिविरhttps://github.com/tegesoft/camp

सीएएमपी प्रीकंपेलर, वर्ग/गुण/फ़ंक्शंस/का उपयोग नहीं करता है ... boost.python या luabind के समान सिंटैक्स का उपयोग करके मैन्युअल रूप से घोषित किया जाता है। बेशक, अगर लोग पसंद करते हैं तो लोग इस घोषणा को उत्पन्न करने के लिए gccxml या open-C++ जैसे प्रीकंपेलर का उपयोग कर सकते हैं।

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

यह एमआईटी लाइसेंस (पहले एलजीपीएल) के तहत वितरित किया जाता है।

+2

इसे फोर्क किया गया है और [पंडर के रूप में जारी रखा गया है] (http://billyquith.github.io/ponder/) – Nick

3

थोड़ी देर के लिए यह भी देखा। वर्तमान सबसे आसान समाधान BOOST_FUSION_ADAPT_STRUCT प्रतीत होता है। व्यावहारिक रूप से आपके पास लाइब्रेरी/हेडर होने के बाद आपको केवल the last segment of the code shows के रूप में BOOST_FUSION_ADAPT_STRUCT() मैक्रो में अपने स्ट्रक्चर फ़ील्ड जोड़ने की आवश्यकता है। हां इसमें कई अन्य लोगों ने उल्लेख किया है। और यह श्रोताओं को सीधे समर्थन नहीं करता है।

अन्य होनहार समाधान मैं में देखा

  • शिविर और XRTTI/gccxml हैं, लेकिन दोनों अपने प्रोजेक्ट में बाहरी उपकरण निर्भरता को लाने के लिए एक बाधा होने लगते हैं।
  • साल पहले मैंने gcc -gstabs के आउटपुट से मेटा जानकारी डंप करने के लिए perl c2ph/pstruct का उपयोग किया था, जो कम घुसपैठ करने वाला है लेकिन अधिक काम करने की आवश्यकता है, हालांकि यह मेरे लिए पूरी तरह से काम करता है।

बूस्ट/__ सीएक्सए दृष्टिकोण के संबंध में, एक बार जब आप सभी छोटे विवरणों को समझते हैं, तो जोड़ना/बदलना structs या फ़ील्ड बनाए रखना आसान है। हम वर्तमान में एपीआई को क्रमबद्ध करने और प्रबंधित ऑब्जेक्ट सेवा उपप्रणाली के लिए परिवहन/आरपीसी विवरण छुपाने के लिए डीबीस के शीर्ष पर एक कस्टम प्रकार बाध्यकारी परत बनाने के लिए इसका उपयोग करते हैं।

+0

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

+0

@sehe: जैसा कि आप देखते हैं कि फ़ील्ड प्रकार __cxa_demangle (टाइपिड (टी) .name() द्वारा मुद्रित हैं। बहुत ही शीर्ष स्तर सहित सभी संरचना प्रकारों और सरणी प्रकारों को मुद्रित करने के लिए स्ट्रक्चर डिकोडर और सरणी डिकोडर पर एक ही फ़ंक्शन लागू किया जा सकता है। यदि आपको लगता है कि जावा वीएम एक आंतरिक द्विआधारी सूची में सभी वर्गों/वस्तुओं की एक सूची रखता है, तो मेटा डेटा इस उदाहरण डंप लगभग उस स्तर पर है। उस निम्न स्तर की जानकारी (प्लस रनटाइम पता जानकारी) से, आपको फ़ील्ड तक पहुंचने के लिए कोड लिखना होगा (स्ट्रिंग या char [] प्रारूप में नामों से)। यह पूरी प्रतिबिंब तस्वीर का दूसरा आधा होगा। – minghua

+0

आह। तो, उत्तर का सबसे महत्वपूर्ण हिस्सा वास्तव में वहां नहीं है। हमम आश्चर्यजनक था। वैसे भी, मैं 'c2ph/pstruct' ** के लिए ** + 1 करूंगा। ओल्डस्कूल, लेकिन वास्तव में, ज्यादातर स्थानों में काम करेगा। __cxa * बिल्कुल पोर्टेबल नहीं है। और ADAPT_STRUCT दोनों बहुत प्रासंगिक नहीं हैं, काम करने में आसान हैं, और आसानी से स्वचालित नहीं हैं। यदि आप मैक्रोज़ का उपयोग कर रहे हैं, तो आप मैक्रोज़ को पूरी तरह से उपयोग कर सकते हैं (और बूस्ट या जीसीसी एबीआई पर निर्भर नहीं) – sehe

0

स्वचालित आत्मनिरीक्षण/प्रतिबिंब टूलकिट।क्यूटी की तरह मेटा कंपाइलर का उपयोग करें और मेटा जानकारी सीधे ऑब्जेक्ट फ़ाइलों में जोड़ना। उपयोग करने के लिए सहज ज्ञान युक्त। कोई बाहरी निर्भरता नहीं। यहां तक ​​कि स्वचालित रूप से std :: स्ट्रिंग को प्रतिबिंबित करने की अनुमति दें और फिर स्क्रिप्ट में इसका उपयोग करें। कृपया IDK

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