2009-04-22 4 views
6

मैं ऐसा कुछ कैसे कर सकता हूं (केवल एक उदाहरण):सी में संरचनाओं को गतिशील रूप से कैसे बनाएं और पढ़ें?

any_struct *my_struct = create_struct(); 
add_struct_member(my_struct, "a", int_member); 
add_struct_member(my_struct, "b", float_member); 

ताकि मैं यहां दिए गए ढांचे के साथ "बाहर से" (पता addressOfMyStruct पर) एक संरचना उदाहरण लोड और उपयोग कर सकता हूं?

any_struct_instance *instance = instance(my_struct, addressOfMyStruct); 
int a = instance_get_member(instance, "a"); 
float b = instance_get_member(instance, "b"); 

मैं इस तरह से संरचनात्मक उदाहरणों को गतिशील रूप से बनाने में सक्षम होना चाहूंगा।

मुझे उम्मीद है कि यह स्पष्ट है कि मैं क्या करना चाहता हूं। मुझे पता है कि C/Invoke ऐसा करने में सक्षम है, लेकिन क्या ऐसा करने के लिए एक अलग पुस्तकालय है?

+0

वैसे, एपीआई सिर्फ एक उदाहरण था। यह बिल्कुल एक ही एपीआई होने की आवश्यकता नहीं है। – user94405

उत्तर

6

वास्तव में सी में यह काम करने के लिए कोड का प्रदर्शन करना एक एसओ पोस्ट के लिए थोड़ा सा शामिल है। लेकिन बुनियादी अवधारणा को समझना संभव है।

जो आप वास्तव में यहां बना रहे हैं वह एक टेम्पलेटेड प्रॉपर्टी बैग सिस्टम है। यह एक चीज आपको इसे जारी रखने के लिए बहुत कुछ चाहिए, हैश टेबल की तरह कुछ आक्रामक संरचना है। मैं कहूंगा कि std :: map के साथ जाएं लेकिन आपने बताया कि यह एक सी समाधान था। चर्चा के लिए मैं सिर्फ यह मानने जा रहा हूं कि आपके पास कुछ प्रकार का हैशटेबल उपलब्ध है।

"create_struct" कॉल को उस संरचना को वापस करने की आवश्यकता होगी जिसमें हैशटेबल में पॉइंटर होता है जो const char* को अनिवार्य रूप से आकार_टी बनाता है। यह नक्शा संरचना का एक नया उदाहरण बनाने के लिए आपको जो चाहिए उसे परिभाषित करता है।

"बीमा" विधि अनिवार्य रूप से टेम्पलेट हैशटेबल के समान सदस्यों के साथ एक नया हैशटेबल तैयार करेगी। चलो एक सेकंड के लिए खिड़की से आलसी evalation फेंक देते हैं और मानते हैं कि आप सभी सदस्यों को सामने बनाते हैं। विधि को प्रत्येक प्रविष्टि के लिए एक सदस्य जोड़ने और निर्दिष्ट आकार के स्मृति खंड को mallocing करने के लिए टेम्पलेट हैशटेबल पर लूप की आवश्यकता होगी।

instance_get_member का कार्यान्वयन बस नाम से मानचित्र में एक लुकअप करेगा। यद्यपि हस्ताक्षर और उपयोग पैटर्न को बदलने की आवश्यकता होगी हालांकि। सी टेम्पलेट का समर्थन नहीं करता है और एक सामान्य रिटर्न प्रकार चुनना चाहिए जो सभी डेटा का प्रतिनिधित्व कर सकता है। इस मामले में आपको void* चुनना होगा क्योंकि स्मृति को संग्रहीत करने की आवश्यकता होगी।

void* instance_get_member(any_struct_instance* inst, const char* name); 

आप टेम्पलेट्स

#define instance_get_member2(inst, name, type) \ 
    *((type*)instance_get_member((inst),(name))) 
... 
int i = instance_get_member2(pInst,"a", int); 
+0

धन्यवाद, यह इतना कठिन नहीं लगता है। हालांकि, क्या यह संभव है कि मैं पैडिंग या उसके जैसा कुछ मुद्दों पर ठोकर खाऊं? – user94405

+0

@frw, आपको ऐसा नहीं करना चाहिए क्योंकि आप संरचना डेटा के लिए स्थान आवंटित करने के लिए मॉलोक का उपयोग कर रहे हैं। चूंकि इसे एक शब्दकोश में संग्रहीत किया जाता है, इसलिए प्रति सदस्य एक आवंटन होना चाहिए। पैडिंग मुद्दे केवल वास्तव में आते हैं यदि आप स्मृति के एक संगत ब्लॉक में उन्हें पैडिंग कर रहे हैं। आप उस दृष्टिकोण को ले सकते हैं, हालांकि मैं इसे टालना चाहूंगा, विशेष रूप से पैकिंग कारणों के कारण;) – JaredPar

+0

ठीक है, मैं पैकिंग के बारे में कुछ पढ़ूंगा और देखें कि मैं क्या करने जा रहा हूं। हालांकि, सी/Invoke का उपयोग करना सबसे आसान समाधान होगा। अभी के लिए धन्यवाद! – user94405

1

आप अब तक हो गई समस्या यह है कि सब अब सिर्फ़ को परिभाषित किया है अनुकरण करने के लिए एक envil मैक्रो जोड़कर इस थोड़ा बेहतर बना सकते का एक सा (थोड़ा में मुश्किल है कुछ भागों) कार्यान्वयन। तुम सिर्फ जानकारी का ट्रैक रखने की जरूरत है:

typedef struct { 
    fieldType type; 
    char  name[NAMEMAX]; 
    /* anything else */ 
} meta_struct_field; 
typedef struct { 
    unsigned   num_fields; 
    meta_struct_field *fields; 
    /* anything else */ 
} meta_struct; 

फिर create_struct()meta_struct के लिए स्मृति आवंटित करता है और 0 के लिए यह प्रारंभ, और add_struct_member()my_struct.fields और वेतन वृद्धि my_struct.num_fields पर एक alloc()/realloc() करता है। बाकी एक ही नस में पीछा करते हैं।

आप meta_struct_field में उदाहरणों में वास्तविक मान रखने के लिए भी union चाहते हैं।

0

मैंने कुछ समय पहले ऐसा किया था।

जिस तरह से मैंने इसे परिभाषित किया था, जिसमें संरचना परिभाषा युक्त कोड उत्पन्न करना था, साथ ही इसे एक्सेस करने के लिए सभी दिनचर्याएं और फिर इसे "फ्लाई पर" डीएलएल में संकलित और लिंक करें, फिर उस डीएलएल को गतिशील रूप से लोड करें।

+0

दुर्भाग्य से मेरे लिए कोई विकल्प नहीं है। फिर भी धन्यवाद :) – user94405

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