पुराना WinINet प्रॉक्सी हेल्पर 64-बिट बिल्ड में क्यों टूटता है
C# प्रॉक्सी इंटरऑप उदाहरणों में पॉइंटर कटौती को पहचानें और दोबारा उपयोग से पहले संरचना लेआउट और मेमोरी स्वामित्व की समीक्षा करें।
एक कास्ट एक सामान्य दिखने वाले प्रॉक्सी-सेटिंग्स हेल्पर को आर्किटेक्चर-निर्भर विफलता में बदल सकता है:
current = (IntPtr)((int)current + optionSize);
वह कोड अगली संरचना का आकार जोड़ने से पहले मूल पते को 32-बिट पूर्णांक में सिकोड़ता है। 64-बिट प्रक्रिया ऐसे पते रख सकती है जो फ़िट नहीं होते। कन्वर्ज़न और मान के आधार पर परिणाम ओवरफ़्लो अपवाद या अमान्य पता हो सकता है। बिल्ड को x86 पर लौटाना गलती छिपा सकता है, लेकिन इंटरऑप कार्यान्वयन को उस वर्कअराउंड पर निर्भर छोड़ देता है।
पतों को पॉइंटर-आकार में रखें। उदाहरण के लिए, पहले से आवंटित सरणी से आगे बढ़ने के लिए यह उपयोग किया जा सकता है:
IntPtr item = IntPtr.Add(buffer, checked(index * optionSize));
ऑफ़सेट पूर्णांक रहता है; पता स्वयं किसी के माध्यम से निचोड़ा नहीं जाता। आवंटन का आकार और सूचकांक अभी भी मान्य होने चाहिए।
फिर आसपास की घोषणाओं की जाँच करें
WinINet के प्रति-कनेक्शन विकल्पों में एक यूनियन होती है जिसके सदस्यों में DWORD, स्ट्रिंग पॉइंटर और FILETIME शामिल हैं। पॉइंटर फ़ील्ड को IntPtr चाहिए; DWORD फ़ील्ड 32-बिट रहते हैं। मूल संरेखण मायने रखता है, इसलिए हर पूर्णांक को 64-बिट पूर्णांक से बदलना या पैक किया गया लेआउट थोपना उचित मरम्मत नहीं है।
सरणी से गुजरते समय marshaling के बाद की संरचना का आकार उपयोग करें, ANSI या Unicode घोषणा का लगातार मिलान करें और प्रत्येक आवंटन को अलग से ट्रैक करें। विकल्प संरचनाओं के ब्लॉक को मुक्त करने से कहीं और आवंटित और उन संरचनाओं द्वारा संदर्भित स्ट्रिंग स्वतः मुक्त नहीं होतीं।
अंत में, सेटिंग्स के दायरे के प्रश्न को मेमोरी सत्यता से अलग रखें। कास्ट ठीक करना यह सिद्ध नहीं करता कि हेल्पर का चुना WinINet विकल्प केवल एक नियंत्रण, एक प्रक्रिया या वर्तमान उपयोगकर्ता की सेटिंग्स को प्रभावित करता है। पुराने नमूने के बाकी हिस्से को अपनाने से पहले उस API व्यवहार की जाँच करें। यदि यह रीफ़्रेश सूचनाएँ भी भेजता है, तो उन्हें इच्छित दायरे के लिए चुनें.