我正在从事以下工作:
int initSerialPort(HANDLE* hSerialPort, LPCSTR portName){
*hSerialPort = CreateFile(
portName,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
....
}
但是,在带有错误消息的"portName“变量下,我得到了一个红色错误标记。
argument of type "LPCSTR" is incompatible with parameter of type "LPCWSTR"
但是,尽管有此错误,代码仍按预期的方式编译和运行。我现在提出的论点如下:
LPCSTR portName = "COM1";
initSerialPort(&hSerialPort, portName);
此外,当我尝试使用LPCWSTR类型时,代码不会编译。当我将参数更改为LPCWSTR并初始化参数时,如下所示:
LPCWSTR portName = L"COM5";
initSerialPort(&hSerialPort, portName);
我不再勉强地看到红色错误,但是当我试图编译这个错误时,我会得到以下错误
.\test.cpp:28:17: error: cannot convert 'LPCWSTR' {aka 'const wchar_t*'} to 'LPCSTR' {aka 'const char*'}
28 | portName,
| ^~~~~~~~
| |
| LPCWSTR {aka const wchar_t*}
到底是怎么回事?
发布于 2022-06-03 13:56:29
基本上,CreateFile()
不是一个函数,它是一个宏,它将根据编译器上选定的字符集选择函数CreateFileA()
或CreateFileW()
。大多数以字符串为参数的Windows都是这样制作的。
这个错误是因为,尽管您显式地使用了简单的8位字符字符串,但是您的编译器被设置为默认假定16位字符字符串,因此宏将选择CreateFileW()
,这将采用LPCWSTR
而不是LPCSTR
。
要解决这个问题,您可以选择以下解决方案之一:
CreateFile()
CreateFileA()
项目的默认字符宽度。
您还可以使用宏TCHAR
和_T()
来处理您的字符串,使您的项目根据编译器上选择的选项自动使用8位或16位字符,尽管这可能需要在整个项目中进行大量更改。
发布于 2022-06-03 13:49:15
Windows有其大多数API函数的宽版本和ASCII版本。它们有后缀A
和W
。根据所定义的宏UNICODE
或未定义的宏,没有后缀的函数名被定义为ASCII或宽版本,例如CreateFile
实际上被定义为CreateFileA
或CreateFileW
的宏。
在生成UNICODE
宏的编辑器内下划线等时,您的IDE似乎定义了这个宏,而编译器在构建项目时并没有得到这个定义。
所有这些都可以避免,只需直接调用后缀版本,而根本不需要使用UNICODE
定义。
Windows 11 (甚至10?)有一个注册表键可以让ASCII变体正确地处理UTF-8,当然,作为开发人员,这并不理想,因为您不能控制用户系统上的注册表。我总是直接调用W版本,并在调用Windows时处理到UTF-16宽字符串的转换,或者如果不编写跨平台代码,只需在任何地方直接使用wchar_t/wstring。
https://stackoverflow.com/questions/72490486
复制相似问题