В статье мы рассмотрим типичную проблему, с которой сталкиваются разработчики, работающие с функциями Internet Explorer в среде Delphi. Примером такой проблемы служит ошибка, возникающая при использовании функции GlobalFree с типом PWideChar, что приводит к несовместимости типов. Мы подробно разберем этот случай и предложим решение, а также рассмотрим альтернативные подходы.
Описание проблемы
Разработчик столкнулся с ошибкой при попытке освободить память, выделенную для строк в структуре WINHTTP_CURRENT_USER_IE_PROXY_CONFIG. Документация функции WinHttpGetIEProxyConfigForCurrentUser указывает, что каллер должен освободить строки lpszProxy, lpszProxyBypass и lpszAutoConfigUrl, если они не равны NULL, используя функцию __GlobalFree__. При вызове GlobalFree с указателем на строку возникла ошибка несовместимости типов: ожидался тип NativeUInt, а был передан PWideChar.
Пример кода, вызывающего ошибку
var
VConfig: TWinHttpCurrentUserIEProxyConfig;
begin
FillChar(VConfig, SizeOf(VConfig), 0);
if not WinHttpGetIEProxyConfigForCurrentUser(VConfig) then
RaiseLastOSError;
...
if VConfig.lpszAutoConfigUrl <> nil then
GlobalFree(VConfig.lpszAutoConfigUrl); // Ошибка
end;
Возможные решения
Приведение типов: Необходимо ли привести указатель на строку к типу NativeUInt?
Использование GlobalFreePtr: Можно ли использовать функцию GlobalFreePtr, которая принимает PWideChar, и работает корректно в тестах разработчика?
Подтвержденное решение
Согласно документации, если функция требует использования определенного метода освобождения памяти, то следует придерживаться этого требования. В случае использования HGLOBAL, функция GlobalFlags может помочь в определении необходимости блокировки памяти перед доступом к ней. В случае с рассматриваемой строкой, если она была выделена как перемещаемая, документация должна была бы указать на необходимость блокировки перед доступом, но такого указания нет.
В коде Delphi необходимо использовать приведение типов к HGLOBAL:
GlobalFree(HGLOBAL(VConfig.lpszAutoConfigUrl));
Это действие обусловлено тем, что GlobalFree объявлен в Windows.pas как принимающий HGBLOAL, который, в свою очередь, является псевдонимом для THandle, а THandle - псевдоним для NativeUInt. Однако, с точки зрения семантики, лучше привести к HGLOBAL, чтобы избежать возможных проблем в будущем.
Заключение
При работе с функциями Internet Explorer в Delphi важно внимательно изучать документацию и следовать указаниям по освобождению памяти. В случае возникновения ошибок, следует рассмотреть возможность приведения типов или использования альтернативных функций, таких как GlobalFreePtr, если это допустимо и подтверждено тестами.
В статье рассматривается проблема освобождения памяти в Delphi при работе с функциями Internet Explorer, связанная с несовместимостью типов при использовании функции `GlobalFree` для строк.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS