当使用Windows CreateFile函数寻址串口时,我似乎遇到了一些TEXT / UNICODE问题。有人可以帮我指出我的错误吗?
我正在使用VS 2008在VC ++中编写Win32控制台应用程序。
我可以创建一个句柄来解决串口问题:
#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的comports,\\\\.\\
位是必需的,对于那些直到COM9的组合也是如此。问题是我的comport并不总是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仍然可以工作吗?谢谢!
答案 0 :(得分:6)
您可以使用std::wstring
和std::wcin
,std::wcout
直接在“unicode字符串”中执行输入,也可以查看Microsoft的conversion functions。
如果你选择第一个选项(推荐),你仍然需要使用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;
}
答案 1 :(得分:2)
如果您想继续使用std::string
,请在调用c_str()
时使用其CreateFileA()
方法,例如:
hSerial = CreateFileA( comID.c_str(), ...);
答案 2 :(得分:0)
作为附加参考,请查看ATL转换宏(例如:CA2CW等)。这些(如果使用得当)可以内联处理几乎所有简单的转换案例,而且不用担心。
在您的示例中,您可以使用std :: string,然后使用:
CreateFile( CA2CT( comID.c_str() ), ... );
答案 3 :(得分:0)
如果(出于某种原因)您决定继续使用ANSI字符串,请查看MultiByteToWideChar
函数。但是ANSI字符串几乎已经过时了。
答案 4 :(得分:0)
我最近碰到了这个。我只是禁用了Unicode,因为Unicode完全超出了这个应用程序的范围。
答案 5 :(得分:0)