为什么我会得到“类型的论点” lpcstr”与“ lpcwstr”类型的参数不兼容。编译罚款时错误?

发布于 2025-02-04 00:23:35 字数 1070 浏览 4 评论 0原文

我正在处理以下功能:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝海 2025-02-11 00:23:35

基本上,createfile()不是一个函数,它是宏,它将选择函数createfilea()或 creationfilew(creationfilew()基于在编译器上的选定字符集上。大多数将字符串作为参数的Windows API都是这样做的。

错误是因为,尽管您明确使用简单的8位char字符串,但您的编译器设置为将16位char字符串视为默认的,因此宏将选择createfilew() lpcwstr而不是lpcstr

要解决此问题,您可以选择其中一种解决方案:

  1. 明确调用createfilea()而不是createfile()
  2. 项目上的默认字符
  3. 宽度

更改 还可以利用宏tchar_t()来处理您的字符串,使您的项目自动使用8位或16位字符,具体取决于哪个选项是在编译器上选择,尽管这可能需要在整个项目中进行重大更改。

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. 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 takes LPCWSTR instead of LPCSTR.

To fix this you can pick one of the solutions:

  1. Explicitly call CreateFileA() instead of CreateFile()
  2. Change the default char width on your project
  3. Use 16-bit char strings

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.

卖梦商人 2025-02-11 00:23:35

Windows API具有大多数API功能的宽和ASCII版本。
这些具有后缀aw。根据宏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 and W. Depending on the macro UNICODE 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 either CreateFileA or CreateFileW.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文