В данной статье мы рассмотрим проблему, связанную с функцией FillChar и StringOfChar в среде разработки Delphi 10.2 для 64-битных приложений. Эта проблема проявляется на старых процессорах, выпущенных до 2012 года, и заключается в неправильной работе данных функций. Ожидается, что FillChar создает последовательность повторяющихся 8-битных символов в заданном буфере памяти, а StringOfChar - аналогичную последовательность, но сохраненную в виде строки. Однако в реальности, начиная с версии Delphi 10.2, эти функции возвращают строку различного содержимого, хотя и в повторяющемся порядке. Это происходит после компиляции приложений, которые ранее работали в версиях Delphi, предшествующих 10.2.
Основная часть
Описание ошибки и пример кода
Ошибка проявляется в следующем примере кода:
procedure TestStringOfChar;
var
a: AnsiString;
ac: AnsiChar;
begin
ac := #1;
a := StringOfChar(ac, 43);
if a <> StringOfChar(#1, 43.Length) then
begin
raise Exception.Create('ANSI StringOfChar Failed!!');
end;
end;
Данный код предполагает, что функция StringOfChar создаст строку из 43 повторяющихся символов, обозначенных как код #1, но на практике это не так. При этом, для воспроизведения ошибки, длина последовательности должна быть не менее 16 символов, а используемый символ не должен быть нулевым.
Решение проблемы
Разработчик, столкнувшийся с данной проблемой, обратился в службу поддержки Embarcadero, но на момент обновления вопроса ответ так и не был получен. Однако, после дополнительных тестов и обновления вопроса, было обнаружено, что проблема связана с использованием определенного бита в таблице CPUIDTable, отвечающего за расширенный режим обработки строк (ERMS). Установка этого бита в 0 позволяет воспроизвести ошибку даже на новых процессорах, выпущенных после 2012 года.
Для решения проблемы можно использовать следующий код:
const
ERMSBBit = 1 shl 9; {$0200}
begin
CPUIDTable[7].EBX := CPUIDTable[7].EBX and not ERMSBBit;
end;
Это изменение позволяет функции FillChar работать корректно, используя простой алгоритм REP STOSB для заполнения памяти.
Альтернативное решение
Также было предложено альтернативное решение, заключающееся в использовании функции FillChar из внешнего модуля FastSystem, который представляет собой альтернативную реализацию данной функции с улучшенной производительностью. Для использования этой функции необходимо скачать и включить в свой проект модуль SynCommons.pas из проекта Mormot.
Подтвержденное решение
Embarcadero подтвердило наличие проблемы и исправило ее в релизе Delphi 10.2 Tokyo Release 1, который был выпущен 8 августа 2017 года. Это означает, что для устранения ошибки достаточно обновить среду разработки до последней версии.
Заключение
В данной статье была рассмотрена проблема, связанная с неправильной работой функций FillChar и StringOfChar в Delphi 10.2 для 64-битных приложений на старых процессорах. Представлены временные решения для устранения ошибки, а также подтверждено, что проблема была исправлена в релизе Tokyo Release 1. Разработчикам, столкнувшимся с аналогичными проблемами, рекомендуется обновить среду разработки до последней версии для получения исправления.
В статье рассматривается проблема, связанная с некорректным функционированием функций `FillChar` и `StringOfChar` в среде разработки Delphi 10.2 Tokyo для 64-битных приложений на старых процессорах, выпущенных до 2012 года, и предлагаются решения для её
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.