Как известно, в Дельфи есть три типа строк: ShortString, AnsiString, WideString. С первым типом всё ясно: это старый, ещё турбопаскалевский тип, содержащий однобайтовые символы, имеющий фиксированную максимальную длину и фактически являющийся массивом. С WideString тоже в общем всё ясно: строка переменной длины, состоящая из двухбайтовых символов и физически размещаемая в динамической памяти, причём о выделении/освобождении памяти заботится компилятор без явного вмешательства программиста.
А вот AnsiString вызывает вопросы. Какая длина хранящихся в ней символов в байтах? Как соотносятся строки этого типа со стандартной однообайтовой ANSI-кодировкой и с юникодом? Что такое многобайтовые системы символов и с чем их едят?
Просьба знакомых с этой темой поделиться ссылками на вразумительные описания, касающиеся как Дельфи, так и FPC.
Разные типы строк и символов
Модератор: Модераторы
Так, с кодировками разобрался, спасибо добрым людям: http://ru.wikipedia.org/wiki/UTF-8. Осталось разобраться с тем, как конкретно всё это поддерживается компиляторами и библиотеками...
По умолчанию в Делфи тип String это и есть AnsiString - по-сути указатель на строку(массив) в памяти, с однобайтовыми символами, заканчивающююся нулём. Сам указатель, если не ошибаюсь хитрый, содержит в себе ещё и длину строки. Вообще это такой же тип как и WideString только каждый символ один байт в кодировке ANSI, а WideString имеет кодировку UTF-16. Вродь так...
... А вообще компилятору, если не ошибаюсь, плевать на кодировку, если только ты не создаёш строковых констант. Так ты можеш хранить в AnsiString-е текст с любой другой однобайтовой кодировкой
... А вообще компилятору, если не ошибаюсь, плевать на кодировку, если только ты не создаёш строковых констант. Так ты можеш хранить в AnsiString-е текст с любой другой однобайтовой кодировкой
Судя по дельфозному хелпу (для дельфи 2006), AnsiString вовсе не обязательно является строкой однобайтовых символов -- такие символы являются лишь частным случаем. Имеется целый ряд функций, который принимает параметры типа AnsiString, но считает, что строки закодированы в UTF-8 (переменная длина символа) -- эти функции с Ansi начинаются.
А двухбайтовые строки (WideString) -- это, судя по всему, не UTF-16 (где бывают двух- и четырёхбайтовые символы), а UCS-2 (подмножество UTF-16, включающее только двухбайтовые символы).
AnsiString включают не только указатель на собственно строку, но ещё и длину строки, и счётчик её использования. В WideString есть длина строки, но счётчика использования нет, т.е. присваивание одной строки другой неизбежно вызывает полное копирование всей строки, что не есть хорошо.
Вот интересно, как с этим дело во ФриПаскале обстоит? И какую часть работы по обслуживанию строк выполняет компилятор, а какую -- его библиотека (которую можно переписать без внесения изменений в компилятор)?
А двухбайтовые строки (WideString) -- это, судя по всему, не UTF-16 (где бывают двух- и четырёхбайтовые символы), а UCS-2 (подмножество UTF-16, включающее только двухбайтовые символы).
AnsiString включают не только указатель на собственно строку, но ещё и длину строки, и счётчик её использования. В WideString есть длина строки, но счётчика использования нет, т.е. присваивание одной строки другой неизбежно вызывает полное копирование всей строки, что не есть хорошо.
Вот интересно, как с этим дело во ФриПаскале обстоит? И какую часть работы по обслуживанию строк выполняет компилятор, а какую -- его библиотека (которую можно переписать без внесения изменений в компилятор)?
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
В FPC дела обстроят практически так же, как и в Дельфи. Но есть и определенная разница:
- WideString на всех платформах, кроме Windows, имеет счетчик ссылок - в точности как AnsiString. На Windows есть переменная winwidestringalloc, при установке которой в false память под WideString выделяется не Windows, а своей библиотекой. Из-за этого оно становится несовместимым с COM, но работает чуть побыстрее.
- За работу с WideString, в частности, перекодировку их в AnsiString и обратно, отвечает WideStringManager (переменная модуля system - запись из нескольких функций), который можно легким движением руки заменить на все что угодно. В Linux этот менеджер реализован в отдельном модуле cwstring, который надо подключать вручную.
- Функции, начинающиеся с Ansi*, находятся в зачаточном состоянии, потому что они просто никому никогда не были нужны. Строго говоря, функции работы с UTF-8 нужны, и они есть (модули freebidi, utf8bidi и еще, если поискать, найдется не одна), но FPC предполагался совместимым где-то с Дельфи 7, в котором Ansi*-функции работали не с utf-8, а черт знает с чем.
Так вот как-то, в общих чертах...
- WideString на всех платформах, кроме Windows, имеет счетчик ссылок - в точности как AnsiString. На Windows есть переменная winwidestringalloc, при установке которой в false память под WideString выделяется не Windows, а своей библиотекой. Из-за этого оно становится несовместимым с COM, но работает чуть побыстрее.
- За работу с WideString, в частности, перекодировку их в AnsiString и обратно, отвечает WideStringManager (переменная модуля system - запись из нескольких функций), который можно легким движением руки заменить на все что угодно. В Linux этот менеджер реализован в отдельном модуле cwstring, который надо подключать вручную.
- Функции, начинающиеся с Ansi*, находятся в зачаточном состоянии, потому что они просто никому никогда не были нужны. Строго говоря, функции работы с UTF-8 нужны, и они есть (модули freebidi, utf8bidi и еще, если поискать, найдется не одна), но FPC предполагался совместимым где-то с Дельфи 7, в котором Ansi*-функции работали не с utf-8, а черт знает с чем.
Так вот как-то, в общих чертах...
- *vmr
- постоялец
- Сообщения: 168
- Зарегистрирован: 08.01.2007 00:46:07
- Откуда: Киев
- Контактная информация:
>В fpc есть ф-ии Utf8Encode() и Utf8Decode(), для преобразования между AnsiString, в которой хранится переменно-байтовый utf8, и WideString, которая ucs16.
Кстати в дельфе тоже есть такие же функции
Правда эти ф-и лепят еще и отсябятину вроде byte-order и других служебных кодов (так обстоит в Delphi7, что в FPC я не знаю)
Кстати в дельфе тоже есть такие же функции
Правда эти ф-и лепят еще и отсябятину вроде byte-order и других служебных кодов (так обстоит в Delphi7, что в FPC я не знаю)
