Warum ein alter WinINet-Proxy-Helfer in einem 64-Bit-Build bricht
Erkennen Sie Zeigerkürzungen in C#-Proxy-Interop-Beispielen und prüfen Sie Strukturlayout und Speichereigentum, bevor Sie sie wiederverwenden.
Ein einziger Cast kann einen scheinbar gewöhnlichen Helfer für Proxy-Einstellungen in einen architekturabhängigen Fehler verwandeln:
current = (IntPtr)((int)current + optionSize);
Dieser Code verengt eine native Adresse auf eine 32-Bit-Ganzzahl, bevor die Größe der nächsten Struktur addiert wird. Ein 64-Bit-Prozess kann Adressen enthalten, die nicht hineinpassen. Je nach Konvertierung und Wert kann das Ergebnis eine Überlaufausnahme oder eine ungültige Adresse sein. Ein Zurückschalten des Builds auf x86 kann den Fehler verbergen, lässt die Interop-Implementierung aber von diesem Workaround abhängig.
Halten Sie Adressen in Zeigergröße. Zum Beispiel kann das Vorrücken durch ein bereits zugewiesenes Array so aussehen:
IntPtr item = IntPtr.Add(buffer, checked(index * optionSize));
Der Offset bleibt eine Ganzzahl; die Adresse selbst wird nicht durch eine solche gepresst. Zuordnungsgröße und Index müssen weiterhin gültig sein.
Prüfen Sie dann die umgebenden Deklarationen
Die WinINet-Optionen pro Verbindung enthalten eine Union, deren Mitglieder ein DWORD, einen Zeiger auf eine Zeichenfolge und ein FILETIME umfassen. Zeigerfelder benötigen IntPtr; DWORD-Felder bleiben 32 Bit breit. Die native Ausrichtung ist wichtig, daher ist es keine solide Reparatur, jede Ganzzahl durch eine 64-Bit-Ganzzahl zu ersetzen oder ein gepacktes Layout zu erzwingen.
Verwenden Sie beim Durchlaufen des Arrays die gemarshallte Strukturgröße, stimmen Sie die ANSI- oder Unicode-Deklaration konsistent ab und verfolgen Sie jede Zuordnung getrennt. Das Freigeben des Blocks der Optionsstrukturen gibt nicht automatisch Zeichenfolgen frei, die anderswo zugewiesen und von diesen Strukturen referenziert werden.
Schließlich sollte die Frage des Einstellungsbereichs von der Speicherkorrektheit getrennt bleiben. Die Reparatur eines Casts beweist nicht, dass eine gewählte WinINet-Option nur ein Steuerelement, einen Prozess oder die Einstellungen des aktuellen Benutzers betrifft. Prüfen Sie dieses API-Verhalten, bevor Sie den Rest eines alten Beispiels übernehmen. Wenn es auch Aktualisierungsbenachrichtigungen sendet, wählen Sie diese für den beabsichtigten Bereich aus.