Proč starý pomocník proxy WinINet selhává v 64bitovém sestavení
Rozpoznejte zkracování ukazatelů v příkladech proxy interopu v C# a před opětovným použitím zkontrolujte rozvržení struktur a vlastnictví paměti.
Jediné přetypování může zdánlivě obyčejný pomocník pro nastavení proxy proměnit v poruchu závislou na architektuře:
current = (IntPtr)((int)current + optionSize);
Tento kód zúží nativní adresu na 32bitové celé číslo, než přičte velikost další struktury. 64bitový proces může obsahovat adresy, které se tam nevejdou. Podle převodu a hodnoty může být výsledkem výjimka přetečení nebo neplatná adresa. Návrat sestavení na x86 může chybu skrýt, ale ponechává implementaci interopu závislou na tomto obchvatu.
Uchovávejte adresy ve tvaru velikosti ukazatele. Například pro postupné procházení již alokovaného pole lze použít:
IntPtr item = IntPtr.Add(buffer, checked(index * optionSize));
Posun zůstává celým číslem; samotná adresa se přes něj neprotlačuje. Velikost alokace a index musí být stále platné.
Potom prozkoumejte okolní deklarace
Volby WinINet pro jednotlivá připojení obsahují sjednocení, jehož členy zahrnují DWORD, ukazatel na řetězec a FILETIME. Pole ukazatelů potřebují IntPtr; pole DWORD zůstávají 32bitová. Nativní zarovnání je důležité, takže nahrazení každého celého čísla 64bitovým celým číslem nebo vynucení zabaleného rozvržení není správná oprava.
Při procházení pole používejte velikost struktury po marshalingu, důsledně slaďte deklaraci ANSI nebo Unicode a každou alokaci sledujte samostatně. Uvolnění bloku struktur voleb automaticky neuvolní řetězce alokované jinde, na které tyto struktury odkazují.
Nakonec oddělte otázku rozsahu nastavení od správnosti paměti. Oprava přetypování nedokazuje, že zvolená volba WinINet ovlivňuje jen jeden ovládací prvek, jeden proces nebo nastavení aktuálního uživatele. Ověřte toto chování API, než přijmete zbytek starého příkladu. Pokud také odesílá oznámení o obnovení, vyberte je pro zamýšlený rozsah.