Üks teisendus võib muuta näiliselt tavalise puhverserveri seadete abilise arhitektuurist sõltuvaks tõrkeks:

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

See kood kitsendab natiivse aadressi 32-biti suuruseks täisarvuks enne järgmise struktuuri suuruse liitmist. 64-bitine protsess võib hoida aadresse, mis ei mahu. Sõltuvalt teisendusest ja väärtusest võib tulemuseks olla ületäitumise erand või kehtetu aadress. Buildi tagasilülitamine x86-le võib vea peita, kuid jätab interopi teostuse sellest möödaviigust sõltuma.

Hoidke aadressid kursori suuruses. Näiteks juba eraldatud massiivis edasi liikumiseks saab kasutada:

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

Nihe jääb täisarvuks; aadressi ennast ei suruta sellest läbi. Eralduse suurus ja indeks peavad endiselt kehtivad olema.

Seejärel uurige ümbritsevaid deklaratsioone

WinINeti ühendusepõhised valikud sisaldavad liitu, mille liikmete hulka kuuluvad DWORD, stringi kursor ja FILETIME. Kursori väljad vajavad IntPtr; DWORD-väljad jäävad 32-bitiseks. Natiivne joondus on oluline, seega iga täisarvu asendamine 64-bitise täisarvuga või pakitud paigutuse pealesurumine ei ole korralik parandus.

Kasutage massiivi läbimisel marshaling-järgset struktuuri suurust, sobitage ANSI või Unicode'i deklaratsiooni järjekindlalt ning jälgige iga eraldust eraldi. Valikustruktuuride ploki vabastamine ei vabasta automaatselt mujal eraldatud ja nende struktuuride poolt viidatud stringe.

Lõpuks hoidke seadete ulatuse küsimus mälu korrektsusest lahus. Teisenduse parandamine ei tõesta, et abilise valitud WinINeti valik mõjutab ainult ühte juhtelementi, ühte protsessi või praeguse kasutaja seadeid. Kontrollige seda API käitumist enne vana näidise ülejäänu omaksvõtmist. Kui see saadab ka värskendusteateid, valige need kavandatud ulatuse jaoks.

Seotud artiklid