Γιατί ένας παλιός βοηθός διακομιστή μεσολάβησης WinINet σπάει σε έκδοση 64-bit
Αναγνωρίστε την περικοπή δεικτών σε παραδείγματα interop διακομιστή μεσολάβησης σε C# και ελέγξτε τη διάταξη των δομών και την ιδιοκτησία μνήμης πριν τα επαναχρησιμοποιήσετε.
Μία μετατροπή μπορεί να μετατρέψει έναν φαινομενικά συνηθισμένο βοηθό ρυθμίσεων διακομιστή μεσολάβησης σε αποτυχία εξαρτώμενη από την αρχιτεκτονική:
current = (IntPtr)((int)current + optionSize);
Ο κώδικας αυτός περιορίζει μια εγγενή διεύθυνση σε ακέραιο 32-bit πριν προσθέσει το μέγεθος της επόμενης δομής. Μια διεργασία 64-bit μπορεί να κρατά διευθύνσεις που δεν χωρούν. Ανάλογα με τη μετατροπή και την τιμή, το αποτέλεσμα μπορεί να είναι εξαίρεση υπερχείλισης ή άκυρη διεύθυνση. Η επιστροφή της έκδοσης σε x86 μπορεί να κρύψει το λάθος, αλλά αφήνει την υλοποίηση interop εξαρτημένη από αυτό το υποκατάστατο.
Κρατήστε τις διευθύνσεις σε μορφή μεγέθους δείκτη. Για παράδειγμα, η προώθηση μέσα σε έναν ήδη δεσμευμένο πίνακα μπορεί να χρησιμοποιήσει:
IntPtr item = IntPtr.Add(buffer, checked(index * optionSize));
Η μετατόπιση παραμένει ακέραιος· η ίδια η διεύθυνση δεν πιέζεται μέσα από έναν. Το μέγεθος δέσμευσης και ο δείκτης πρέπει ακόμη να είναι έγκυρα.
Έπειτα εξετάστε τις γύρω δηλώσεις
Οι επιλογές του WinINet ανά σύνδεση περιέχουν μια ένωση της οποίας τα μέλη περιλαμβάνουν DWORD, δείκτη συμβολοσειράς και FILETIME. Τα πεδία δεικτών χρειάζονται IntPtr· τα πεδία DWORD παραμένουν 32-bit. Η εγγενής στοίχιση έχει σημασία, επομένως η αντικατάσταση κάθε ακεραίου με ακέραιο 64-bit ή η επιβολή πακεταρισμένης διάταξης δεν είναι υγιής επισκευή.
Χρησιμοποιήστε το μέγεθος της δομής μετά το marshaling όταν διατρέχετε τον πίνακα, αντιστοιχίστε με συνέπεια τη δήλωση ANSI ή Unicode και παρακολουθήστε κάθε δέσμευση ξεχωριστά. Η απελευθέρωση του μπλοκ των δομών επιλογών δεν απελευθερώνει αυτόματα συμβολοσειρές που δεσμεύτηκαν αλλού και αναφέρονται από αυτές τις δομές.
Τέλος, κρατήστε το ζήτημα του εύρους των ρυθμίσεων χωριστά από την ορθότητα της μνήμης. Η επισκευή μιας μετατροπής δεν αποδεικνύει ότι η επιλεγμένη επιλογή WinINet επηρεάζει μόνο ένα στοιχείο ελέγχου, μία διεργασία ή τις ρυθμίσεις του τρέχοντος χρήστη. Ελέγξτε αυτή τη συμπεριφορά του API πριν υιοθετήσετε το υπόλοιπο παλιό δείγμα. Αν στέλνει επίσης ειδοποιήσεις ανανέωσης, επιλέξτε τις για το προβλεπόμενο εύρος.