windows विंडोज हैंडल क्या है?




handle (7)

विंडोज़ में संसाधनों पर चर्चा करते समय "हैंडल" क्या है? वो कैसे काम करते है?


यह संसाधन के लिए एक सार संदर्भ मान है, अक्सर स्मृति या खुली फ़ाइल, या एक पाइप।

ठीक है , विंडोज़ में, (और आमतौर पर कंप्यूटिंग में) एक हैंडल एक अमूर्त है जो एपीआई उपयोगकर्ता से वास्तविक मेमोरी एड्रेस छुपाता है, जिससे सिस्टम को भौतिक मेमोरी को पारदर्शी रूप से प्रोग्राम में पुनर्गठित करने की इजाजत मिलती है। एक सूचक में एक हैंडल को हल करने से स्मृति को ताला लगा दिया जाता है, और हैंडल को रिहा करने से पॉइंटर को अमान्य कर दिया जाता है। इस मामले में इसे पॉइंटर्स की एक तालिका में एक इंडेक्स के रूप में सोचें ... आप सिस्टम एपीआई कॉल के लिए इंडेक्स का उपयोग करते हैं, और सिस्टम इच्छा में तालिका में पॉइंटर बदल सकता है।

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

मुझे यह भी जोड़ना चाहिए कि किसी भी आधुनिक ऑपरेटिंग सिस्टम में, तथाकथित "वास्तविक पॉइंटर्स" अभी भी प्रक्रिया के वर्चुअल मेमोरी स्पेस में अपारदर्शी हैंडल हैं, जो ओ / एस को प्रक्रिया के भीतर पॉइंटर्स को अमान्य किए बिना स्मृति को प्रबंधित और पुनर्व्यवस्थित करने में सक्षम बनाता है ।


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


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


Win32 प्रोग्रामिंग में एक हैंडल एक टोकन है जो Windows कर्नेल द्वारा प्रबंधित संसाधन का प्रतिनिधित्व करता है। एक हैंडल खिड़की, एक फाइल, आदि के लिए हो सकता है

हैंडल केवल एक कण संसाधन की पहचान करने का एक तरीका है जिसे आप Win32 एपीआई का उपयोग करके काम करना चाहते हैं।

तो उदाहरण के लिए, यदि आप एक विंडो बनाना चाहते हैं, और इसे स्क्रीन पर दिखाएं तो आप निम्न कार्य कर सकते हैं:

// Create the window
HWND hwnd = CreateWindow(...); 
if (!hwnd)
   return; // hwnd not created

// Show the window.
ShowWindow(hwnd, SW_SHOW);

उपरोक्त उदाहरण में एचडब्ल्यूएनडी का मतलब है "एक खिड़की के लिए एक हैंडल"।

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

अधिक जानकारी के लिए हैंडल और डेटा प्रकार देखें।


तो सबसे बुनियादी स्तर पर किसी भी प्रकार का हैंडल पॉइंटर या पॉइंटर होता है

#define HANDLE void **

अब आप इसका उपयोग क्यों करना चाहते हैं

चलिए एक सेटअप लेते हैं:

class Object{
   int Value;
}

class LargeObj{

   char * val;
   LargeObj()
   {
      val = malloc(2048 * 1000);
   }

}

void foo(Object bar){
    LargeObj lo = new LargeObj();
    bar.Value++;
}

void main()
{
   Object obj = new Object();
   obj.val = 1;
   foo(obj);
   printf("%d", obj.val);
}

इसलिए क्योंकि ओबीजे मूल्य से पारित किया गया था (एक प्रतिलिपि बनाएं और इसे फ़ंक्शन पर दें) foo करने के लिए, printf 1 के मूल मान को प्रिंट करेगा।

अब अगर हम foo को अपडेट करते हैं:

void foo(Object * bar)
{
    LargeObj lo = new LargeObj();
    bar->val++;
}

एक मौका है कि printf 2 के अद्यतन मूल्य को प्रिंट करेगा। लेकिन यह भी संभावना है कि foo स्मृति भ्रष्टाचार या अपवाद के कुछ रूपों का कारण बन जाएगा।

इसका कारण यह है कि अब आप फ़ंक्शन पर ओबीजे पास करने के लिए पॉइंटर का उपयोग कर रहे हैं, आप 2 मेगाहर्ट्ज मेमोरी आवंटित कर रहे हैं, इससे ओएस ओबीजे के स्थान को अपडेट करने के लिए स्मृति को स्थानांतरित कर सकता है। चूंकि आपने पॉइंटर को मूल्य से पारित कर दिया है, यदि ओबीजे स्थानांतरित हो जाता है तो ओएस पॉइंटर को अपडेट करता है लेकिन फ़ंक्शन में कॉपी नहीं करता है और संभावित रूप से समस्याएं पैदा करता है।

के लिए अंतिम अद्यतन:

void foo(Object **bar){
    LargeObj lo = LargeObj();
    Object * b = &bar;
    b->val++;
}

यह हमेशा अद्यतन मूल्य मुद्रित करेगा।

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

किसी विशेष प्रकार के हैंडल (एचडब्ल्यूएनडी, फाइल, इत्यादि) डोमेन विशिष्ट हैं और स्मृति भ्रष्टाचार के खिलाफ सुरक्षा के लिए एक निश्चित प्रकार की संरचना को इंगित करते हैं।


एक HANDLE एक संदर्भ-विशिष्ट अद्वितीय पहचानकर्ता है। संदर्भ-विशिष्ट से, मेरा मतलब है कि एक संदर्भ से प्राप्त एक हैंडल का उपयोग किसी भी अन्य अत्याधुनिक संदर्भ में नहीं किया जा सकता है जो HANDLE पर भी काम करता है।

उदाहरण के लिए, GetModuleHandle वर्तमान में लोड किए गए मॉड्यूल के लिए एक अद्वितीय पहचानकर्ता देता है। लौटा हुआ हैंडल अन्य कार्यों में उपयोग किया जा सकता है जो मॉड्यूल हैंडल स्वीकार करते हैं। यह उन कार्यों को नहीं दिया जा सकता है जिनके लिए अन्य प्रकार के हैंडल की आवश्यकता होती है। उदाहरण के लिए, आप GetModuleHandle से GetModuleHandle तक लौटाए गए हैंडल नहीं दे HeapDestroy और उम्मीद करते हैं कि यह कुछ समझदार हो।

HANDLE स्वयं ही एक अभिन्न प्रकार है। आमतौर पर, लेकिन जरूरी नहीं, यह कुछ अंतर्निहित प्रकार या स्मृति स्थान के लिए एक सूचक है। उदाहरण के लिए, GetModuleHandle द्वारा लौटा गया HANDLE वास्तव में मॉड्यूल के मूल वर्चुअल मेमोरी एड्रेस के लिए एक सूचक है। लेकिन कोई नियम नहीं है कि हैंडल पॉइंटर्स होना चाहिए। एक हैंडल भी एक साधारण पूर्णांक हो सकता है (जिसे संभवतः कुछ Win32 एपीआई द्वारा एक सरणी में इंडेक्स के रूप में उपयोग किया जा सकता है)।

HANDLE जानबूझकर अपारदर्शी प्रतिनिधित्व हैं जो आंतरिक Win32 संसाधनों से encapsulation और abstraction प्रदान करते हैं। इस तरह, Win32 एपीआई किसी भी तरह से उपयोगकर्ता कोड को प्रभावित किए बिना अंतर्निहित प्रकार को एक हैंडल के पीछे बदल सकता है (कम से कम यह विचार है)।

Win32 एपीआई के इन तीन अलग-अलग आंतरिक कार्यान्वयन पर विचार करें जो मैंने अभी बनाया है, और मान लें कि Widget एक struct

Widget * GetWidget (std::string name)
{
    Widget *w;

    w = findWidget(name);

    return w;
}
void * GetWidget (std::string name)
{
    Widget *w;

    w = findWidget(name);

    return reinterpret_cast<void *>(w);
}
typedef void * HANDLE;

HANDLE GetWidget (std::string name)
{
    Widget *w;

    w = findWidget(name);

    return reinterpret_cast<HANDLE>(w);
}

पहला उदाहरण एपीआई के बारे में आंतरिक विवरण का खुलासा करता है: यह उपयोगकर्ता कोड को यह जानने की अनुमति देता है कि GetWidget एक struct Widget पॉइंटर लौटाता है। इसके कुछ परिणाम हैं:

  • उपयोगकर्ता कोड में हेडर फ़ाइल तक पहुंच होनी चाहिए जो Widget स्ट्रक्चर को परिभाषित करता है
  • उपयोगकर्ता कोड संभावित रूप से लौटा Widget संरचना के आंतरिक भागों को संशोधित कर सकता है

इन दोनों परिणामों को अवांछनीय हो सकता है।

दूसरा उदाहरण उपयोगकर्ता कोड से इस आंतरिक विवरण को छुपाता है, केवल void * लौटकर। उपयोगकर्ता कोड को हेडर तक पहुंच की आवश्यकता नहीं है जो Widget स्ट्रक्चर को परिभाषित करता है।

तीसरा उदाहरण बिल्कुल दूसरे जैसा ही है, लेकिन हम इसके बजाय void * एक HANDLE कॉल करते हैं। शायद यह उपयोगकर्ता कोड को void * बिंदुओं के बारे में पता लगाने की कोशिश करने से हतोत्साहित करता है।

इस परेशानी के माध्यम से क्यों जाना है? इस एपीआई के एक नए संस्करण के इस चौथे उदाहरण पर विचार करें:

typedef void * HANDLE;

HANDLE GetWidget (std::string name)
{
    NewImprovedWidget *w;

    w = findImprovedWidget(name);

    return reinterpret_cast<HANDLE>(w);
}

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

इन उदाहरणों में हैंडल वास्तव में सिर्फ एक नया, संभवतः मित्रवत है, void * लिए नाम है, जो Win32 API में एक HANDLE है (इसे एमएसडीएन पर देखें )। यह उपयोगकर्ता कोड और Win32 लाइब्रेरी के आंतरिक प्रतिनिधित्वों के बीच एक अपारदर्शी दीवार प्रदान करता है जो Win32 API का उपयोग करने वाले कोड के विंडोज़ के संस्करणों के बीच पोर्टेबिलिटी बढ़ाता है।


एक ऑब्जेक्ट एक डेटा संरचना है जो एक सिस्टम संसाधन, जैसे कि फ़ाइल, थ्रेड या ग्राफ़िक छवि का प्रतिनिधित्व करती है। कोई ऑब्जेक्ट सीधे ऑब्जेक्ट डेटा या सिस्टम संसाधन का उपयोग नहीं कर सकता है जो ऑब्जेक्ट का प्रतिनिधित्व करता है। इसके बजाए, किसी एप्लिकेशन को ऑब्जेक्ट हैंडल प्राप्त करना होगा, जिसका उपयोग सिस्टम संसाधन की जांच या संशोधित करने के लिए किया जा सकता है। प्रत्येक हैंडल में आंतरिक रूप से रखी गई तालिका में प्रवेश होता है। इन प्रविष्टियों में संसाधनों के पते और संसाधन प्रकार की पहचान करने के साधन शामिल हैं।





handle