Помощь в переносе с Multi-Byte на UNICODE в MFC

У меня есть что-то вроде утомительного от 6 месяцев до года впереди меня. Я работаю над программой с более чем миллионом строк кода (большая часть написана в начале/середине 90-х), и было решено, что теперь она должна поддерживать сборку UNICODE. Я исследовал и нашел много лучших практик:

  • используя версию _t многих методов Microsoft и C++, таких как _stprintf_s() вместо sprintf_s() или _tcsstr() вместо strstr(),
  • обертывание всех закодированных строк, которые должны быть TCHAR*, например, _T("string") или _T('c'),
  • замена большинства char* на LPTSTR и большинства const char* на LPCTSTR и char на TCHAR с использованием CA2T() и CT2A() для преобразования между char* и LPTSTR, если это необходимо,

Мне было интересно, написал ли кто-нибудь сценарий, способный автоматически вносить многие из этих изменений, поскольку они могут сэкономить мне МЕСЯЦЫ работы.


person Alex Londeree    schedule 14.06.2012    source источник
comment
Я думаю, что это помощь: mihai-nita.net/2007/12/19/   -  person chris    schedule 14.06.2012
comment
Если это реальное обновление и больше не требуется многобайтность, вам следует пропустить все _t и сразу перейти к wchar_t. _t и _T были разработаны как (временная) помощь около 15 лет назад.   -  person Bo Persson    schedule 14.06.2012
comment
Но есть ли причина не использовать _t и _T? Насколько я могу судить, _T() по-прежнему требуется для установки строк wchar_t, и использование LPWSTR против LPTSTR, похоже, не требует дополнительных усилий.   -  person Alex Londeree    schedule 15.06.2012
comment
@Alex: Нет, в wchar_t строках используются L"..." литералы.   -  person dan04    schedule 15.06.2012
comment
_T("") сопоставляется с L"", когда определено _UNICODE. Единственная причина для использования TCHAR и связанных с ними функций вместо wchar_t и связанных с ними функций заключается в том, что вам нужно создавать сборки ANSI и UNICODE из одного и того же исходного кода. Если вам нужно сохранить поддержку ANSI, используйте TCHAR и связанные с ним. Если вы собираетесь использовать только полный UNICODE, используйте wchar_t и связанные с ним. Вместо этого лучше использовать фреймворк Unicode, такой как ICONV или ICU, поскольку Unicode трудно понять правильно. Недостаточно просто изменить типы данных, иногда вам нужно изменить логику программы, чтобы учесть логические различия в том, как работают ANSI и UNICODE.   -  person Remy Lebeau    schedule 15.06.2012
comment
Да, можно легко изменить вызовы Windows API для использования UTF-16. Но собираетесь ли вы изменить форматы файлов, чтобы использовать UTF-16? И если вы полагаетесь на какие-либо библиотеки, не принадлежащие Microsoft, все они поддерживают UTF-16? Что, если они так же отстают в поддержке Unicode, как и ваш продукт? Zlib, например, не поддерживал wchar_t* имен файлов, пока пользователь StackOverflow не запросил это 3 месяца назад.   -  person dan04    schedule 15.06.2012
comment
Аналогично, OpenSSL по-прежнему вообще не поддерживает имена файлов в формате Unicode в Windows. Другие платформы используют файловые системы Ansi или UTF-8, поэтому OpenSSL нормально их обрабатывает, используя имена файлов на основе char*. Но в Windows библиотеке Indy с открытым исходным кодом (над которой я работаю) пришлось писать собственный набор функций, которые в основном являются копиями кода OpenSSL, но адаптированы для использования имен файлов на основе wchar_t* для поддержки UTF-16.   -  person Remy Lebeau    schedule 16.06.2012
comment
@RemyLebeau: другие платформы используют Ansi Нет. ANSI - это чисто термин Microsoft для набора проприетарных кодовых страниц, которые должны были быть стандартизированы ANSI, но затем ISO первой стандартизировала аналогичные (но не идентичные) кодовые страницы. Так что другая платформа использует ISO.   -  person Yakov Galka    schedule 17.06.2012
comment
В любом случае, char* может работать с кодировками ISO/ANSI, поэтому OpenSSL с радостью поддерживает эти кодировки, поскольку он просто передает значения char* как есть API-интерфейсам платформы, которые также принимают значения char*. В Windows это исключает любую возможность поддержки UTF-16. Это то, что я пытался сделать.   -  person Remy Lebeau    schedule 17.06.2012


Ответы (1)


Я думаю, что этот подход точно соответствует вашему сценарию.

Оставьте все свои строки узкими символами, используйте sprintf и strstr, как и раньше, читайте и записывайте из текстовых файлов, которые всегда предполагаются как UTF-8 без спецификаций и т. д. Все, что вам нужно изменить, это ваше взаимодействие с системой. Просто предположим, что строки имеют формат UTF-8, и перед вызовом MFC или Windows преобразуйте их в UTF-16 на лету.

В качестве бонуса вы получите более легкую переносимость на платформы, отличные от Windows, по сравнению с подходом, который отстаивает Microsoft.

person Yakov Galka    schedule 16.06.2012