为什么我会得到“类型的论点” lpcstr”与“ lpcwstr”类型的参数不兼容。编译罚款时错误?
我正在处理以下功能:
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*}
该错误发生了什么?
I am working on the following function:
int initSerialPort(HANDLE* hSerialPort, LPCSTR portName){
*hSerialPort = CreateFile(
portName,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
....
}
However, I get a red error mark under the "portName" variable with the error message
argument of type "LPCSTR" is incompatible with parameter of type "LPCWSTR"
However, despite this error, the code compiles and runs as expected. I am currently passing in an argument as follows:
LPCSTR portName = "COM1";
initSerialPort(&hSerialPort, portName);
Furthermore, when I try to use type LPCWSTR instead, the code does not compile.
When I instead change the parameter to LPCWSTR and initialize the argument like this:
LPCWSTR portName = L"COM5";
initSerialPort(&hSerialPort, portName);
I no longer see the red error squiggly, however when I try to compile this I get the following error
.\test.cpp:28:17: error: cannot convert 'LPCWSTR' {aka 'const wchar_t*'} to 'LPCSTR' {aka 'const char*'}
28 | portName,
| ^~~~~~~~
| |
| LPCWSTR {aka const wchar_t*}
What the heck is going on?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
基本上,
createfile()
不是一个函数,它是宏,它将选择函数createfilea()
或 creationfilew(creationfilew()基于在编译器上的选定字符集上。大多数将字符串作为参数的Windows API都是这样做的。错误是因为,尽管您明确使用简单的8位char字符串,但您的编译器设置为将16位char字符串视为默认的,因此宏将选择
createfilew()
lpcwstr
而不是lpcstr
。要解决此问题,您可以选择其中一种解决方案:
createfilea()
而不是createfile()
更改 还可以利用宏
tchar
和_t()
来处理您的字符串,使您的项目自动使用8位或16位字符,具体取决于哪个选项是在编译器上选择,尽管这可能需要在整个项目中进行重大更改。Basically,
CreateFile()
isn't a function, it's a macro, that will select either the functionCreateFileA()
orCreateFileW()
based on the selected charset on your compiler. Most Windows APIs that take strings as parameters are made that way.The error is because, although you're explicitly using simple 8-bit char strings, your compiler is set to assume 16-bit char strings as default, so that macro will pick
CreateFileW()
, which takesLPCWSTR
instead ofLPCSTR
.To fix this you can pick one of the solutions:
CreateFileA()
instead ofCreateFile()
You could also make use of the macros
TCHAR
and_T()
to handle your strings, to make your project automatically use 8-bit or 16-bit chars depending on what option is selected on the compiler, though this could require making substantial changes throughout the entire project.Windows API具有大多数API功能的宽和ASCII版本。
这些具有后缀
a
和w
。根据宏unicode
的定义是否定义,将后缀函数名称定义为ASCII或宽版本,例如createfile 实际上将其定义为宏为<代码> createfilea 或createfilew
。看来,您的IDE在生产其内部编辑器等时定义了
Unicode
宏,而您的编译器在构建项目时未能定义此功能。可以通过直接调用后缀版本而不会打扰
unicode
完全定义所有这些。Windows 11(甚至10?)具有注册表密钥,可以使ASCII变体正确处理UTF-8,这当然并不是作为开发人员真正理想的,因为您无法控制用户系统上的注册表。
我总是直接调用W版本,并在调用Windows API时处理转换为UTF-16宽字符串,或者如果不编写跨平台代码,只需直接在任何地方使用WCHAR_T/WSTRING即可。
The Windows API has Wide and ASCII versions of most of its API functions.
These have suffixes
A
andW
. Depending on the macroUNICODE
being defined or not, the suffixless function names are defined to either the ASCII or Wide versions, e.g.CreateFile
is actually defined as a macro to be eitherCreateFileA
orCreateFileW
.It seems you IDE defines the
UNICODE
macro when producing its in-editor underlining etc., while your compiler is not getting this define when you're building your project.All this can be avoided by just calling the suffixed versions directly and not bothering with the
UNICODE
define at all.Windows 11 (and maybe even 10?) has a registry key to let the ASCII variants handle UTF-8 properly, which of course isn't really ideal as a developer, as you don't control the registry on your users' systems.
I'd always call the W versions directly, and handle conversion to UTF-16 wide strings when calling the Windows API, or if not writing cross-platform code, just use wchar_t/wstring directly everywhere.