Я пишу слой-обертку для использования с mingw, который предоставляет приложению виртуальную среду UTF-8.Функции, которые имеют дело с именами файлов, являются обертками, которые конвертируют из UTF-8 и вызывают соответствующие функции "_w" и так далее.Большая проблема, с которой я столкнулся, заключается в том, что Windows wchar_t
является 16-битной.
Для операций с файловой системой это не имеет большого значения.Я могу просто конвертировать туда и обратно между UTF-8 и UTF-16, и все будет работать.Но стандартный API преобразования многобайтовых / широких символов в C не допускает использование символов multi-wchar_t.
Возможные решения:
- Обеспечение среды CESU-8 вместо UTF-8.Мне действительно не нравится этот.
- Выбери легкий путь и поддержи только BMP.Считайте недействительными последовательности UTF-8 длиной 4.
- Расширение оболочки для замены mingw
wchar_t
на typedef int32_t wchar_t;
и взаимодействие с WCHAR
и wchar_t
различными.Это боль, но она может быть идеальной для портирования приложений, которые ожидают чистой среды типа POSIX и не используют wchar_t
для каких-либо целей Windows-API. - Следующий взлом:
mbrtowc
выводит wchar_t
, соответствующий старшему суррогату после чтения первых 3 байтов 4-байтового символа UTF-8, и сохраняет оставшееся состояние в объекте mbstate_t
.Получив следующий байт, он объединяет его с сохраненным состоянием для вывода низкого суррогата.Если последний байт оказывается недействительным, он возвращает -1 (с EILSEQ) и одиночный суррогат заканчивается в выходном потоке (плохой ...).
wcrtomb
выводит первые 2 байта UTF-8, когда он обрабатывает верхний суррогат и сохраняет оставшееся состояние в своем mbstate_t
объекте.Когда он впоследствии обрабатывает низкий суррогат, он комбинирует это с сохраненным состоянием, чтобы вывести последние 2 байта UTF-8.Если действительный низкий суррогат не получен, он возвращает -1 (с EILSEQ) и неполная последовательность UTF-8 заканчивается в выходном потоке (плохой ...).
Плюс этого хакачто он работает до тех пор, пока ввод действителен, и разрешает доступ к любому символу UTF-8 и, следовательно, к любому возможному имени файла / аргументу и т. д.текст, с которым может потребоваться приложение.
Недостатки в том, что он не полностью соответствует ISO C (строка wchar_t
не может быть сохранена с состоянием) и задерживает обнаружение искаженных символов до неправильного частичного выводауже написано.
Я ищу отзывы о различных вариантах, и особенно о моем предложенном хакере: разумно ли это, могут ли недостатки вызывать серьезные ошибки, и есть ли другие недостатки, которые яеще не обдумал, что может помешать работе схемы полностью.Я также был бы рад услышать любые другие возможные решения, о которых я не думал.