উইন্ডোজ হ্যান্ডেল কী?


153

উইন্ডোজের রিসোর্সগুলি নিয়ে আলোচনা করার সময় "হ্যান্ডেল" কী? তারা কিভাবে কাজ করে?

উত্তর:


167

এটি কোনও উত্সের জন্য একটি বিমূর্ত রেফারেন্স মান, প্রায়শই স্মৃতি বা একটি উন্মুক্ত ফাইল বা পাইপ।

যথাযথভাবে , উইন্ডোজে, (এবং সাধারণত কম্পিউটারে) একটি হ্যান্ডেল এমন বিমূর্ততা যা এপিআই ব্যবহারকারীর কাছ থেকে একটি আসল মেমরি ঠিকানা লুকিয়ে রাখে, সিস্টেমটিকে প্রোগ্রামে স্বচ্ছভাবে মেমরির পুনর্গঠন করতে দেয়। একটি হ্যান্ডেলটিকে পয়েন্টারে সমাধান করা মেমরিটিকে লক করে এবং হ্যান্ডেলটি ছেড়ে দেওয়া পয়েন্টারটিকে অকার্যকর করে দেয়। এক্ষেত্রে এটি পয়েন্টারগুলির একটি সারণিতে সূচক হিসাবে ভাবেন ... আপনি সিস্টেম এপিআই কলগুলির জন্য সূচকটি ব্যবহার করেন এবং সিস্টেমটি ইচ্ছায় টেবিলের পয়েন্টারটি পরিবর্তন করতে পারে।

বিকল্প হিসাবে একটি আসল পয়েন্টার হ্যান্ডেল হিসাবে দেওয়া যেতে পারে যখন এপিআই লেখক ইচ্ছে করে যে এপিআই-র ব্যবহারকারীকে ঠিকানাটি কী নির্দেশ করে তাতে নির্দিষ্ট করে দেওয়া হয়; এক্ষেত্রে এটি অবশ্যই বিবেচনা করা উচিত যে হ্যান্ডেলটি যে কোনও সময় পরিবর্তিত হতে পারে (এপিআই সংস্করণ থেকে সংস্করণে বা এমনকি কলটি থেকে কলটি কল থেকে হ্যান্ডেলটি ফিরে আসে) - হ্যান্ডেলটিকে তাই কেবল অস্বচ্ছ মান হিসাবে বিবেচনা করা উচিত শুধুমাত্র এপিআই-এর অর্থবহ ।

আমার যোগ করা উচিত যে কোনও আধুনিক অপারেটিং সিস্টেমে, তথাকথিত "রিয়েল পয়েন্টার" এখনও প্রক্রিয়ার ভার্চুয়াল মেমরি স্পেসে অস্বচ্ছ হ্যান্ডেলগুলি থাকে, যা O / S প্রক্রিয়াটির মধ্যে পয়েন্টারগুলিকে অকার্যকর না করে মেমরি পরিচালনা এবং পুনঃব্যবস্থা করতে সক্ষম করে ables ।


4
আমি সত্যিই দ্রুত প্রতিক্রিয়া প্রশংসা করি। দুর্ভাগ্যক্রমে, আমি মনে করি আমি এখনও পুরোপুরি বুঝতে পেরে একজন নবজাতকের খুব বেশি :-(
আল সি

4
আমার বর্ধিত উত্তর কি কোনও আলো ফেলবে?
লরেন্স ডল

100

HANDLEএকটি প্রসঙ্গ-নির্দিষ্ট অনন্য শনাক্তকারী। প্রসঙ্গ-নির্দিষ্ট করে বলতে গেলে, আমি বলতে চাইছি একটি প্রসঙ্গ থেকে প্রাপ্ত একটি হ্যান্ডেল অগত্যা অন্য কোনও অ্যাব্রিট্রি প্রসঙ্গে ব্যবহার করা যাবে না যা এটিতেও কাজ করে HANDLE

উদাহরণস্বরূপ, GetModuleHandleবর্তমানে লোড হওয়া মডিউলে একটি অনন্য শনাক্তকারীকে ফেরত দেয়। ফিরে আসা হ্যান্ডেলটি অন্যান্য ফাংশনগুলিতে ব্যবহার করা যেতে পারে যা মডিউল হ্যান্ডেলগুলি গ্রহণ করে। এটি এমন ফাংশনগুলিতে দেওয়া যায় না যা অন্যান্য ধরণের হ্যান্ডলগুলি প্রয়োজন। উদাহরণস্বরূপ, যদি আপনি একটি হ্যান্ডল থেকে ফিরিয়ে দেওয়া না দিতে পারে GetModuleHandleথেকে HeapDestroyএবং এটি কিছু যুক্তিসম্মত করতে আশা।

HANDLEনিজেই ঠিক অবিচ্ছেদ্য প্রকার। সাধারণত, তবে অগত্যা নয়, এটি কিছু অন্তর্নিহিত টাইপ বা মেমরির অবস্থানের জন্য একটি পয়েন্টার। উদাহরণস্বরূপ, HANDLEফিরে GetModuleHandleআসাটি আসলে মডিউলটির বেস ভার্চুয়াল মেমরি ঠিকানার পয়েন্টার। তবে হ্যান্ডলগুলি পয়েন্টার হতে হবে বলে উল্লেখ করার কোনও নিয়ম নেই। একটি হ্যান্ডেলটি কেবল একটি সাধারণ পূর্ণসংখ্যা হতে পারে (যা সম্ভবত কিছু উইন 32 এপিআই ব্যবহার করতে পারে একটি অ্যারেতে সূচক হিসাবে)।

HANDLEগুলি ইচ্ছাকৃত অস্বচ্ছ উপস্থাপনা যা অভ্যন্তরীণ উইন 32 সংস্থান থেকে এনক্যাপসুলেশন এবং বিমূর্ততা সরবরাহ করে। এইভাবে, উইন 32 এপিআইগুলি কোনওভাবেই হ্যান্ডল এর ​​পিছনে অন্তর্নিহিত প্রকারটি পরিবর্তন করতে পারে, এটি কোনওভাবে ব্যবহারকারীর কোডকে প্রভাবিত না করে (কমপক্ষে এটি ধারণা)।

আমি সবেমাত্র তৈরি একটি উইন 32 এপিআইয়ের এই তিনটি পৃথক অভ্যন্তরীণ বাস্তবায়ন বিবেচনা করুন এবং ধরে নিন যে 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। এর বেশ কয়েকটি পরিণতি ঘটেছে:

  • ব্যবহারকারী কোড হেডার ফাইল সংজ্ঞায়িত অ্যাক্সেস থাকতে হবে Widgetstruct হয়
  • ব্যবহারকারীর কোডটি সম্ভাব্যভাবে ফিরে আসা Widgetকাঠামোর অভ্যন্তরীণ অংশগুলি সংশোধন করতে পারে

এই উভয় পরিণতি অনাকাঙ্ক্ষিত হতে পারে।

দ্বিতীয় উদাহরণটি কেবলমাত্র ফিরে এসে ব্যবহারকারীর কোড থেকে এই অভ্যন্তরীণ বিবরণটি গোপন করে void *। ব্যবহারকারীর Widgetকোডটির শিরোনামটিতে স্ট্রাকটি সংজ্ঞায়িত করার প্রয়োজন নেই ।

তৃতীয় উদাহরণটি হ'ল দ্বিতীয়টির মতো, তবে আমরা কেবল void *একটি HANDLEপরিবর্তে কল করি । সম্ভবত এটি ব্যবহারকারী কোডগুলিকে ঠিক কী void *পয়েন্টগুলি বোঝায় তা নিরুৎসাহিত করে।

কেন এই ঝামেলা পার? এই একই API এর নতুন সংস্করণের এই চতুর্থ উদাহরণটি বিবেচনা করুন:

typedef void * HANDLE;

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

    w = findImprovedWidget(name);

    return reinterpret_cast<HANDLE>(w);
}

লক্ষ্য করুন যে ফাংশনটির ইন্টারফেসটি উপরের তৃতীয় উদাহরণের মতো। এর অর্থ এই যে ব্যবহারকারীর কোড কোনও পরিবর্তন ছাড়াই এপিআইয়ের এই নতুন সংস্করণটি ব্যবহার করা চালিয়ে যেতে পারে, যদিও "পর্দার অন্তরালে" প্রয়োগটি NewImprovedWidgetপরিবর্তে কাঠামো ব্যবহার করতে পরিবর্তিত হয়েছে ।

এই উদাহরণগুলির মধ্যে হ্যান্ডলগুলি আসলেই একটি নতুন, সম্ভবত বন্ধুত্বপূর্ণ void *, যার নাম HANDLEউইন 32 এপিআইতে রয়েছে ( এমএসডিএন এ দেখুন ) really এটি ব্যবহারকারীর কোড এবং উইন 32 লাইব্রেরির অভ্যন্তরীণ উপস্থাপনার মধ্যে একটি অস্বচ্ছ প্রাচীর সরবরাহ করে যা উইন্ডোজের সংস্করণগুলির মধ্যে, উইন 32 এপিআই ব্যবহার করে এমন কোডের, যা বহনযোগ্যতা বৃদ্ধি করে।


5
ইচ্ছাকৃত বা না, আপনি ঠিক বলেছেন - ধারণাটি অবশ্যই অস্বচ্ছ (কমপক্ষে আমার কাছে :-)
আল সি

5
আমি কিছু দৃ answer় উদাহরণ সহ আমার মূল উত্তরটি প্রসারিত করেছি। আশা করি এর ধারণাটি কিছুটা স্বচ্ছ হয়ে উঠবে।
ড্যান মোল্ডিং

2
খুব সহায়ক সম্প্রসারণ ... ধন্যবাদ!
আল সি

4
আমি কিছুক্ষণের মধ্যে দেখেছি এমন কোনও প্রশ্নের উত্তর সবচেয়ে পরিষ্কার, প্রত্যক্ষ এবং সর্বাধিক লিখিত জবাব হতে হবে। এটি লেখার জন্য সময় দেওয়ার জন্য আন্তরিকভাবে আপনাকে ধন্যবাদ!
অ্যান্ড্রু

@DanMoulding: তাই প্রধান কারণ ব্যবহার করতে handleপরিবর্তে void *হয় ঠিক কি অকার্যকর * পয়েন্ট চিন্তা করার চেষ্টা থেকে নিরুৎসাহিত ব্যবহারকারী কোড । আমি কি সঠিক?
সিংহ লাই

37

উইন 32 প্রোগ্রামিংয়ের একটি হ্যান্ডেল এমন একটি টোকেন যা উইন্ডোজ কার্নেল দ্বারা পরিচালিত এমন একটি সংস্থানকে উপস্থাপন করে। একটি হ্যান্ডেল উইন্ডো, একটি ফাইল ইত্যাদির হতে পারে etc.

হ্যান্ডলগুলি হ'ল উইন 32 এপিআইগুলি ব্যবহার করে আপনি যে কণাগুলি তৈরি করতে চান তা চিহ্নিত করার একটি উপায়।

সুতরাং উদাহরণস্বরূপ, আপনি যদি উইন্ডো তৈরি করতে চান এবং এটি স্ক্রিনে প্রদর্শন করতে চান তবে নিম্নলিখিতগুলি করতে পারেন:

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

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

উপরের উদাহরণে এইচডাব্লুএনডি অর্থ "উইন্ডোতে একটি হ্যান্ডেল"।

যদি আপনি কোনও অবজেক্ট ওরিয়েন্টেড ল্যাঙ্গুয়েজে অভ্যস্ত হন তবে আপনি একটি হ্যান্ডেলকে এমন কোনও শ্রেণীর উদাহরণ হিসাবে ভাবতে পারেন যার কোনও পদ্ধতি নেই যার রাজ্যটি কেবল অন্য ফাংশন দ্বারা পরিবর্তনযোগ্য। এই ক্ষেত্রে শো উইন্ডো ফাংশনটি উইন্ডো হ্যান্ডেলের স্থিতি পরিবর্তন করে।

দেখুন পরিচালনা ও ডেটা প্রকার আরও তথ্যের জন্য।


HANDLEADT এর মাধ্যমে রেফারেন্সযুক্ত অবজেক্টগুলি কার্নেল দ্বারা পরিচালিত হয়। অন্যদিকে আপনি যে হ্যান্ডেল প্রকারের নাম ( HWNDইত্যাদি) রাখেন সেগুলি হ'ল USER অবজেক্ট। এগুলি উইন্ডোজ কার্নেল দ্বারা পরিচালিত হয় না।
IInspectable

1
@Inspectable অনুমান যে এগুলি ব্যবহারকারী 32.dll স্টাফ দ্বারা পরিচালিত হয়?
the_endian

8

একটি হ্যান্ডেল উইন্ডোজ দ্বারা পরিচালিত কোনও সামগ্রীর জন্য একটি অনন্য শনাক্তকারী। এটি একটি পয়েন্টারের মতো , তবে এটি কোনও নির্দেশকের মতো নয় যে এটি কোনও ঠিকানা নয় যা ব্যবহারকারীর কোড দ্বারা কিছু ডেটাতে অ্যাক্সেস পাওয়ার জন্য বিবেচিত হতে পারে। পরিবর্তে একটি হ্যান্ডেল হ'ল হ্যান্ডেল সনাক্ত করে এমন বস্তুর ক্রিয়া সম্পাদন করতে পারে এমন ফাংশনগুলির একটি সংকেতে প্রেরণ করতে হবে।


5

সুতরাং সবচেয়ে বেসিক স্তরে যে কোনও ধরণের হ্যান্ডল হ'ল একটি পয়েন্টারকে নির্দেশক বা

#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 করার জন্য, মুদ্রণকারীটি 1 এর মূল মানটি মুদ্রণ করবে।

এখন আমরা যদি foo এ আপডেট করি:

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

এমন একটি সম্ভাবনা রয়েছে যা প্রিন্টফ 2 এর আপডেট হওয়া মানটি মুদ্রণ করবে তবে এমনও সম্ভাবনা রয়েছে যে ফু কিছুভাবে মেমরির দুর্নীতি বা ব্যতিক্রম ঘটায়।

কারণ আপনি যখন এখন 2 মেগা মেমরি বরাদ্দ করছেন সেই ফাংশনে আপত্তি পাস করার জন্য একটি পয়েন্টার ব্যবহার করছেন, এটি ওএসকে আপত্তিটির অবস্থান আপডেট করার জন্য মেমরিটিকে সরিয়ে ফেলতে পারে। যেহেতু আপনি মান দ্বারা পয়েন্টারটি পাস করেছেন, যদি আপত্তিটি সরানো হয় তবে ওএস পয়েন্টারটি আপডেট করে তবে ফাংশনে থাকা অনুলিপিটি না করে এবং সম্ভাব্য সমস্যা তৈরি করে।

এর চূড়ান্ত আপডেটের জন্য:

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

এটি সর্বদা আপডেট হওয়া মানটি মুদ্রণ করবে।

দেখুন, যখন সংকলক পয়েন্টারগুলির জন্য মেমরি বরাদ্দ করে এটি এগুলি স্থাবর হিসাবে চিহ্নিত করে, সুতরাং ফাংশনে পাস করা মান বরাদ্দ করা বড় অবজেক্টের কারণে মেমরির কোনও পুনর্বিবেচনা স্মৃতিতে চূড়ান্ত অবস্থানটি সন্ধানের জন্য সঠিক ঠিকানায় নির্দেশ করবে হালনাগাদ.

যে কোনও বিশেষ ধরণের হ্যান্ডেল (hWnd, ফাইল, ইত্যাদি) ডোমেইন নির্দিষ্ট এবং স্মৃতি দুর্নীতির বিরুদ্ধে সুরক্ষার জন্য নির্দিষ্ট ধরণের কাঠামোর দিকে নির্দেশ করে।


1
এটি ত্রুটিযুক্ত যুক্তি; সি মেমরি বরাদ্দ সাবসিস্টেমটি ইচ্ছেমতো পয়েন্টারকে অবৈধ করতে পারে না। অন্যথায় কোনও সি বা সি ++ প্রোগ্রাম কখনও কার্যকরভাবে সঠিক হতে পারে না; আরও জটিলতর কোনও জটিলতার সংজ্ঞাটি যথাযথভাবে ভুল হবে। তদুপরি, ডাবল ইন্ডিয়ারেশন সাহায্য করবে না যদি সরাসরি নির্দেশিত মেমরিটি প্রোগ্রামের নীচে চারদিকে সরানো হয় যদি না পয়েন্টারটি প্রকৃত মেমরি থেকে নিজেকে বিমূর্ত করে তোলে - যা এটি একটি হ্যান্ডেল হিসাবে তৈরি করে
লরেন্স ডল

1
ম্যাকিনটোস অপারেটিং সিস্টেম (9 বা 8 অবধি সংস্করণে) উপরের ঠিক মতো করেছে। যদি আপনি কোনও সিস্টেম অবজেক্ট বরাদ্দ করেন তবে আপনি প্রায়শই এটিতে একটি হ্যান্ডেল পাবেন, ওএসকে অবজেক্টের চারপাশে সরিয়ে ফ্রি করে রেখে। প্রথম ম্যাকের সীমিত মেমরির আকারের সাথে যা গুরুত্বপূর্ণ ছিল।
রিয়াল্তো

5

একটি হ্যান্ডেল একটি ডাটাবেসে রেকর্ডের প্রাথমিক কী মানের মতো।

সম্পাদনা 1: ভাল, ডাউন ডাউনটি কেন, একটি প্রাথমিক কী অনন্যভাবে একটি ডাটাবেস রেকর্ড সনাক্ত করে এবং উইন্ডোজ সিস্টেমের একটি হ্যান্ডেল একটি উইন্ডো, একটি খোলা ফাইল, ইত্যাদি স্বতন্ত্রভাবে চিহ্নিত করে, আমি যা বলছি তা তাই।


1
আপনি কল্পনা করতে পারবেন না যে আপনি হ্যান্ডেলটি অনন্য। এটি কোনও ব্যবহারকারীর উইন্ডোজ স্টেশন প্রতি অনন্য হতে পারে, তবে একই সময়ে একই সিস্টেমে একাধিক ব্যবহারকারী অ্যাক্সেস করা থাকলে এটি অনন্য হওয়ার নিশ্চয়তা নেই। অর্থাত, একাধিক ব্যবহারকারী একটি হ্যান্ডেল মান ফিরে পেতে পারে যা সংখ্যার সাথে অভিন্ন, তবে ব্যবহারকারীর উইন্ডোজ স্টেশন প্রসঙ্গে তারা বিভিন্ন জিনিসকে মানচিত্র করে ...
নিক

2
@ নিক এটি প্রদত্ত প্রসঙ্গে অনন্য। একটি প্রাথমিক কীটি বিভিন্ন টেবিলের মধ্যে অনন্য হতে পারে না ...
বেনি ম্যাকনি

2

উইন্ডোটির উইন্ডোটিকে এমন স্ট্রাক হিসাবে বর্ণনা করুন যা এটি বর্ণনা করে। এই কাঠামোটি উইন্ডোজের অভ্যন্তরীণ অংশ এবং এটির বিশদ জানার দরকার নেই। পরিবর্তে, উইন্ডোজ সেই স্ট্রাক্টের জন্য পয়েন্টার গঠনের জন্য টাইপিডেফ সরবরাহ করে। এটি "হ্যান্ডেল" যার দ্বারা আপনি উইন্ডোতে ধরে রাখতে পারেন,


সত্য, তবে এটি সর্বদা স্মরণযোগ্য যে হ্যান্ডেলটি সাধারণত কোনও মেমরি ঠিকানা হয় না এবং একটি ব্যবহারকারীর কোডটি এটির অবহেলা করা উচিত নয়।
শার্পটোথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.