რატომ იშლება ძველი WinINet პროქსის დამხმარე 64-ბიტიან აწყობაში
ამოიცანით მაჩვენებლების მოკვეთა C# პროქსის interop მაგალითებში და გადახედეთ სტრუქტურების განლაგებასა და მეხსიერების საკუთრებას ხელახლა გამოყენებამდე.
ერთმა cast-მა შეიძლება ერთი შეხედვით ჩვეულებრივი პროქსის პარამეტრების დამხმარე არქიტექტურაზე დამოკიდებულ გაუმართაობად აქციოს:
current = (IntPtr)((int)current + optionSize);
ეს კოდი ბუნებრივ მისამართს 32-ბიტიან მთელ რიცხვამდე ავიწროებს, სანამ შემდეგი სტრუქტურის ზომას დაუმატებს. 64-ბიტიან პროცესს შეუძლია ისეთი მისამართების შენახვა, რომლებიც არ ეტევა. გარდაქმნისა და მნიშვნელობის მიხედვით შედეგი შეიძლება იყოს გადავსების გამონაკლისი ან არასწორი მისამართი. აწყობის x86-ზე დაბრუნებამ შეიძლება შეცდომა დამალოს, მაგრამ interop-ის რეალიზაცია ამ გვერდის ავლით გადაწყვეტაზე დამოკიდებული რჩება.
შეინახეთ მისამართები მაჩვენებლის ზომის ფორმით. მაგალითად, უკვე გამოყოფილ მასივში გასავლელად შეიძლება გამოვიყენოთ:
IntPtr item = IntPtr.Add(buffer, checked(index * optionSize));
გადახრა მთელ რიცხვად რჩება; თავად მისამართი მასში არ იწურება. გამოყოფის ზომა და ინდექსი მაინც უნდა იყოს სწორი.
შემდეგ შეამოწმეთ გარშემო არსებული დეკლარაციები
WinINet-ის თითო კავშირის პარამეტრები შეიცავს გაერთიანებას, რომლის წევრებში შედის DWORD, სტრიქონის მაჩვენებელი და FILETIME. მაჩვენებლის ველებს სჭირდება IntPtr; DWORD ველები 32-ბიტიანი რჩება. ბუნებრივ გასწორებას მნიშვნელობა აქვს, ამიტომ ყოველი მთელი რიცხვის 64-ბიტიანი მთელი რიცხვით ჩანაცვლება ან შეფუთული განლაგების იძულება სწორი შეკეთება არ არის.
მასივში სიარულისას გამოიყენეთ სტრუქტურის ზომა marshaling-ის შემდეგ, თანმიმდევრულად შეასაბამეთ ANSI ან Unicode დეკლარაცია და თვალყური ადევნეთ თითოეულ გამოყოფას ცალ-ცალკე. პარამეტრების სტრუქტურების ბლოკის გათავისუფლება ავტომატურად არ ათავისუფლებს სხვაგან გამოყოფილ და ამ სტრუქტურების მიერ მითითებულ სტრიქონებს.
და ბოლოს, გამოყავით პარამეტრების ფარგლების საკითხი მეხსიერების სისწორისგან. cast-ის შეკეთება არ ამტკიცებს, რომ დამხმარის მიერ არჩეული WinINet პარამეტრი მოქმედებს მხოლოდ ერთ კონტროლზე, ერთ პროცესზე ან მიმდინარე მომხმარებლის პარამეტრებზე. შეამოწმეთ ეს API ქცევა ძველი ნიმუშის დანარჩენი ნაწილის მიღებამდე. თუ ის ასევე აგზავნის განახლების შეტყობინებებს, აირჩიეთ ისინი განკუთვნილი ფარგლისთვის.