Разница и преобразования между wchar_t для Linux и для Windows

Я понимаю из это и эта ветка, в Windows wchar_t является 16-битным, а для Linux wchar_t — 32-битным.

У меня клиент-серверная архитектура (с использованием только каналов, а не сокетов), где мой сервер основан на Windows, а клиент - на Linux.

Сервер имеет API для получения имени хоста от клиента. Когда клиент основан на Windows, он может просто выполнить GetComputerNameW и вернуть Wide-String. Однако, когда клиент основан на Linux, все становится запутанным.

В качестве первого наивного подхода я использовал mbstowcs(), надеясь вернуть wchar_t* на серверную часть Windows. Однако этот LPWSTR (у меня есть typedef wchar_t* LPWSTR на стороне моего Linux-клиента) не распознается в Windows, поскольку он ожидает, что его wchar_t будет 16-битным.

Итак, преобразование вывода gethostname() в linux - который находится в char * в unsigned short (16-битный) - мой единственный вариант?

Заранее спасибо!


person sskanitk    schedule 27.11.2012    source источник
comment
Какой у вас формат передачи текста?   -  person chill    schedule 28.11.2012
comment
использовать либику. Вам нужно будет преобразовать окна UCS-2 в UCS-4 Linux, файловую систему UTF-8 linux и т. д.   -  person neagoegab    schedule 28.11.2012
comment
Как насчет того, чтобы попробовать UTF-8 Everywhere? Ваш код Linux будет чистым, а часть Windows будет легко взаимодействовать с остальной частью вашего приложения.   -  person Yakov Galka    schedule 28.11.2012


Ответы (2)


Вам нужно будет выбрать фактический протокол для передачи данных по сети. Здесь несколько вариантов, хотя, вероятно, UTF-8, как правило, является наиболее разумным - также это означает, что под Linux вы можете просто использовать данные как есть (нет причин использовать wchar_t для начала, хотя вы, очевидно, можете преобразовать его во что угодно) хотеть).

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

Очевидно, вы можете выбрать любую кодировку, которую вы хотите, не обязательно UTF-8, процесс тот же: при получении данных конвертируйте их в собственный формат ОС, а при отправке конвертируйте их в вашу кодировку по сети. iconv работает в Linux, если вы не используете utf-8.

person Voo    schedule 27.11.2012
comment
как вы будете отображать UTF-8 на linux, GUI? - person neagoegab; 28.11.2012
comment
@neagoegab Это во многом зависит от того, какую графическую библиотеку вы на самом деле используете, не так ли? Но QT, например, позволяет пользователям прекрасно использовать UTF-8, даже если он внутренне использует UTF-16 для представления данных. - person Voo; 28.11.2012

Лучше всего выбрать стандартную кодировку символов для данных, которые вы отправляете по каналу, а затем потребовать, чтобы все машины отправляли свои данные с использованием этой кодировки.

Windows использует UTF-16LE, поэтому вы можете использовать UTF-16LE по каналу, а затем машины Windows могут отправлять свои строки в кодировке UTF-16LE как есть, но машины Linux должны будут конвертировать в/из UTF-16LE по мере необходимости.

Или вместо этого вы можете выбрать UTF-8, что уменьшит пропускную способность сети, но компьютеры с Windows и Linux должны будут конвертировать в/из UTF-8 по мере необходимости. Для сетевых коммуникаций лучшим выбором будет UTF-8.

В Windows вы можете использовать MultiByteToWideChar() и WideCharToMultiByte() с кодовой страницей CP_UTF8.

В Linux используйте iconv() API, чтобы вы могли указать кодировку UTF-8 для кодирования/декодирования.

person Remy Lebeau    schedule 27.11.2012
comment
На самом деле не вижу причин использовать wchar_t под Linux для начала. Только вызывает проблемы, и я не могу вспомнить много API, которые не используют UTF-8 и просто возвращают char* для начала. - person Voo; 28.11.2012