Зашто стари WinINet прокси помоћник пуца у 64-битном билду
Препознајте одсецање показивача у C# прокси interop примерима и прегледајте распоред структура и власништво над меморијом пре поновне употребе.
Једно претварање може наизглед обичан помоћник за прокси поставке претворити у квар који зависи од архитектуре:
current = (IntPtr)((int)current + optionSize);
Тај код сужава изворну адресу на 32-битни цео број пре додавања величине следеће структуре. 64-битни процес може да држи адресе које се не уклапају. У зависности од претворбе и вредности, резултат може бити изузетак преливања или неважећа адреса. Враћање билда на x86 може сакрити грешку, али оставља interop имплементацију зависном од тог заобилазног решења.
Држите адресе у облику величине показивача. На пример, кретање кроз већ додељени низ може користити:
IntPtr item = IntPtr.Add(buffer, checked(index * optionSize));
Померај остаје цео број; сама адреса се не протискује кроз њега. Величина доделе и индекс и даље морају бити важећи.
Затим прегледајте околне декларације
WinINet опције по вези садрже унију чији чланови укључују DWORD, показивач на стринг и FILETIME. Поља показивача требају IntPtr; DWORD поља остају 32-битна. Изворно поравнање је важно, па замена сваког целог броја 64-битним целим бројем или присилно паковање распореда није исправан поправак.
Користите величину структуре након маршалинга када пролазите кроз низ, доследно ускладите ANSI или Unicode декларацију и пратите сваку доделу засебно. Ослобађање блока структура опција не ослобађа аутоматски стрингове додељене другде на које те структуре упућују.
Коначно, одвојите питање обима поставки од исправности меморије. Поправка претварања не доказује да изабрана WinINet опција утиче само на једну контролу, један процес или поставке тренутног корисника. Проверите то понашање API-ја пре него што прихватите остатак старог примера. Ако такође шаље обавештења о освежавању, изаберите их за предвиђени обим.