Преобразование строки в LPCWSTR для CreateFile () для адресации последовательного порта - PullRequest
4 голосов
/ 24 сентября 2010

Кажется, у меня возникла небольшая проблема TEXT / UNICODE при использовании функции Windows CreateFile для адресации последовательного порта.Может кто-нибудь, пожалуйста, помогите указать на мою ошибку?

Я пишу консольное приложение Win32 на VC ++, используя VS 2008.

Я могу создать дескриптор для адресации последовательного порта, например:

#include <iostream>    
#include <windows.h>
#include <string>

int main()
{

   HANDLE hSerial;

   hSerial = CreateFile( L"\\\\.\\COM20",
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         0,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         0);`

   return 0;
}

Это работает просто отлично (бит \\\\.\\ требуется для компиляторов, превышающих COM9, и работает также для тех, кто до COM9).Проблема в том, что мой компорт не всегда будет COM20, поэтому я бы хотел, чтобы пользователь указал, что это такое.

Вот некоторые вещи, которые я пробовал:

#include <iostream>    
#include <windows.h>
#include <string>

int main()
{
   std::string comNum;
   std::cout << "\n\nEnter the port (ex: COM20): ";
   std::cin >> comNum;
   std::string comPrefix = "\\\\.\\";
   std::string comID = comPrefix+comNum;

   HANDLE hSerial;

   hSerial = CreateFile( comID,
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         0,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         0);`

   return 0;
}

Это не компилируется и возвращает ошибку: ошибка C2664: «CreateFileW»: невозможно преобразовать параметр 1 из «std :: string» в «LPCWSTR»

Я подумал, что, возможно, определение CreateFileA будет работатьзатем, но это дало в основном ту же ошибку.

Я также пытался:

/*
everything else the same
*/   

hSerial = CreateFile( TEXT(comID),
                      GENERIC_READ | GENERIC_WRITE,
                      0,
                      0,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL,
                      0);`

, который также не компилируется и возвращает: ошибка C2065: 'LcomID': необъявленный идентификатор

Я не очень опытный специалист, но я уже давно работаю над этим.Может кто-нибудь сказать мне, как заменить L"\\\\.\\COM20" таким образом, чтобы пользователь мог указать comport и чтобы CreateFile все еще работал?Спасибо!

Ответы [ 6 ]

6 голосов
/ 24 сентября 2010

Вы можете использовать std::wstring и std::wcin, std::wcout, чтобы выполнить ввод непосредственно в «строках Unicode», или вы можете посмотреть функции преобразования Microsoft .

Есливы выбираете 1-й вариант (рекомендуется), вам все еще нужно использовать функцию c_str(), чтобы получить доступ к значению LPCWSTR (указатель на const wchar_t).

Пример решения (также не использоватьСинтаксис CreateFileW для предотвращения проблем с макросом UNICODE:

#include <iostream>    
#include <windows.h>
#include <string>

int main()
{
   std::wstring comNum;
   std::wcout << L"\n\nEnter the port (ex: COM20): ";
   std::wcin >> comNum;
   std::wstring comPrefix = L"\\\\.\\";
   std::wstring comID = comPrefix+comNum;

   HANDLE hSerial;

   hSerial = CreateFileW( comID.c_str(),
                     GENERIC_READ | GENERIC_WRITE,
                     0,
                     0,
                     OPEN_EXISTING,
                     FILE_ATTRIBUTE_NORMAL,
                     0);`

   return 0;
}
2 голосов
/ 24 сентября 2010

Если вы хотите продолжить использовать std::string, тогда используйте метод c_str() при вызове CreateFileA(), например:

hSerial = CreateFileA( comID.c_str(), ...);
0 голосов
/ 24 сентября 2010

Общая информация о преобразованиях строк здесь: http://www.codeproject.com/KB/string/cppstringguide2.aspx

0 голосов
/ 24 сентября 2010

Я столкнулся с этим недавно. Я просто отключил Юникод, так как Юникод был полностью недоступен для этого приложения.

0 голосов
/ 24 сентября 2010

Если (по какой-то причине) вы решили продолжить работу со строками ANSI, посмотрите на функцию MultiByteToWideChar.Но строки ANSI в значительной степени устарели.

0 голосов
/ 24 сентября 2010

В качестве дополнительной справки рассмотрим макросы преобразования ATL (например, CA2CW и т. Д.). Они (при правильном использовании) могут справляться практически со всеми простыми конверсионными сценариями, практически без суеты.

В вашем примере вы можете использовать std :: string, а затем использовать:

CreateFile( CA2CT( comID.c_str() ), ... );
...