लिनक्स कर्नेल में conatainer_of () मैक्रो -
जब कोड में कई डेटा संरचनाओं का प्रबंधन करने की बात आती है, तो आपको लगभग हमेशा एक संरचना को दूसरे में एम्बेड करने और किसी भी क्षण उन्हें पुनर्प्राप्त करने की आवश्यकता होगी, बिना मेमोरी ऑफ़सेट्स या सीमाओं के बारे में प्रश्न पूछे जाने पर। मान लें कि आपके पास एक संरचनात्मक व्यक्ति है, जैसा कि यहां परिभाषित किया गया है:
struct person {
int age;
int salary;
char *name;
} p;
केवल उम्र या वेतन पर एक पॉइंटर होने से, आप उस पॉइंटर को पूरी तरह से लपेटकर (युक्त) प्राप्त कर सकते हैं। जैसा कि नाम कहता है, कंटेनर_ऑफ मैक्रो का उपयोग किसी संरचना के दिए गए क्षेत्र के कंटेनर को खोजने के लिए किया जाता है। मैक्रो में शामिल / linux / kernel.h परिभाषित किया गया है और निम्नलिखित की तरह दिखता है:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
संकेत से डरो मत; बस उन्हें इस प्रकार देखें:
container_of(pointer, container_type, container_field);
यहां पूर्ववर्ती कोड टुकड़े के तत्व दिए गए हैं:
- पॉइंटर: यह संरचना में क्षेत्र का सूचक है
- कंटेनर_टाइप: यह पॉइंटर को लपेटने (युक्त) का प्रकार है
- कंटेनर_फील्ड: यह उस क्षेत्र का नाम है, जो संरचना के अंदर इंगित करता है
चलो निम्नलिखित कंटेनर पर विचार करें:
struct person {
int age;
int salary;
char *name;
};
अब, आइए, इसके एक उदाहरण पर विचार करें, साथ ही उम्र के सदस्य को एक संकेत दें:
struct person somebody;
[...]
int *age_ptr = &somebody.age;
नाम सदस्य (age_ptr) के लिए एक पॉइंटर के साथ, आप कंटेनर (मैक्रो) का उपयोग कर सकते हैं ताकि पूरी संरचना (कंटेनर) को एक पॉइंटर मिल सके जो इस सदस्य को निम्नलिखित का उपयोग करके लपेटता है:
struct person *the_person;
the_person = container_of(age_ptr, struct person, age);
कंटेनर_ऑफ सही पॉइंटर स्थान प्राप्त करने के लिए संरचना की शुरुआत में उम्र की भरपाई करता है। यदि आप सूचक age_ptr से फ़ील्ड आयु की ऑफ़सेट घटाते हैं, तो आपको सही स्थान मिलेगा। यह मैक्रो की अंतिम पंक्ति है:
(type *)( (char *)__mptr - offsetof(type,member) );
इसे एक वास्तविक उदाहरण पर लागू करना, निम्नलिखित देता है:
struct family {
struct person *father;
struct person *mother;
int number_of_sons;
int family_id;
} f;
[...]
int *fam_id_ptr = &f.family_id;
struct family *fam_ptr;
fam_ptr = container_of(fam_id_ptr, struct family, family_id);
कंटेनर_ऑफ मैक्रो का उपयोग मुख्य रूप से कर्नेल में जेनेरिक कंटेनरों में किया जाता है।
यह सब के बारे में कंटेनर_ऑफ मैक्रो कर्नेल में है।
rb_node
।