Как преобразовать argv в широкие символы в приложении командной строки Win32?

Я использую win32 API для C в своей программе для чтения из последовательного порта, это кажется довольно низкоуровневым материалом. Предполагая, что нет лучшего способа чтения из последовательного порта, функция CreateFile использует аргумент LPCWSTR, я читал, и похоже, что LPCWSTR является типом wchar_t. Во-первых, я не совсем понимаю разницу между wchar и char, я читал про ansi и unicode, но не знаю, как это применимо к моей ситуации.

Моя программа использует основную функцию, а не wmain, и ей необходимо получить аргумент из командной строки и сохранить его в переменной wchar_t. Теперь я знаю, что мог бы сделать это, если бы просто сделал нить на месте;

wchar_t variable[1024];
swprintf(variable,1024,L"%s",L"randomstringETC");

Потому что похоже, что L преобразует массивы символов в массивы wchar. Однако это не работает, когда я это делаю;

wchar_t variable[1024];
swprintf(variable,1024,L"%s",Largv[1]);

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

Или есть способ полностью избежать этого материала Unicode и читать из серийного номера другим способом, используя C в Windows.


person Michael    schedule 07.09.2011    source источник


Ответы (3)


L предназначен только для строковых литералов.

Вам нужно преобразовать строку argv (предположительно беззнаковый символ) в wchar, используя что-то вроде функции winapi mbstowcs().

person myforwik    schedule 07.09.2011
comment
гораздо проще использовать основную функцию широкого символа - person David Heffernan; 07.09.2011
comment
@David: Не только проще, но и правильно. Если вы не используете wmain, вы должны получить командную строку с помощью GetCommandLineW — получение аргументов из main неверно, поскольку это не строки Unicode. - person Philipp; 10.09.2011

Нет функции winapi с именем CreateFile. Есть CreateFileW и CreateFileA. CreateFile — это макрос, который сопоставляется с одной из этих реальных функций в зависимости от того, определен ли макрос _UNICODE. CreateFileW принимает LPCWSTR (он же const wchar_t*), CreateFileA принимает LPCSTR (он же const char*).

Если вы еще не готовы перейти на Unicode, просто явно используйте функцию CreateFileA(). Или измените настройку проекта: «Проект + Свойства», «Общие», «Набор символов». Там ненулевая стоимость, базовая операционная система полностью основана на Unicode. Таким образом, CreateFileA() проходит через слой перевода, который превращает const char* в const wchar_t* в соответствии с текущей кодовой страницей системы.

person Hans Passant    schedule 07.09.2011
comment
Ого приятно! У меня уже есть работа с файлом создания юникода, поэтому я не думаю, что его стоит менять. Хотя это единственная часть моей программы, которая использует wchars. Как вы думаете, было бы хорошей идеей изменить его на createfileA с точки зрения аккуратности/однородности кода? - person Michael; 07.09.2011
comment
Нет, не совсем. Не использовать Unicode в операционной системе, которая полностью использует Unicode на языке, который вы обычно выбираете из соображений скорости, для меня не имеет особого смысла. Тем не менее, шумиха вокруг макросов явно предназначалась для поддержания работы старых программ на C. Некоторый акцент на старом. - person Hans Passant; 07.09.2011
comment
«Если вы еще не готовы перейти на Unicode» — тогда вам стоит подумать об изобретении машины времени и совершить путешествие на 20 лет назад во времени ;-) - person Philipp; 10.09.2011

MultiByteToWideChar можно использовать для ANSI в UNICODE. Чтобы выполнить вызов swprintf, вам нужно определить массив wchar следующим образом:

WCHAR lala[256] = {0};
swprintf(lala, _countof(lala), L"%s", Largv[1]);

Можно избежать юникода, скомпилировав ваше приложение с многобайтовым набором символов, но это плохая практика, если только вы не делаете это по устаревшим причинам. В какой-то момент Windows все равно потребуется преобразовать его обратно в Unicode, потому что это кодировка базовой ОС.

person Mike Kwan    schedule 07.09.2011
comment
Извините, я неправильно записал код, он должен быть переменным[1024]; В любом случае, Largv[1] не работает, как объяснил myforwik. - person Michael; 07.09.2011
comment
Вы назвали его Largv, поэтому я предположил, что это уже юникод. Вы можете преобразовать либо с помощью указанной им функции, либо с помощью MultiByteToWideChar - person Mike Kwan; 07.09.2011