<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Windows API on kenji.blog</title><link>http://kenji.blog/hi/tags/windows-api/</link><description>Recent content in Windows API on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 06:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/tags/windows-api/index.xml" rel="self" type="application/rss+xml"/><item><title>आधुनिक C++ के साथ Windows API (Win32) को सुरक्षित और आधुनिक तरीके से संभालना</title><link>http://kenji.blog/hi/p/modern-cpp-win32-api-safe-handling/</link><pubDate>Sat, 12 Sep 2026 06:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/modern-cpp-win32-api-safe-handling/</guid><description>&lt;img src="http://kenji.blog/p/modern-cpp-win32-api-safe-handling/img/eyecatch.jpg" alt="Featured image of post आधुनिक C++ के साथ Windows API (Win32) को सुरक्षित और आधुनिक तरीके से संभालना" />&lt;h2 id="1-परचय-c-आधरत-win32-api-और-आधनक-c-क-बच-क-अतर">1. परिचय: C-आधारित Win32 API और आधुनिक C++ के बीच का अंतर
&lt;/h2>&lt;p>Windows OS का आधारभूत &lt;strong>Windows API (जिसे सामान्यतः Win32 API कहा जाता है)&lt;/strong> एक विशाल C भाषा इंटरफ़ेस है, जिसे 1990 के दशक में Windows NT और Windows 95 के युग से लगातार आगे बढ़ाया गया है। आज भी, Windows के लिए नेटिव एप्लिकेशन विकसित करते समय, OS के कोर फ़ंक्शंस (प्रोसेस प्रबंधन, फ़ाइल I/O, थ्रेड सिंक्रोनाइज़ेशन, विंडो नियंत्रण, आदि) तक पहुँचने के लिए अंततः इस Win32 API को कॉल करना आवश्यक है।&lt;/p>
&lt;p>हालाँकि, Win32 API को शुद्ध C भाषा के लिए डिज़ाइन किया गया था, और यह &lt;strong>आधुनिक C++ (Modern C++)&lt;/strong> की उन्नत भाषा विशेषताओं (जैसे अपवाद प्रबंधन, RAII के माध्यम से स्वचालित संसाधन प्रबंधन, मूव सिमेंटिक्स, टाइप-सेफ एन्यूमरेशन, और स्मार्ट पॉइंटर्स) को ध्यान में नहीं रखता है। परिणामस्वरूप, कच्चे Win32 API को सीधे C++ कोड के साथ मिलाने पर निम्नलिखित समस्याएँ उत्पन्न होती हैं:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>मैनुअल संसाधन प्रबंधन:&lt;/strong> &lt;code>CreateFile&lt;/code> या &lt;code>CreateEvent&lt;/code> से प्राप्त &lt;code>HANDLE&lt;/code> को हमेशा &lt;code>CloseHandle&lt;/code> का उपयोग करके रिलीज़ करना पड़ता है।&lt;/li>
&lt;li>&lt;strong>अपवाद सुरक्षा का अभाव:&lt;/strong> यदि C++ अपवाद (exception) फेंका जाता है और &lt;code>CloseHandle&lt;/code> को सही ढंग से कॉल करने के लिए कोड नहीं लिखा गया है, तो आसानी से संसाधन लीक (resource leak) हो सकता है।&lt;/li>
&lt;li>&lt;strong>असंगत त्रुटि प्रतिनिधित्व:&lt;/strong> कुछ API &lt;code>BOOL&lt;/code> लौटाते हैं और विफलता पर &lt;code>GetLastError()&lt;/code> को कॉल करने की आवश्यकता होती है। अन्य API &lt;code>HRESULT&lt;/code> लौटाते हैं, और कुछ अन्य (जैसे GDI) &lt;code>NULL&lt;/code> लौटाते हैं।&lt;/li>
&lt;li>&lt;strong>टाइप सुरक्षा की कमी:&lt;/strong> मैक्रोज़ के विस्तार के बाद &lt;code>HANDLE&lt;/code>, &lt;code>HWND&lt;/code>, &lt;code>HDC&lt;/code> आदि अक्सर केवल &lt;code>void*&lt;/code> बन जाते हैं, जिससे कंपाइलर द्वारा सख्त टाइप चेकिंग मुश्किल हो जाती है।&lt;/li>
&lt;/ul>
&lt;p>यह लेख इन &amp;ldquo;विरासत (legacy) C इंटरफेस&amp;rdquo; के जाल से बचने और आधुनिक C++ (C++11/14/17/20/23) की विशेषताओं का उपयोग करके &lt;strong>सुरक्षित (Safe) और आधुनिक (Modern) तरीके से Win32 API को संभालने की तकनीक&lt;/strong> के बारे में अत्यंत विस्तार से बताएगा।&lt;/p>
&lt;hr>
&lt;h2 id="2-कचच-win32-api-क-खतर-ससधन-लक-और-तरट-परबधन-क-जल">2. कच्चे Win32 API के खतरे: संसाधन लीक और त्रुटि प्रबंधन का जाल
&lt;/h2>&lt;p>सबसे पहले, आइए पुराने C-शैली के Win32 API कॉल्स वाले सामान्य कोड को देखें। पहली नज़र में यह ठीक लग सकता है, लेकिन आधुनिक C++ के दृष्टिकोण से इसमें गंभीर कमज़ोरियाँ हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;windows.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">ProcessFileLegacy&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">wstring&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">filename&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. फ़ाइल हैंडल प्राप्त करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">HANDLE&lt;/span> &lt;span class="n">hFile&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">::&lt;/span>&lt;span class="n">CreateFileW&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">filename&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c_str&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">GENERIC_READ&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">FILE_SHARE_READ&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">NULL&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">OPEN_EXISTING&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">FILE_ATTRIBUTE_NORMAL&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">NULL&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">INVALID_HANDLE_VALUE&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to open file. Error: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="o">::&lt;/span>&lt;span class="n">GetLastError&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 2. फ़ाइल का आकार प्राप्त करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">LARGE_INTEGER&lt;/span> &lt;span class="n">fileSize&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!::&lt;/span>&lt;span class="n">GetFileSizeEx&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">fileSize&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">CloseHandle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// त्रुटि होने पर मैनुअल रिलीज़
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3. मेमोरी आवंटन और पढ़ना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">buffer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">fileSize&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">QuadPart&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DWORD&lt;/span> &lt;span class="n">bytesRead&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!::&lt;/span>&lt;span class="n">ReadFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">buffer&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">buffer&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">bytesRead&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">NULL&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">CloseHandle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// त्रुटि होने पर मैनुअल रिलीज़
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// --- मान लें कि यहाँ कोई अपवाद (exception) फेंकने वाला कोड है ---
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// उदाहरण: बफ़र को पार्स करने वाला फ़ंक्शन जो std::runtime_error फेंकता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ParseBuffer(buffer); // यदि अपवाद फेंका जाता है, तो नीचे का CloseHandle कॉल नहीं होगा और लीक हो जाएगा!
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 4. संसाधन को मैनुअल रूप से रिलीज़ करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="o">::&lt;/span>&lt;span class="n">CloseHandle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="इस-कड-म-कय-समसय-ह">इस कोड में क्या समस्या है?
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>कोड का दोहराव और जटिलता:&lt;/strong> प्रत्येक अर्ली रिटर्न (&lt;code>return&lt;/code>) पर &lt;code>::CloseHandle(hFile);&lt;/code> लिखना पड़ता है, जो DRY (Don&amp;rsquo;t Repeat Yourself) सिद्धांत का उल्लंघन करता है।&lt;/li>
&lt;li>&lt;strong>अपवाद सुरक्षा का पूर्ण अभाव (Exception Unsafe):&lt;/strong> C++ में, यदि &lt;code>std::vector&lt;/code> का मेमोरी आवंटन विफल हो जाता है (&lt;code>std::bad_alloc&lt;/code>) या यदि कोई अन्य फ़ंक्शन अपवाद फेंकता है, तो फ़ंक्शन से जबरन बाहर निकलना पड़ता है। इस समय, अंत में मौजूद &lt;code>CloseHandle&lt;/code> निष्पादित नहीं होता है, इसलिए &lt;strong>फ़ाइल हैंडल हमेशा के लिए लीक हो जाता है&lt;/strong> (जिससे गंभीर बग उत्पन्न हो सकते हैं, जैसे प्रक्रिया समाप्त होने तक फ़ाइल का लॉक रहना)।&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="3-अपवद-सरकष-और-ससधन-परबधन-क-गणतय-मडल">3. अपवाद सुरक्षा और संसाधन प्रबंधन का गणितीय मॉडल
&lt;/h2>&lt;p>यहाँ, आइए गणितीय रूप से (प्रायिकता सिद्धांत का उपयोग करके) मॉडल करें कि मैन्युअल संसाधन प्रबंधन कितना कमज़ोर है।&lt;/p>
&lt;p>मान लें कि एक फ़ंक्शन में $N$ संसाधन आवंटन (या अर्ली रिटर्न पॉइंट, अपवाद बिंदु) हैं। प्रत्येक चरण $i$ में, त्रुटि या अपवाद के कारण फ़ंक्शन से बाहर निकलने की प्रायिकता $P(\text{Exit}_i)$ है। विचार करें कि सभी निकास मार्गों पर मैन्युअल रूप से क्लीनअप कोड (जैसे &lt;code>CloseHandle&lt;/code>) को सही ढंग से लिखने में विफलता के कारण संसाधन के लीक होने की प्रायिकता क्या है।&lt;/p>
&lt;p>मान लें कि मानवीय चूक या किसी अज्ञात अपवाद के कारण अप्रत्याशित निकास (प्रति निकास मार्ग लीक की प्रायिकता) की प्रायिकता $p$ है, तो पूरे प्रोग्राम में कम से कम एक संसाधन लीक होने की प्रायिकता $P(\text{Leak})$ को निम्नलिखित समीकरण द्वारा दर्शाया जा सकता है:&lt;/p>
$$ P(\text{Leak}) = 1 - (1 - p)^N $$
&lt;p>उदाहरण के लिए, यदि $p = 0.05$ (5% संभावना है कि आप अपवाद प्रबंधन या क्लीनअप कोड मिस कर देंगे) और $N = 20$ (एक जटिल फ़ंक्शन में 20 त्रुटि रिटर्न या अपवाद बिंदु हैं):&lt;/p>
$$ P(\text{Leak}) = 1 - (1 - 0.05)^{20} \approx 1 - 0.358 = 0.642 $$
&lt;p>आश्चर्यजनक रूप से, &lt;strong>लगभग 64.2% संभावना है कि कहीं न कहीं संसाधन लीक बग छिपा होगा&lt;/strong>। जैसे-जैसे सॉफ़्टवेयर का आकार बढ़ता है और $N \to \infty$ होता है, $P(\text{Leak}) \to 1$ हो जाता है, और सिस्टम अनिवार्य रूप से विफल हो जाएगा।&lt;/p>
&lt;p>इस गणितीय वास्तविकता का मुकाबला करने का एकमात्र तार्किक तरीका C++ के &lt;strong>RAII (Resource Acquisition Is Initialization)&lt;/strong> का उपयोग करना है।&lt;/p>
&lt;hr>
&lt;h2 id="4-raii-resource-acquisition-is-initialization-क-बनयद-बत">4. RAII (Resource Acquisition Is Initialization) की बुनियादी बातें
&lt;/h2>&lt;p>RAII C++ के निर्माता, Bjarne Stroustrup द्वारा प्रस्तावित एक अवधारणा है। इसका सिद्धांत अत्यंत सरल और शक्तिशाली है।&lt;/p>
&lt;ol>
&lt;li>संसाधन का अधिग्रहण (Acquisition) ऑब्जेक्ट के &lt;strong>कंस्ट्रक्टर (Initialization)&lt;/strong> में किया जाता है।&lt;/li>
&lt;li>संसाधन की मुक्ति (Release) ऑब्जेक्ट के &lt;strong>डिस्ट्रक्टर&lt;/strong> में की जाती है।&lt;/li>
&lt;/ol>
&lt;p>C++ भाषा विनिर्देश के कारण, जब स्कोप से बाहर निकला जाता है (चाहे वह सामान्य &lt;code>return&lt;/code> हो या अपवाद के कारण स्टैक अनवाइंडिंग हो), स्टैक पर आवंटित ऑब्जेक्ट का डिस्ट्रक्टर &lt;strong>निश्चित और स्वचालित रूप से&lt;/strong> कॉल किया जाता है।&lt;/p>
&lt;p>इसके परिणामस्वरूप, पिछले समीकरण में मानवीय त्रुटि की प्रायिकता $p$ को गणितीय रूप से &lt;strong>$0$&lt;/strong> किया जा सकता है।&lt;/p>
&lt;h3 id="ऑबजकट-लइफसइकल-क-वजअलइजशन">ऑब्जेक्ट लाइफसाइकल का विज़ुअलाइज़ेशन
&lt;/h3>&lt;p>निम्नलिखित अनुक्रम आरेख (sequence diagram) कच्चे API का उपयोग करके मैन्युअल प्रबंधन और RAII का उपयोग करके स्वचालित प्रबंधन के लाइफसाइकल के बीच का अंतर दिखाता है।&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant App as "C++ Application"
participant Wrapper as "RAII Wrapper"
participant OS as "Windows OS (Win32)"
Note over App, OS: "कच्चा Win32 API (मैनुअल प्रबंधन)"
App->>OS: "CreateFile()"
OS-->>App: "Return Raw HANDLE"
App->>App: "Do work (अपवाद उत्पन्न!)"
App--xOS: "CloseHandle() बायपास हो गया"
Note right of OS: "संसाधन लीक उत्पन्न"
Note over App, OS: "आधुनिक C++ (RAII प्रबंधन)"
App->>Wrapper: "Request Resource"
Wrapper->>OS: "CreateFile()"
OS-->>Wrapper: "Return Raw HANDLE"
Wrapper-->>App: "Return std::unique_ptr"
App->>App: "Do work (अपवाद उत्पन्न!)"
Note over App, Wrapper: "स्टैक अनवाइंडिंग से डिस्ट्रक्टर ट्रिगर होता है"
Wrapper->>OS: "CloseHandle()"
Note right of OS: "संसाधन सुरक्षित रूप से मुक्त"&lt;/div>
&lt;hr>
&lt;h2 id="5-stdunique_ptr-क-उपयग-करक-handle-क-सरकषत-रप-स-रप-करन-क-वध">5. &lt;code>std::unique_ptr&lt;/code> का उपयोग करके &lt;code>HANDLE&lt;/code> को सुरक्षित रूप से रैप करने की विधि
&lt;/h2>&lt;p>C++11 के बाद से, मानक लाइब्रेरी एक सामान्य-उद्देश्यीय RAII रैपर, &lt;code>std::unique_ptr&lt;/code> प्रदान करती है। इसका उपयोग न केवल मेमोरी (&lt;code>new/delete&lt;/code>) के प्रबंधन के लिए किया जा सकता है, बल्कि &lt;strong>कस्टम डिलीटर (Custom Deleter)&lt;/strong> निर्दिष्ट करके किसी भी संसाधन के प्रबंधन के लिए भी किया जा सकता है।&lt;/p>
&lt;p>Win32 के &lt;code>HANDLE&lt;/code> को &lt;code>std::unique_ptr&lt;/code> के साथ प्रबंधित करने के लिए एक बुनियादी डिलीटर इस प्रकार लिखा जा सकता है:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;windows.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;memory&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// HANDLE के लिए कस्टम डिलीटर
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">struct&lt;/span> &lt;span class="nc">handle_deleter&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// वह पॉइंटर प्रकार निर्दिष्ट करें जिसे std::unique_ptr आंतरिक रूप से प्रबंधित करता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">using&lt;/span> &lt;span class="n">pointer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">HANDLE&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">operator&lt;/span>&lt;span class="p">()(&lt;/span>&lt;span class="n">HANDLE&lt;/span> &lt;span class="n">handle&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">handle&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="k">nullptr&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">handle&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">INVALID_HANDLE_VALUE&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">CloseHandle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">handle&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// सुरक्षित हैंडल का टाइप एलियास (Type Alias)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">using&lt;/span> &lt;span class="n">unique_handle&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">handle_deleter&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस &lt;code>unique_handle&lt;/code> का उपयोग करके, पहले वाला खतरनाक कोड निम्नलिखित तरीके से फिर से लिखा जा सकता है:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">ProcessFileModern&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">wstring&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">filename&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// प्राप्त करने के तुरंत बाद RAII ऑब्जेक्ट को स्वामित्व (ownership) सौंपें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">unique_handle&lt;/span> &lt;span class="n">hFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">CreateFileW&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">filename&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c_str&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">GENERIC_READ&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">FILE_SHARE_READ&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">NULL&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">OPEN_EXISTING&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">FILE_ATTRIBUTE_NORMAL&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">NULL&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// त्रुटि जांच (INVALID_HANDLE_VALUE को संभालने के बारे में बाद में चर्चा की गई है)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">INVALID_HANDLE_VALUE&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">runtime_error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Failed to open file&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LARGE_INTEGER&lt;/span> &lt;span class="n">fileSize&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!::&lt;/span>&lt;span class="n">GetFileSizeEx&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">fileSize&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">runtime_error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Failed to get file size&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">buffer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">fileSize&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">QuadPart&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DWORD&lt;/span> &lt;span class="n">bytesRead&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!::&lt;/span>&lt;span class="n">ReadFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">buffer&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">buffer&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">bytesRead&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">NULL&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">runtime_error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Failed to read file&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// भले ही यहाँ कोई अपवाद उत्पन्न हो या अर्ली रिटर्न हो,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// जैसे ही फ़ंक्शन बाहर निकलता है, unique_handle का डिस्ट्रक्टर CloseHandle को कॉल करेगा!
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="6-गहरई-म-invalid_handle_value-और-nullptr-समसयओ-क-समधन">6. गहराई में: &lt;code>INVALID_HANDLE_VALUE&lt;/code> और &lt;code>nullptr&lt;/code> समस्याओं का समाधान
&lt;/h2>&lt;p>Win32 API के साथ काम करते समय C++ प्रोग्रामर को सबसे ज़्यादा परेशान करने वाली चीज़ों में से एक है &lt;strong>अमान्य (invalid) हैंडल का असंगत प्रतिनिधित्व&lt;/strong>।&lt;/p>
&lt;ul>
&lt;li>&lt;code>CreateEvent&lt;/code> या &lt;code>CreateThread&lt;/code> आदि: विफल होने पर &lt;code>NULL&lt;/code> (&lt;code>nullptr&lt;/code>) लौटाते हैं।&lt;/li>
&lt;li>&lt;code>CreateFile&lt;/code> आदि: विफल होने पर &lt;code>INVALID_HANDLE_VALUE&lt;/code> (मूल्य के रूप में &lt;code>(HANDLE)-1&lt;/code>) लौटाते हैं।&lt;/li>
&lt;/ul>
&lt;p>मानक &lt;code>std::unique_ptr&lt;/code> आंतरिक पॉइंटर के &lt;code>nullptr&lt;/code> होने को &amp;ldquo;खाली स्थिति (संसाधन के बिना)&amp;rdquo; के रूप में विशेष रूप से मानता है। इसका मतलब है कि बुलियन जांच जैसे &lt;code>if (ptr)&lt;/code> केवल &lt;code>nullptr&lt;/code> के लिए &lt;code>false&lt;/code> लौटाएगा।&lt;/p>
&lt;p>हालाँकि, यदि &lt;code>CreateFile&lt;/code> विफल हो जाता है और &lt;code>INVALID_HANDLE_VALUE&lt;/code> लौटाता है, तो &lt;code>std::unique_ptr&lt;/code> गलती से इसे &amp;ldquo;वैध गैर-NULL पॉइंटर&amp;rdquo; मान लेगा।&lt;/p>
&lt;p>इस समस्या को शालीनता से हल करने के लिए, हम C++ के &lt;code>std::unique_ptr&lt;/code> के उन्नत विनिर्देशों का लाभ उठा सकते हैं और एक &lt;strong>कस्टम पॉइंटर प्रकार&lt;/strong> परिभाषित कर सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;windows.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;memory&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">win32_handle_traits&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// कस्टम पॉइंटर प्रकार की परिभाषा
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="nc">pointer&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">HANDLE&lt;/span> &lt;span class="n">m_handle&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// हालाँकि डिफ़ॉल्ट निर्माण या nullptr असाइनमेंट के दौरान प्रारंभिक मान के रूप में INVALID_HANDLE_VALUE का उपयोग करना संभव है,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// अधिक बहुमुखी प्रतिभा के लिए, हम nullptr और INVALID_HANDLE_VALUE दोनों को अमान्य स्थितियों के रूप में मानते हैं।
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">pointer&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">m_handle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pointer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">nullptr_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">m_handle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pointer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">HANDLE&lt;/span> &lt;span class="n">h&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">m_handle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ऑपरेटर bool को ओवरलोड करें, और Win32 के दोनों अमान्य मानों को फ़िल्टर करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">explicit&lt;/span> &lt;span class="k">operator&lt;/span> &lt;span class="nf">bool&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">m_handle&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="k">nullptr&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">m_handle&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">INVALID_HANDLE_VALUE&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">operator&lt;/span> &lt;span class="nf">HANDLE&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">m_handle&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">friend&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="k">operator&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pointer&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">pointer&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">m_handle&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">m_handle&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">friend&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="k">operator&lt;/span>&lt;span class="o">!=&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pointer&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">pointer&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">m_handle&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">m_handle&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">operator&lt;/span>&lt;span class="p">()(&lt;/span>&lt;span class="n">pointer&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="c1">// operator bool कॉल किया जाएगा
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="o">::&lt;/span>&lt;span class="n">CloseHandle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="n">safe_win32_handle&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">win32_handle_traits&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस कार्यान्वयन के साथ, हम अब सहज और सुरक्षित कोड लिख सकते हैं जैसे:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="n">safe_win32_handle&lt;/span> &lt;span class="nf">hFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">CreateFileW&lt;/span>&lt;span class="p">(...));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">hFile&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// nullptr और INVALID_HANDLE_VALUE दोनों को यहाँ पकड़ा जा सकता है!
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">throw&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">system_error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">GetLastError&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">system_category&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="s">&amp;#34;CreateFile failed&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="7-gdi-ऑबजकटस-hdc-hbitmap-क-उननत-raii-परबधन">7. GDI ऑब्जेक्ट्स (&lt;code>HDC&lt;/code>, &lt;code>HBITMAP&lt;/code>) का उन्नत RAII प्रबंधन
&lt;/h2>&lt;p>Win32 का एक और मुश्किल हिस्सा GDI (Graphics Device Interface) संसाधन प्रबंधन है।
GDI ऑब्जेक्ट्स (पेन, ब्रश, फ़ॉन्ट, बिटमैप, आदि) को बनाने के बाद &lt;code>SelectObject&lt;/code> के माध्यम से डिवाइस कॉन्टेक्स्ट (&lt;code>HDC&lt;/code>) में चुना जाना चाहिए। उपयोग के बाद, उन्हें नष्ट करने के लिए &lt;code>DeleteObject&lt;/code> को कॉल करने से पहले &lt;strong>मूल ऑब्जेक्ट को वापस &lt;code>SelectObject&lt;/code> करके पुनर्स्थापित करने&lt;/strong> की बहुत बोझिल आवश्यकता होती है।&lt;/p>
&lt;p>इसे RAII के साथ हल करने के लिए रैपर कुछ इस तरह दिखता है:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// GDI ऑब्जेक्ट विलोपन के लिए डिलीटर
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">struct&lt;/span> &lt;span class="nc">gdi_deleter&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">using&lt;/span> &lt;span class="n">pointer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">HGDIOBJ&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">operator&lt;/span>&lt;span class="p">()(&lt;/span>&lt;span class="n">HGDIOBJ&lt;/span> &lt;span class="n">obj&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">obj&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">DeleteObject&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">obj&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="n">unique_gdi_obj&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">gdi_deleter&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// SelectObject का RAII रैपर (स्कोप छोड़ने पर मूल ऑब्जेक्ट को पुनर्स्थापित करता है)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">gdi_selector&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">HDC&lt;/span> &lt;span class="n">m_hdc&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">HGDIOBJ&lt;/span> &lt;span class="n">m_oldObj&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">gdi_selector&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">HDC&lt;/span> &lt;span class="n">hdc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">HGDIOBJ&lt;/span> &lt;span class="n">newObj&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">m_hdc&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hdc&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// नया ऑब्जेक्ट चुनें और पुराना ऑब्जेक्ट सेव करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">m_oldObj&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">::&lt;/span>&lt;span class="n">SelectObject&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">m_hdc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">newObj&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">~&lt;/span>&lt;span class="n">gdi_selector&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">m_oldObj&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="k">nullptr&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">m_oldObj&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">HGDI_ERROR&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// स्कोप से बाहर निकलते समय स्वचालित पुनर्स्थापना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="o">::&lt;/span>&lt;span class="n">SelectObject&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">m_hdc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m_oldObj&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// कॉपी करना प्रतिबंधित है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">gdi_selector&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">gdi_selector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">delete&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">gdi_selector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="k">operator&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">gdi_selector&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">delete&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="उपयग-क-उदहरण">उपयोग का उदाहरण
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">DrawMyGraphics&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">HDC&lt;/span> &lt;span class="n">hdc&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// एक पेन बनाएँ (RAII प्रबंधन)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">unique_gdi_obj&lt;/span> &lt;span class="n">hPen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">CreatePen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">PS_SOLID&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">RGB&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">255&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// HDC में पेन चुनें (स्कोप प्रबंधन)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">gdi_selector&lt;/span> &lt;span class="n">penSelect&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hdc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">hPen&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ड्राइंग प्रक्रिया...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="o">::&lt;/span>&lt;span class="n">MoveToEx&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hdc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">NULL&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">LineTo&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hdc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">100&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// स्कोप से बाहर निकलते समय, penSelect का डिस्ट्रक्टर SelectObject का उपयोग करके पुराने पेन को पुनर्स्थापित करेगा
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// फ़ंक्शन से बाहर निकलते समय, hPen का डिस्ट्रक्टर DeleteObject को कॉल करेगा
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस प्रकार, नेस्टेड लाइफसाइकिल वाले संसाधन प्रबंधन में RAII उत्कृष्ट है।&lt;/p>
&lt;hr>
&lt;h2 id="8-थरड-सकरनइजशन-ऑबजकटस-क-आधनककरण">8. थ्रेड सिंक्रोनाइज़ेशन ऑब्जेक्ट्स का आधुनिकीकरण
&lt;/h2>&lt;p>Win32 में &lt;code>CRITICAL_SECTION&lt;/code> और &lt;code>SRWLOCK&lt;/code> जैसे थ्रेड सिंक्रोनाइज़ेशन प्रिमिटिव मौजूद हैं। अपवाद सुरक्षा के दृष्टिकोण से &lt;code>EnterCriticalSection&lt;/code> / &lt;code>LeaveCriticalSection&lt;/code> को मैन्युअल रूप से कॉल करना निषिद्ध है।&lt;/p>
&lt;p>C++11 के &lt;code>std::mutex&lt;/code> और &lt;code>std::lock_guard&lt;/code> बहुत सुविधाजनक हैं, لیکن ऐसे समय भी होते हैं जब आप सीधे OS-नेटिव हाई-स्पीड लॉक मैकेनिज्म (विशेष रूप से SRWLock बहुत हल्का होता है) का उपयोग करना चाहते हैं।
मानक &lt;code>std::lock_guard&lt;/code> को किसी भी ऐसे प्रकार को स्वीकार करने के लिए डिज़ाइन किया गया है जिसमें &lt;code>lock()&lt;/code> और &lt;code>unlock()&lt;/code> सदस्य फ़ंक्शन हों (डक टाइपिंग के समान एक टेम्पलेट विनिर्देश)। हम इसका उपयोग कर सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">win32_srwlock&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">SRWLOCK&lt;/span> &lt;span class="n">m_lock&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">win32_srwlock&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">InitializeSRWLock&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">m_lock&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// std::lock_guard द्वारा आवश्यक इंटरफ़ेस
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">lock&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">AcquireSRWLockExclusive&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">m_lock&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">unlock&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">ReleaseSRWLockExclusive&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">m_lock&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// कॉपी और मूव निषिद्ध
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">win32_srwlock&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">win32_srwlock&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">delete&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">win32_srwlock&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="k">operator&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">win32_srwlock&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">delete&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इसके साथ, हम Win32 लॉक्स को पूरी तरह से C++ स्टैंडर्ड लाइब्रेरी की शैली में संभाल सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="n">win32_srwlock&lt;/span> &lt;span class="n">g_myLock&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="n">g_sharedData&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">UpdateData&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// अपवाद-सुरक्षित लॉक प्राप्ति
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">lock_guard&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">win32_srwlock&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">lock&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">g_myLock&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">g_sharedData&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">g_sharedData&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">100&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">runtime_error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Overflow&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// यदि अपवाद फेंका जाता है तो भी सुरक्षित रूप से लॉक रिलीज़ करें!
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="9-c-मनक-लइबरर-क-सथ-एककरण-stdsystem_error-और-hresult">9. C++ मानक लाइब्रेरी के साथ एकीकरण: &lt;code>std::system_error&lt;/code> और &lt;code>HRESULT&lt;/code>
&lt;/h2>&lt;p>Win32 त्रुटियों की दो मुख्य श्रेणियां हैं: &lt;code>GetLastError()&lt;/code> (DWORD प्रकार) और &lt;code>HRESULT&lt;/code> जिसका उपयोग COM और DirectX में किया जाता है। इन्हें C++ अपवाद, &lt;code>std::system_error&lt;/code> में परिवर्तित करके त्रुटि प्रबंधन को आधुनिक बनाया जा सकता है।&lt;/p>
&lt;p>&lt;code>GetLastError()&lt;/code> को फेंकते समय, MSVC (Visual C++) कार्यान्वयन &lt;code>std::system_category()&lt;/code> प्रदान करता है जो Win32 त्रुटि कोड को त्रुटि संदेशों में मैप करता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">inline&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">throw_if_win32_error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">BOOL&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="kt">char&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">msg&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;Win32 API failed&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DWORD&lt;/span> &lt;span class="n">err&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">::&lt;/span>&lt;span class="n">GetLastError&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// std::system_category आंतरिक रूप से FormatMessage API को कॉल करता है और एक त्रुटि स्ट्रिंग उत्पन्न करता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">throw&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">system_error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">err&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">system_category&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">msg&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>दूसरी ओर, &lt;code>HRESULT&lt;/code> के लिए, आप या तो एक समर्पित त्रुटि श्रेणी बना सकते हैं या Windows मानक &lt;code>_com_error&lt;/code> का उपयोग कर सकते हैं।&lt;/p>
&lt;hr>
&lt;h2 id="10-stdexpected-c23-क-उपयग-करत-हए-आधनक-तरट-परबधन">10. &lt;code>std::expected&lt;/code> (C++23) का उपयोग करते हुए आधुनिक त्रुटि प्रबंधन
&lt;/h2>&lt;p>C++23 से, &lt;code>std::expected&lt;/code> (जो Rust के &lt;code>Result&lt;/code> प्रकार के बराबर है) पेश किया गया था। उन परियोजनाओं में जो अपवाद पसंद नहीं करते हैं (प्रदर्शन कारणों से या अक्सर त्रुटियां उत्पन्न करने वाले डिज़ाइनों के कारण), Win32 रिटर्न वैल्यू को आधुनिक बनाने का यह सबसे अच्छा तरीका है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;expected&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;string&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// सफलता पर unique_handle, विफलता पर DWORD (त्रुटि कोड) लौटाता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">expected&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">safe_win32_handle&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">DWORD&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">OpenFileModern&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">wstring&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">path&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">safe_win32_handle&lt;/span> &lt;span class="nf">h&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">CreateFileW&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">path&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c_str&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">GENERIC_READ&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">OPEN_EXISTING&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unexpected&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">GetLastError&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">move&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// सफलता पर हैंडल को मूव करें और लौटाएं
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">Usage&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">OpenFileModern&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">L&lt;/span>&lt;span class="s">&amp;#34;C:&lt;/span>&lt;span class="se">\\&lt;/span>&lt;span class="s">test.txt&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// सफलता के मामले में हैंडलिंग
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">safe_win32_handle&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">hFile&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// विफलता के मामले में हैंडलिंग
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">DWORD&lt;/span> &lt;span class="n">err&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">error&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Error code: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">err&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस तरह, C++23 का उपयोग करके, आप रिटर्न वैल्यू-आधारित त्रुटि प्रबंधन और RAII के लाभों को संतुलित कर सकते हैं।&lt;/p>
&lt;hr>
&lt;h2 id="11-microsoft-क-उततर-1-wil-windows-implementation-libraries-क-लभ-उठन">11. Microsoft का उत्तर (1): WIL (Windows Implementation Libraries) का लाभ उठाना
&lt;/h2>&lt;p>अब तक, हमने कस्टम-निर्मित रैपर प्रस्तुत किए हैं, लेकिन वास्तविकता में, Microsoft भी इस समस्या को गंभीरता से लेता है और उसने एक आधिकारिक हेडर-ओनली लाइब्रेरी &lt;strong>WIL (Windows Implementation Libraries)&lt;/strong> को आधुनिक C++ के लिए ओपन सोर्स (GitHub पर उपलब्ध) के रूप में प्रकाशित किया है।&lt;/p>
&lt;p>WIL का उपयोग करके, ऊपर हमारे द्वारा बनाए गए सभी रैपर मानक के रूप में प्रदान किए जाते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;wil/resource.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;wil/result.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">ProcessWithWIL&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// wil::unique_handle पहले से ही INVALID_HANDLE_VALUE और NULL दोनों को संभालता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">wil&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_handle&lt;/span> &lt;span class="n">hFile&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// THROW_IF_WIN32_BOOL_FALSE मैक्रो स्वचालित रूप से त्रुटि जांच करता है और अपवाद फेंकता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">THROW_IF_WIN32_BOOL_FALSE&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">CreateFileW&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">L&lt;/span>&lt;span class="s">&amp;#34;test.txt&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">GENERIC_READ&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">OPEN_EXISTING&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hFile&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">put&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="c1">// WIL-विशिष्ट आउटपुट पॉइंटर प्राप्त करने के लिए सहायक
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// मेमोरी प्रबंधन रैपर जैसे wil::unique_cotaskmem_string भी उपलब्ध हैं
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>WIL का वास्तविक सार &lt;code>wil::unique_any&lt;/code> नामक इसके शक्तिशाली टेम्पलेट में निहित है, जो आपको केवल कुछ पंक्तियों के कोड के साथ किसी भी Win32 संसाधन (केवल फ़ाइल हैंडल ही नहीं, बल्कि रजिस्ट्री कुंजियाँ, GDI ऑब्जेक्ट, स्थानीय मेमोरी आदि) के लिए RAII रैपर उत्पन्न करने की अनुमति देता है।&lt;/p>
&lt;hr>
&lt;h2 id="12-microsoft-क-उततर-2-cwinrt-क-सथ-com-अमरतन-abstraction">12. Microsoft का उत्तर (2): C++/WinRT के साथ COM अमूर्तन (Abstraction)
&lt;/h2>&lt;p>कई Win32 API (विशेष रूप से शेल एक्सटेंशन और DirectX) C-आधारित COM (Component Object Model) इंटरफेस के माध्यम से प्रदान किए जाते हैं।
पारंपरिक &lt;code>CComPtr&lt;/code> (ATL) और &lt;code>ComPtr&lt;/code> (WRL) से आगे बढ़ते हुए, Microsoft अब आधिकारिक तौर पर &lt;strong>C++/WinRT&lt;/strong> की सिफारिश करता है।&lt;/p>
&lt;p>C++/WinRT न केवल Windows Runtime (WinRT) बल्कि पारंपरिक COM ऑब्जेक्ट्स को भी बेहद स्मार्ट तरीके से संभाल सकता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;winrt/base.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">ComExample&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// COM आरंभीकरण (RAII-कृत)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">winrt&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">init_apartment&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// winrt::com_ptr के साथ IUnknown को विरासत में प्राप्त करने वाले COM इंटरफेस को सुरक्षित रूप से प्रबंधित करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">winrt&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">com_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">IDXGIFactory&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">factory&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">winrt&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">check_hresult&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">::&lt;/span>&lt;span class="n">CreateDXGIFactory&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">__uuidof&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">IDXGIFactory&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">factory&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">put_void&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// मैन्युअल रूप से AddRef या Release कॉल करने की कोई आवश्यकता नहीं है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="13-वसतकल-architecture-और-लइफसइकल-क-वजअलइजशन">13. वास्तुकला (Architecture) और लाइफसाइकल का विज़ुअलाइज़ेशन
&lt;/h2>&lt;p>आइए आधुनिक Windows C++ एप्लिकेशन विकास में लेयर संरचना को व्यवस्थित करें।&lt;/p>
&lt;div class="mermaid">graph TD
A["आधुनिक C++ एप्लिकेशन लॉजिक"] --> B["C++ मानक लाइब्रेरी (std::unique_ptr, std::mutex, std::expected)"]
A --> C["Windows इम्प्लीमेंटेशन लाइब्रेरी (WIL)"]
A --> D["C++/WinRT"]
C --> E["कच्चा Win32 API (C इंटरफ़ेस)"]
D --> F["COM इंटरफेस"]
F --> E
B --> E
E --> G["Windows कर्नेल (ntoskrnl.exe) / सबसिस्टम्स"]
style A fill:#4CAF50,stroke:#388E3C,stroke-width:2px,color:#fff
style G fill:#2196F3,stroke:#1976D2,stroke-width:2px,color:#fff&lt;/div>
&lt;p>एप्लिकेशन लॉजिक को कभी भी कच्चे Win32 API (लेयर E) के सीधे संपर्क में नहीं आना चाहिए। हमेशा मानक लाइब्रेरी, WIL या C++/WinRT जैसे अमूर्तन लेयर के माध्यम से पहुंचने वाली वास्तुकला को अपनाकर मेमोरी सुरक्षा में नाटकीय रूप से सुधार किया जा सकता है।&lt;/p>
&lt;hr>
&lt;h2 id="14-जर-कसट-अमरतन-zero-cost-abstraction-क-परदरशन-वशलषण">14. ज़ीरो-कॉस्ट अमूर्तन (Zero-cost Abstraction) का प्रदर्शन विश्लेषण
&lt;/h2>&lt;p>कुछ लोगों को यह आश्चर्य हो सकता है, &amp;ldquo;क्या RAII रैपर या स्मार्ट पॉइंटर्स का उपयोग कच्चे C API की तुलना में प्रदर्शन को धीमा कर देगा?&amp;rdquo;
आइए यहां प्रदर्शन लागत के गणितीय मॉडल को देखें।&lt;/p>
&lt;p>कुल निष्पादन समय $T_{\text{total}}$ को निम्नानुसार विभाजित किया जा सकता है:&lt;/p>
$$ T_{\text{total}} = T_{\text{syscall}} + T_{\text{wrapper}} + T_{\text{cleanup}} $$
&lt;ul>
&lt;li>$T_{\text{syscall}}$: Win32 API के अंदर कर्नेल-मोड संक्रमण और वास्तविक प्रसंस्करण में लगने वाला समय। आमतौर पर मिलीसेकंड से माइक्रोसेकंड में।&lt;/li>
&lt;li>$T_{\text{wrapper}}$: &lt;code>std::unique_ptr&lt;/code> या WIL रैपर कक्षाओं के निर्माण में लगने वाला समय।&lt;/li>
&lt;li>$T_{\text{cleanup}}$: डिस्ट्रक्टर को कॉल करने में लगने वाला समय।&lt;/li>
&lt;/ul>
&lt;p>C++ कंपाइलर (MSVC, Clang, GCC) इनलाइनिंग (Inlining) अनुकूलन में बहुत उत्कृष्ट हैं। &lt;code>std::unique_ptr&lt;/code> के कंस्ट्रक्टर्स, डिस्ट्रक्टर्स और ओवरलोडेड &lt;code>operator*&lt;/code> या &lt;code>operator bool&lt;/code> सभी को &lt;code>inline&lt;/code> विस्तारित किया जाता है, और यह मेमोरी में कच्चे पॉइंटर्स के प्रत्यक्ष हेरफेर के समान मशीन कोड में संकलित होता है।&lt;/p>
&lt;p>अर्थात्, &lt;strong>$T_{\text{wrapper}} \approx 0$&lt;/strong> है। यह C++ के सबसे बड़े दर्शन, &lt;strong>Zero-cost Abstraction (ज़ीरो-कॉस्ट अमूर्तन)&lt;/strong> का प्रमाण है। भले ही आप सुरक्षा प्राप्त करते हैं, रनटाइम ओवरहेड वस्तुतः शून्य है।&lt;/p>
&lt;hr>
&lt;h2 id="15-नषकरष-सरकषत-windows-परगरमग-क-भवषय">15. निष्कर्ष: सुरक्षित Windows प्रोग्रामिंग का भविष्य
&lt;/h2>&lt;p>ऐतिहासिक कारणों से, Win32 API एक अच्छी पुरानी विरासत है जिसे C भाषा प्रतिमान (paradigm) में डिज़ाइन किया गया है। हालाँकि, इसे कॉल करने वाला C++ विकसित होता रहा है, और अब बेहद सुरक्षित और अभिव्यंजक (expressive) कोड लिखना संभव है।&lt;/p>
&lt;p>आइए इस लेख में शामिल मुख्य बिंदुओं की समीक्षा करें।&lt;/p>
&lt;ol>
&lt;li>&lt;strong>मैनुअल &lt;code>CloseHandle&lt;/code> या &lt;code>DeleteObject&lt;/code> कभी न लिखें।&lt;/strong> हर चीज़ को &lt;code>std::unique_ptr&lt;/code> जैसे RAII कंटेनरों में एनकैप्सुलेट (encapsulate) करें।&lt;/li>
&lt;li>&lt;strong>&lt;code>INVALID_HANDLE_VALUE&lt;/code> के जाल को समझें।&lt;/strong> एक कस्टम डिलीटर/कस्टम पॉइंटर ट्रेट्स लागू करें, या WIL के &lt;code>wil::unique_handle&lt;/code> का उपयोग करें।&lt;/li>
&lt;li>&lt;strong>त्रुटि प्रबंधन को आधुनिक बनाएं।&lt;/strong> &lt;code>GetLastError()&lt;/code> या &lt;code>HRESULT&lt;/code> को &lt;code>std::system_error&lt;/code> अपवाद के रूप में फेंकें, या टाइप-सुरक्षित हैंडलिंग के लिए C++23 के &lt;code>std::expected&lt;/code> का उपयोग करें।&lt;/li>
&lt;li>&lt;strong>दिग्गजों के कंधों पर खड़े हों।&lt;/strong> सक्रिय रूप से Microsoft के आधिकारिक WIL और C++/WinRT को अपनाएं और पहिया का फिर से आविष्कार करने से बचें।&lt;/li>
&lt;/ol>
&lt;p>आधुनिक C++ विकास में, नग्न (raw) पॉइंटर्स या हैंडल्स को चारों ओर ले जाना बिना सीटबेल्ट के हाईवे पर गाड़ी चलाने जैसा है। कृपया C++ द्वारा प्रदान किए गए शक्तिशाली टाइप सिस्टम और RAII का पूरा उपयोग करें और सुरक्षित और मजबूत Windows एप्लिकेशन विकास का आनंद लें।&lt;/p></description></item></channel></rss>