C# सिस्टम प्रोग्रामिंग: जब हाई-लेवल मिलता है लो-लेवल हार्डवेयर से
\n\nजब आप "सिस्टम प्रोग्रामिंग" सुनते हैं, तो आमतौर पर दिमाग में C या असेंबली में कोड लिखने वाले दाढ़ी वाले गुरुओं की तस्वीर आती है, जिनके टर्मिनल हरे टेक्स्ट से भरे होते हैं। और C# तो "बिजनेस एप्लिकेशन", "Windows Forms" और "उन लोगों के लिए है जो पॉइंटर्स से परेशान नहीं होना चाहते"। स्पॉयलर: यह एक मिथक है।
\n\nअसल में, C# एक सिस्टम प्रोग्रामर के लिए स्विस आर्मी नाइफ की तरह है, जो तेज़, सुरक्षित कोड लिखना चाहता है, लेकिन ज़रूरत पड़ने पर अनमैनेज्ड मेमोरी की गहराई में भी जा सकता है। इस आर्टिकल में, हम देखेंगे कि C# कैसे वास्तविक सिस्टम कार्यों को हल करने में मदद करता है: प्रोसेस के साथ काम करने से लेकर WinAPI के ज़रिए डायरेक्ट मेमोरी एक्सेस तक। और हाँ, कोड उदाहरण होंगे — उनके बिना तो काम नहीं चलेगा।
C# सिर्फ "बिजनेस टूल" क्यों नहीं है?
\n\nC# में सिस्टम प्रोग्रामिंग कोई ऑक्सीमोरॉन नहीं है। .NET प्लेटफॉर्म (खासकर .NET 5+) डेवलपर को एक अनोखा कॉम्बिनेशन देता है: नेटिव कोड के करीब परफॉरमेंस और हाई-लेवल भाषा की सुविधा। आप ड्राइवर लिख सकते हैं, प्रोसेस के साथ काम कर सकते हैं, मैन्युअली मेमोरी अलॉकेट कर सकते हैं और रिसोर्स मैनेजमेंट के तनाव से बच सकते हैं।
\n\nमुख्य क्षमताएं जो C# को सिस्टम प्रोग्रामिंग के लिए उपयुक्त बनाती हैं:
\n- \n
- Unsafe कोड और पॉइंटर्स — हाँ, C++ की तरह C# में भी सीधे एड्रेस के साथ काम कर सकते हैं। \n
- P/Invoke — नेटिव लाइब्रेरी (WinAPI, libc, ड्राइवर) के किसी भी फंक्शन को कॉल करना। \n
- Span
और Memory — बिना अनावश्यक अलॉकेशन के मेमोरी ब्लॉक के साथ सुरक्षित काम। \n - Native AOT — JIT और CLR के बिना नेटिव कोड में कंपाइलेशन। \n
- C/C++ के साथ Interop — मौजूदा सिस्टम प्रोजेक्ट्स में C# को एम्बेड करना। \n
अगर आपको लगता था कि C# सिर्फ वेब और डेटाबेस के लिए है, तो हैरान होने के लिए तैयार रहें।
\n\nUnsafe कोड: आग से खेलना, लेकिन नियंत्रण में
\n\nC# में unsafe कीवर्ड एक परमाणु मिसाइल पर लाल बटन की तरह है। दबाएं — और आप सब कुछ कर सकते हैं: पॉइंटर्स को डीरेफरेंस करना, फिक्स्ड ऑब्जेक्ट्स के साथ काम करना, स्टैक मेमोरी अलॉकेट करना। लेकिन ज़िम्मेदारी भी पूरी।
मान लीजिए, हमें बाउंड्री चेक को छोड़कर तेज़ी से बाइट एरे कॉपी करनी है। सेफ कोड में हम Array.Copy का उपयोग करेंगे, लेकिन अगर हम ड्राइवर के साथ काम करने वाली सिस्टम यूटिलिटी लिख रहे हैं, तो हर माइक्रोसेकंड मायने रखता है।
using System;\n\nunsafe class MemoryCopy\n{\n public static void FastCopy(byte[] source, byte[] dest, int length)\n {\n fixed (byte* pSrc = source, pDst = dest)\n {\n byte* ps = pSrc;\n byte* pd = pDst;\n for (int i = 0; i < length; i++)\n *pd++ = *ps++;\n }\n }\n}\n\nयहां हम मैनेज्ड एरे को मेमोरी में "फिक्स" करने के लिए fixed का उपयोग करते हैं, ताकि कॉपी के दौरान गार्बेज कलेक्टर उन्हें शिफ्ट न करे। परिणाम — C में memcpy के करीब स्पीड पर कॉपी। बेशक, रोज़मर्रा के कामों के लिए यह ज़रूरत से ज़्यादा है, लेकिन C# सिस्टम प्रोग्रामिंग के लिए — यह must-have है।
Unsafe कब उचित है?
\n- \n
- रॉ बाइट लेवल पर नेटवर्क पैकेट के साथ काम करना। \n
- DMA के ज़रिए हार्डवेयर के साथ इंटरैक्शन। \n
- खुद के मेमोरी अलोकेटर को लागू करना। \n
- क्रिटिकल कोड सेक्शन का ऑप्टिमाइजेशन (जैसे, कैमरा वीडियो प्रोसेसिंग)। \n
P/Invoke और WinAPI: C# कर्नेल पर दस्तक देता है
\n\nअसली सिस्टम प्रोग्रामिंग नेटिव फंक्शन को कॉल किए बिना संभव नहीं है। C# इसके लिए P/Invoke (Platform Invocation Services) तंत्र प्रदान करता है। प्रोसेस की लिस्ट प्राप्त करनी है, विंडो मैनेज करनी है या दूसरे प्रोसेस की मेमोरी पढ़नी है? बिल्कुल संभव है।
\n\nआइए एक क्लासिक उदाहरण देखें — WinAPI फंक्शन CreateToolhelp32Snapshot के ज़रिए चल रहे प्रोसेस की लिस्ट प्राप्त करना।
using System;\nu