오래된 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 동작을 확인하세요. 새로 고침 알림도 보낸다면 의도한 범위에 맞게 선택하세요.