C ++ Builder — AnsiString по умолчанию для типа строки в Embarcadero C ++ Builder?

Я унаследовал старое приложение Borland C ++ Builder, которое теперь необходимо перенести в новый инструмент разработки. Предлагаемый способ — использовать Embarcadero C ++ Builder, и из моих первоначальных тестов это выглядит как довольно плавный переход.

Однако у меня есть одна проблема, на которую, я надеюсь, есть простое решение:

Приложение анализирует большое количество текстовых файлов. Все эти файлы основаны на ANSI, и это никогда не изменится, поэтому это ANSI в и ANSI вне. Основная проблема у меня заключается в том, что с Embarcadero C ++, тип string сейчас UnicodeString вместо AnsiString (как это было в Borland C ++ Builder).

Использование Unicode в этом приложении не вариант — файлы, с которыми он работает, имеют формат ANSI. Изменение кода для использования AnsiString (и тому подобное) выполнимо, но я бы предпочел, потому что он использует много TStringList (и аналогичные) конструкции.

Итак, мой вопрос: есть ли параметр или опция компилятора или что-то, что я могу использовать, чтобы сказать Embarcadero, чтобы использовать System.AnsiString как определение для string вместо System.UnicodeString?

Вероятно, это длинный путь, но в документации RAD Studio XE (более старой версии, которую я позаимствовал для нескольких тестов) говорится:по умолчанию, тип string теперь является строкой Unicode «, что подразумевает, что это можно изменить. Однако это перефразировано в документации для текущей версии (XE8), так что …

3

Решение

Я унаследовал старое приложение Borland C ++ Builder, которое теперь необходимо перенести в новый инструмент разработки. Предлагаемый способ — использовать Embarcadero C ++ Builder.

Да. Они на самом деле один и тот же продукт. Borland создала дочернюю компанию CodeGear для управления инструментами разработчика (Delphi, C ++ Builder и т. Д.), А затем Embarcadero приобрела CodeGear.

Основная проблема у меня заключается в том, что в Embarcadero C ++ строка типа теперь представляет собой UnicodeString вместо AnsiString (как это было в Borland C ++ Builder).

string (строчные буквы) относится к STL std::string класс, который до сих пор char-основан. Вы думаете о C ++ Builder System::String псевдоним, который теперь отображается на System::UnicodeString вместо System::AnsiString (это изменение было сделано в C ++ Builder 2009, когда UnicodeString был представлен). Тем не мение, AnsiString все еще существует и может быть использован напрямую.

Использование Unicode в этом приложении не вариант — файлы, с которыми он работает, имеют формат ANSI.

Тогда не используйте UnicodeString обрабатывать их. Продолжайте использовать AnsiString вместо.

Модификация кода для использования AnsiString (и аналогичных) выполнима, но я бы предпочел этого не делать, поскольку он использует множество конструкций TStringList (и аналогичных).

Это, с другой стороны, было бы проблемой, да. Большая часть RTL поддерживает только UnicodeString сейчас. Так что используйте код TStringList придется переписать, например, используя TList<AnsiString> или же std::vector<AnsiString> вместо этого (если код не использует TStringList::(Comma|Delimited)Text свойства, в этом случае у вас есть больше переписать). Однако для AnsiString парсинг кода, многие старшие AnsiStringRTL-функции были перенесены в отдельный System.AnsiStrings блок, так что вы можете добавить #include <System.AnsiStrings.hpp> к вашему коду, чтобы добраться до них.

Итак, мой вопрос: есть ли параметр или опция компилятора или что-то, что я могу использовать, чтобы сказать Embarcadero использовать System.AnsiString как определение для строки вместо System.UnicodeString?

Нет. И если вы подумаете об этом, это будет серьезное обязательство для их реализации. Несколько копий платформ RTL / VCL / FMX, по 2 на каждую поддерживаемую платформу ОС. И много внутреннего кода должно быть IFDEF для обработки различий между логикой обработки Ansi / Unicode. Так что это не реально выполнимо или экономически выгодно для них (и слишком поздно на этом этапе, особенно учитывая, что AnsiString не поддерживается на платформах мобильных ОС — хотя есть сторонний патч для его повторного включения).

Это, вероятно, длинный путь, но в документации RAD Studio XE (которая является более старой версией, которую я позаимствовал для проведения нескольких тестов) говорится «по умолчанию строка типа теперь является строкой Unicode», что подразумевает, что это может быть изменен.

Нет, это не может быть изменено. Платформы RTL / VCL / FMX теперь являются Unicode. Но это не требует, чтобы ваш код также был Unicode. Только в тех местах, где вам нужно напрямую взаимодействовать с RTL / VCL / FMX. Остальная часть вашего кода может продолжать использовать AnsiString (или даже std::string) по мере необходимости.

5

Другие решения

Возможно, у меня плохие новости. Они всегда говорят о миграции, а не о быстром решении.

http://docwiki.embarcadero.com/RADStudio/XE3/en/Enabling_Applications_for_Unicode
http://docwiki.embarcadero.com/RADStudio/XE3/en/Enabling_C%2B%2B_Applications_for_Unicode

Ну … я ненавижу Стрингс в Borland. Кто, черт возьми, придумал нумеровать их от 1 до 0 ?!

1

AnsiString-с можно конвертировать в UnicodeString-легко. Вот как я справился с конверсией. Старый код C ++ Builder 2007:

void __fastcall TFormVidya::lbEntData(TWinControl *Control, int Index, AnsiString &Data)
{
if(FEntNameSto) {
char *pc;
int len=FEntNameSto->PeekValue(Index,&pc);
Data.printf("DB %.*s",len,pc);
} else Data.sprintf("MOCK %d!",Index);
}

Преобразован для C ++ Builder XE2:

void __fastcall TFormVidya::lbEntData(TWinControl *Control, int Index, UnicodeString &Data)
{
if(FEntNameSto) {
char *pc;
int len=FEntNameSto->PeekValue(Index,&pc);
AnsiString astr;
astr.printf("DB %.*s",len,pc);
Data=astr;
} else Data.sprintf(L"MOCK %d!",Index);
}

Суть в назначении AnsiString для UnicodeString: Data=astr;,

Также на странице справки мс-помощь: //embarcadero.rs_xe2/libraries/System.UnicodeString.html (тот, который говорит «По умолчанию переменные, объявленные как тип String, являются UnicodeString.»), также говорит «Несмотря на свое имя, UnicodeString может представлять как строки набора символов ANSI, так и строки Unicode.«, но я не мог его использовать.

0