简体   繁体   English

为什么在代码编译正常时会出现“类型为“LPCSTR”的参数与类型为“LPCWSTR”的参数不兼容的错误?

[英]Why do I get "argument of type "LPCSTR" is incompatible with parameter of type "LPCWSTR" error when code compiles fine?

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但是,我在“portName”变量下得到一个红色错误标记,并带有错误消息

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.此外,当我尝试改用类型 LPCWSTR 时,代码无法编译。 When I instead change the parameter to LPCWSTR and initialize the argument like this:当我改为将参数更改为 LPCWSTR 并像这样初始化参数时:

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?到底他妈发生了什么?

Basically, CreateFile() isn't a function, it's a macro, that will select either the function CreateFileA() or CreateFileW() based on the selected charset on your compiler.基本上, CreateFile()不是一个函数,它是一个宏,它将根据编译器上选定的字符集选择函数CreateFileA()CreateFileW() Most Windows APIs that take strings as parameters are made that way.大多数将字符串作为参数的 Windows API 都是以这种方式制作的。

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 takes LPCWSTR instead of LPCSTR .错误是因为,尽管您明确使用简单的 8 位 char 字符串,但您的编译器设置为默认采用 16 位 char 字符串,因此该宏将选择CreateFileW() ,它采用LPCWSTR而不是LPCSTR

To fix this you can pick one of the solutions:要解决此问题,您可以选择以下解决方案之一:

  1. Explicitly call CreateFileA() instead of CreateFile()显式调用CreateFileA()而不是CreateFile()
  2. Change the default char width on your project更改项目的默认字符宽度
  3. Use 16-bit char strings使用 16 位字符字符串

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.您还可以使用宏TCHAR_T()来处理您的字符串,使您的项目根据在编译器上选择的选项自动使用 8 位或 16 位字符,但这可能需要在整个过程中进行大量更改整个项目。

The Windows API has Wide and ASCII versions of most of its API functions. Windows API 具有其大多数 API 函数的 Wide 和 ASCII 版本。 These have suffixes A and W .这些有后缀AW Depending on the macro UNICODE being defined or not, the suffixless function names are defined to either the ASCII or Wide versions, eg CreateFile is actually defined as a macro to be either CreateFileA or CreateFileW .根据是否定义了宏UNICODE ,无后缀的函数名称被定义为 ASCII 或 Wide 版本,例如CreateFile实际上被定义为一个宏,可以是CreateFileACreateFileW

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.似乎您的 IDE 在生成其编辑器内下划线等时定义了UNICODE宏,而您的编译器在构建项目时没有得到这个定义。

All this can be avoided by just calling the suffixed versions directly and not bothering with the UNICODE define at all.所有这些都可以通过直接调用带后缀的版本来避免,而根本不需要使用UNICODE定义。

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. Windows 11(甚至可能是 10?)有一个注册表项,可以让 ASCII 变体正确处理 UTF-8,这对于开发人员来说当然不是很理想,因为您不控制用户系统上的注册表。 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.我总是直接调用 W 版本,并在调用 Windows API 时处理转换为 UTF-16 宽字符串,或者如果不编写跨平台代码,则在任何地方直接使用 wchar_t/wstring。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “LPCWSTR”类型的参数与“LPCSTR”类型的参数不兼容 - Argument of type “LPCWSTR” is incompatible of the parameter of type “LPCSTR” 错误:char* 类型的参数与 LPCWSTR 类型的参数不兼容 - Error: argument of type char* is incompatible with parameter of type LPCWSTR LPCWSTR ERROR C++ 参数类型与参数类型不兼容 - LPCWSTR ERROR C++ argument of type is incompatible with parameter of type WORD *类型的参数与LPCWSTR类型的参数不兼容 - argument of type WORD* is incompatible with parameter of type LPCWSTR 与“LPCWSTR”类型的参数不兼容 - Incompatible with parameter of type "LPCWSTR" “WCHAR *”类型的参数与 c++ 中“LPCSTR”类型的参数不兼容 - argument of type "WCHAR *" is incompatible with parameter of type "LPCSTR" in c++ 类型“ const char *”的参数与类型“ LPCWSTR”的参数不兼容 - argument of type “const char *” is incompatible with parameter of type “LPCWSTR” IntelliSense:“ const char *”类型的参数与“ LPCWSTR”类型的参数不兼容 - IntelliSense: argument of type “const char *” is incompatible with parameter of type “LPCWSTR” “ char *”类型的参数与“ STRSAFE_LPCWSTR”类型的参数不兼容 - argument of type “char *” is incompatible with parameter of type "STRSAFE_LPCWSTR “BYTE*”类型的参数与 Windows 上的“LPCWSTR”类型参数不兼容 - Argument of type "BYTE*" is incompatible with parameter of type "LPCWSTR" on Windows
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM