En enda cast kan förvandla en till synes vanlig hjälpare för proxyinställningar till ett arkitekturoberoende fel:

current = (IntPtr)((int)current + optionSize);

Den koden snävar in en inbyggd adress till ett 32-bitars heltal innan storleken på nästa struktur läggs till. En 64-bitarsprocess kan hålla adresser som inte får plats. Beroende på konverteringen och värdet kan resultatet bli ett överflödesundantag eller en ogiltig adress. Att bygga för x86 igen kan dölja felet, men lämnar interop-implementeringen beroende av den omvägen.

Håll adresser i pekarstorlek. Till exempel kan genomgång av en redan allokerad array använda:

IntPtr item = IntPtr.Add(buffer, checked(index * optionSize));

Offseten förblir ett heltal; själva adressen pressas inte genom ett. Allokeringsstorleken och indexet måste fortfarande vara giltiga.

Undersök sedan deklarationerna runt omkring

WinINet-inställningarna per anslutning innehåller en union vars medlemmar omfattar en DWORD, en strängpekare och en FILETIME. Pekarfält behöver IntPtr; DWORD-fält förblir 32-bitars. Inbyggd justering spelar roll, så att ersätta varje heltal med ett 64-bitars heltal eller tvinga fram en packad layout är inte en sund reparation.

Använd den marshallade strukturstorleken när du går igenom arrayen, matcha ANSI- eller Unicode-deklarationen konsekvent och spåra varje allokering separat. Att frigöra blocket med inställningsstrukturer frigör inte automatiskt strängar som allokerats någon annanstans och refereras av dessa strukturer.

Slutligen, håll frågan om inställningarnas omfattning åtskild från minneskorrekthet. Att reparera en cast bevisar inte att en hjälpares valda WinINet-inställning bara påverkar en kontroll, en process eller den aktuella användarens inställningar. Kontrollera det API-beteendet innan du antar resten av ett gammalt exempel. Om den också skickar uppdateringsmeddelanden, välj dem för det avsedda omfånget.

Relaterade artiklar