2015-04-17 3 views
3

Я унаследовал старое приложение Borland C++ Builder, которое теперь необходимо перенести в новый инструмент разработки. Предлагаемый способ - с Embarcadero C++ Builder, и из моих первоначальных тестов это выглядит довольно плавным.AnsiString по умолчанию для строки типа в 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), поэтому ...

+0

Нет ничего плохого в использовании' UnicodeString' для этой цели. 'UnicodeString' и' AnsiString' являются специализациями шаблона 'AnsiStringT', где параметр шаблона является кодовой страницей. –

ответ

4

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

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

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

string (в нижнем регистре ы) относится к классу std::string в STL, который до сих пор 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, многие из старых функций RTL были перемещены в отдельный блок System.AnsiStrings, поэтому вы можете добавить #include <System.AnsiStrings.hpp> в свой код, чтобы достичь их.

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

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

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

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

+0

Не совсем быстрое решение, на которое я надеялся , но я знал, что это был длинный выстрел. Действительно хороший и обширный ответ, тем не менее! Я сейчас понимаю проблему и имею достаточно подсказок, чтобы поверить я могу снять это без лишней работы. Так что спасибо, Реми! – Boise

1

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

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

Ну ... Я ненавижу строк в Борланд. Кто, черт возьми, придумал их номер от 1 вместо 0?

+0

Строки Delphi являются 1-индексированными (за исключением мобильных платформ, где по умолчанию они индексируются по 0, но для этого есть директива компилятора Dephi). Структуры RTL/VCL/FMX написаны в Delphi , а не в C++. Классы C++ 'System :: AnsiString' и' System :: UnicodeString' - это просто совместимые оболочки для собственных типов строк Delphi, поэтому они должны использовать ту же индексацию. –

0

AnsiString -s может быть преобразован в UnicodeString -s легко. Так я обработал конверсию. Старый 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. ", но я не мог его использовать.

Смежные вопросы