Чому старий помічник проксі WinINet ламається в 64-бітній збірці
Розпізнавайте усікання вказівників у прикладах interop проксі на C# і перевіряйте розташування структур та володіння пам'яттю, перш ніж використовувати їх повторно.
Одне приведення типу може перетворити звичайний на вигляд помічник налаштувань проксі на збій, що залежить від архітектури:
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, перш ніж приймати решту старого прикладу. Якщо він також надсилає сповіщення про оновлення, виберіть їх для потрібної області.