gokings Ответов: 1

Преобразование в Unicode (C++, Microsoft, UTF-16, Native Windows)


ИЩУ СОВЕТ ОТНОСИТЕЛЬНО ПРЕОБРАЗОВАНИЯ В ЮНИКОД


ПОЧЕМУ Я ТАК ПОЗДНО ПРИНИМАЮ ЮНИКОД

[Не стесняйтесь переходить к "ситуации" ниже, но если вы это сделаете, пожалуйста, не увольняйте меня за "ожидание так долго".]

Я бывший профессиональный инженер-программист и программист.

Я был "далеко" от программирования в течение многих лет из-за медицинских соображений.

Я "ушел" как раз тогда, когда переход на Юникод стал мейнстримом.

В последнее время я начал возиться с программированием.

С момента моего "возвращения к программированию" я продолжал работать только со сборками MBCS.

[Из-за моего состояния любое преобразование в Юникод будет намного большим делом, чем если бы я был здоров.]

После моего "возвращения" (такого, как оно есть) я прочитал о unicode.

Мне казалось ясным, что UTF-8-это "путь к успеху".

Я предположил, что UTF-8 был принят практически повсеместно.

Я был очень удивлен (и разочарован), узнав, что Microsoft "пошла с" UTF-16.



МОЯ СИТУАЦИЯ С КОДИРОВАНИЕМ


Мои проблемы связаны с преобразованием в Юникод в следующей среде:

Язык: C++
Целевая Платформа: Собственные Окна
Инструмент Разработки: Visual Studio 2013

У меня есть много строк исходного кода C++ (сотни тысяч, почти наверняка) как в библиотеках, так и в приложениях.

Кроме того, я использую сторонние библиотеки (для которых у меня также есть исходный код). Некоторые из них относительно актуальны, так как я проделал некоторую работу (MBCS) с момента моего "возвращения к программированию".


ОСНОВНАЯ ПРОБЛЕМА СО СБОРКАМИ UNICODE


А) каждое взаимодействие с Windows API требует UTF-16 strings+.

B) однако сторонние библиотеки, которые я использую, принимают char*.


Для каждой отдельной переменной "строкового типа" я должен решить, должна ли она быть "char" или "TCHAR" (или string или wstring).

Для каждого строкового литерала я должен решить, должен ли он быть а) обернут макросом, Б) префиксом, в) ни тем, ни другим. [В основном, родной char*, или UTF-16.]

Это относится не только к новому коду, но и к существующему коду (существующий код, вероятно, содержит более 100 000 экземпляров таких переменных и литералов).

[Игнорируйте сейчас, что я хочу иметь возможность делать как MBCS, так и unicode сборки. Но дело не в этом. Представьте, что я буду делать только сборки unicode.]


Для каждого отдельного вызова функции или метода я должен убедиться, что передаются ожидаемые строковые типы.


Кодовая база состоит из 4 "категорий": А) Windows API, Б) сторонний API/код, в) мои библиотеки, г) Мои приложения.


Строки "передаются повсюду" внутри кодовой категории и между ними.


Было бы намного лучше, если бы все функции (Windows API, мой код, сторонний код) использовали один и тот же тип строки/символа.


Однако я не могу очень хорошо конвертировать сторонние библиотеки для использования TCHAR, _T () и т. д.

Мне придется делать это каждый раз, когда будет выпущена новая версия библиотеки.

[Кстати, одна библиотека, которую я использую, - это Boost.]

В дополнение к необходимости выбирать "правильный" строковый тип для каждой переменной и литерала, похоже, мне придется добавить большое количество вызовов преобразования строк в мой код, постоянно конвертируя между UTF-16 и UTF-8/ASCII.

Мне кажется, что Microsoft создала кошмар программирования, Перейдя на UTF-16.

Кроме того, мне кажется, что они избежали относительно незначительных неудобств для себя (для поддержания совместимости DLL), причинив абсурдно высокую стоимость разработчикам, не являющимся Microsoft.

Я что-то упустил?

Если бы Microsoft просто "пошла с" UTF-8, UTF-8 можно было бы передать "везде". Весь этот кошмар исчезнет. Это была бы сама простота.

[Да, какой-то сторонний код (в то время) мог неправильно работать с многобайтовыми символами UTF-8. Однако для этого его можно было бы обновить.]



Как мне подойти к преобразованию?


А) использовать "инфраструктуру" UTF-16 и писать обертку вокруг каждой сторонней библиотеки?

Б) использовать "инфраструктуру" UTF-8 и написать оболочку вокруг Windows API?

Например, класс CEditUTF8, как выпадающая замена для CEdit.

В) определите индивидуально для каждой строковой переменной и литерала соответствующий тип и добавьте специальные вызовы функций преобразования строк по всему моему коду?


Мне кажется, что Microsoft приняла феноменально эгоистичное решение, перейдя на UTF-16 (который должен был быть отвергнут сообществом разработчиков).


Может быть, я ошибаюсь.


Может быть, я что-то упускаю.


Мне кажется, что даже если бы не было проблемы со сторонней библиотекой, решение "пойти с" UTF-16 сильно усложняет исходный код.

Проблема совместимости с третьей стороной делает ситуацию по крайней мере в 10 раз хуже.

Для нового кода почти половина моих усилий по программированию будет связана с проблемами строкового типа.

В дополнение к "смешанным" строкам, делающим код намного более запутанным, существует неэффективность из-за преобразований.

Если я приму решение (C), преобразование существующего кода может потребовать проверки каждого использования ключевого слова "char", каждого использования строки и т. д.


Еще одно соображение: я предпочитаю сделать свой библиотечный код переносимым, если это возможно (чтобы изолировать код, зависящий от ОС). Эта проблема со строками усложняет написание переносимого кода.

Теперь даже код, полностью независимый от операционной системы, должен содержать "Микрософтимы", чтобы обратиться к ним.
проблемы со строковым/символьным типом.


Все могло бы быть так просто.




Комментарии? Предложения? Насмешка? Смеется? Оскорбления? Сочувствие? Соглашение?


С. П.

Я написал утилиту для обертывания строковых литералов с помощью _T() **. Однако он не может определить, какие литералы нужно обернуть (он недостаточно умен, чтобы проанализировать исходный код и определить типы переменных, которым присваивается литерал). Даже если бы это было возможно, это не решило бы проблемы типов переменных или вызовов преобразования.


** Это не было сделано с помощью поиска и замены регулярных выражений:


Во - первых, было слишком много исключений (включая директивы, различные макросы, встроенные двойные кавычки, комментарии-как//, так и /**/ - и различные другие "особые случаи").

Во-вторых, Visual Studio search and replace прослушивается: поиск и замена в файлах не работает, если включены регулярные выражения (я использовал SED, чтобы обойти это).

1 Ответов

Рейтинг:
1

Michael Haephrati

Вот большинство этапов, которые необходимо выполнить при преобразовании старого проекта (определяется как

Use Multi-Byte Character Set

или
Not Set

в проекте -> Свойства -> Общие -> набор символов.

Сначала вы устанавливаете этот атрибут в Юникод.

1. Тогда вам придется изменить какие-либо жестко заданных строк из "струны" в L"строка" / то _t("строка").
2. В некоторых местах Юникод должны быть использованы, вам придется заменить :
char something[];

в
wchar_t something[];

3. За этими строками Unicode, вы будете иметь, чтобы изменить функции работы со строками в Юникод. Например, вместо того, чтобы:
strcpy(str1,str2);
использовать
wcscpy(str1,str2);
и вместо этого
strcmp(str1,"")
использовать
wcscmp(str1,_T(""))
и так далее...
Если вы не уверены, пожалуйста, обратите внимание, что если вы, например, google:
"
strcpy unicode
"
вы попадете на страницу MSDN, где показан Юникод-эквивалент старой функции.

Рекомендации:

Краткое Описание Программирования В Юникоде

strcpy, wcscpy, _mbscpy


Richard MacCutchan

Опоздал на четыре года.

Michael Haephrati

По-видимому, у вопросов нет срока годности, и когда я искал вопросы без ответов, я попал сюда...

Richard MacCutchan

Правда, но вряд ли ОП все еще ждет ответа. Лучше перечислить все вопросы, чтобы вы обычно видели только те, которые в данный момент активны.

Richard Deeming

В обычной ситуации я бы согласился. Но на этот вопрос не было предварительных ответов, и даже если ОП двинулся дальше, это решение может помочь кому-то еще, кто найдет этот вопрос.

Обязательный XKCD[^]. :)

Michael Haephrati

Спасибо за совет. Я не видел никаких признаков того, что этот вопрос неактивен. Я очень надеюсь, что мой ответ послужит другим, кто, возможно, ищет тот же вопрос...