Я унаследовал старое приложение 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), так что …
Я унаследовал старое приложение 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
парсинг кода, многие старшие AnsiString
RTL-функции были перенесены в отдельный 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
) по мере необходимости.
Возможно, у меня плохие новости. Они всегда говорят о миграции, а не о быстром решении.
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 ?!
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.«, но я не мог его использовать.