无法将 'const char*' 转换为 'LPCWSTR {aka const wchar_t*}'
cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}'
我的 C++ 代码中出现了一个我无法理解的错误。精简代码位在这里:
RS232Handle=OpenRS232("COM1", 9600);
HANDLE OpenRS232(const char* ComName, DWORD BaudRate)
{
ComHandle=CreateFile(ComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
我收到以下错误:
error: cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}' for argument '1' to 'void* CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE)'
ComHandle=CreateFile(ComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
代码取自VS code,我现在使用的是Qt creator。
我该如何解决这个问题?谢谢!
const char*
和 const wchar_t*
是两种不同的类型,它们之间没有隐式转换。因此,您需要在将值传递给 CreateFile
函数之前执行转换。查看此答案以了解可能的转换方法:
或者,您可以使用 CreateFileA
函数代替 CreateFile
,正如 Ben Voigt 所建议的那样。
试试这个:
RS232Handle=OpenRS232(L"COM1", 9600);
HANDLE OpenRS232(const wchar_t* ComName, DWORD BaudRate)
{
ComHandle=CreateFileW(ComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
在 Windows 上,wchar_t 类型用于表示 UTF-16 编码中的字符。这是 Windows 内核在内部使用的内容,因此现代版本的 Visual C++ 默认使用 Unicode 函数。如果您坚持改用 ANSI 函数(从而返回到您的原始代码),请从字符串 "COM1" 中删除 L
前缀并将调用从 CreateFileW
更改为 CreateFileA
.
大多数处理字符串的 Windows API 函数都有 W
和 A
版本;我知道的唯一例外是函数 GetProcAddress
,无论您在项目中使用的是 ANSI 还是 Unicode,总是 采用 ANSI 字符串。
Windows CreateFile 函数实际上是一个扩展为以下之一的宏:
CreateFileA
,采用 const char*
类型的文件路径
CreateFileW
,采用 const wchar_t*
. 类型的文件路径
(Windows API中的大部分函数也是如此。)
您正在声明参数 const char* ComName
,但显然编译时定义了 UNICODE
,因此它调用了函数的 W
版本。没有从 const wchar_t*
到 const char*
的自动转换,因此出现错误。
您的选择是:
- 将函数参数更改为 UTF-16 (
const wchar_t*
) 字符串。
- 保留
char*
参数,但让您的函数使用 MultiByteToWideChar. 之类的函数将其显式转换为 UTF-16 字符串
- 明确调用
CreateFileA
而不是 CreateFile
。
- 在没有
UNICODE
的情况下编译您的程序,以便默认情况下宏扩展到 A
版本。
- 绑架一位著名的 Microsoft 开发人员并强迫他阅读 UTF-8 Everywhere 直到他同意 Windows 完全支持 UTF-8 作为“ANSI”代码页,从而释放 Windows各地的开发人员都从这个宽字符的东西。
编辑:不知道是不是绑架了,不过Windows10 1903终于支持了for UTF-8 as an ANSI code page.
有很多方法可以解决这个问题
- 打开项目属性,General/Character设置。这将被设置为 Unicode 或多字节字符集。如果您希望使用 char*,请将 Unicode 更改为 MBCS。如果指定了 Unicode,这会将 CreateFile 转换为 CreateFileW,如果指定了 MBCS,则转换为 CreateFileA。
- 将所有字符串括在 _T() 中,例如 _T("COM1")。如果指定了 MBCS,则将字符串编译为 char*,如果指定了 unicode,则 wchar_t
- 强制所有字符串为宽字符串,通过使用 L 作为前缀,例如 L"COM1"
请注意,在某些错误处理例程中,字符串特别是 MBCS
我的 C++ 代码中出现了一个我无法理解的错误。精简代码位在这里:
RS232Handle=OpenRS232("COM1", 9600);
HANDLE OpenRS232(const char* ComName, DWORD BaudRate)
{
ComHandle=CreateFile(ComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
我收到以下错误:
error: cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}' for argument '1' to 'void* CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE)'
ComHandle=CreateFile(ComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
代码取自VS code,我现在使用的是Qt creator。
我该如何解决这个问题?谢谢!
const char*
和 const wchar_t*
是两种不同的类型,它们之间没有隐式转换。因此,您需要在将值传递给 CreateFile
函数之前执行转换。查看此答案以了解可能的转换方法:
或者,您可以使用 CreateFileA
函数代替 CreateFile
,正如 Ben Voigt 所建议的那样。
试试这个:
RS232Handle=OpenRS232(L"COM1", 9600);
HANDLE OpenRS232(const wchar_t* ComName, DWORD BaudRate)
{
ComHandle=CreateFileW(ComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
在 Windows 上,wchar_t 类型用于表示 UTF-16 编码中的字符。这是 Windows 内核在内部使用的内容,因此现代版本的 Visual C++ 默认使用 Unicode 函数。如果您坚持改用 ANSI 函数(从而返回到您的原始代码),请从字符串 "COM1" 中删除 L
前缀并将调用从 CreateFileW
更改为 CreateFileA
.
大多数处理字符串的 Windows API 函数都有 W
和 A
版本;我知道的唯一例外是函数 GetProcAddress
,无论您在项目中使用的是 ANSI 还是 Unicode,总是 采用 ANSI 字符串。
Windows CreateFile 函数实际上是一个扩展为以下之一的宏:
CreateFileA
,采用const char*
类型的文件路径
CreateFileW
,采用const wchar_t*
. 类型的文件路径
(Windows API中的大部分函数也是如此。)
您正在声明参数 const char* ComName
,但显然编译时定义了 UNICODE
,因此它调用了函数的 W
版本。没有从 const wchar_t*
到 const char*
的自动转换,因此出现错误。
您的选择是:
- 将函数参数更改为 UTF-16 (
const wchar_t*
) 字符串。 - 保留
char*
参数,但让您的函数使用 MultiByteToWideChar. 之类的函数将其显式转换为 UTF-16 字符串
- 明确调用
CreateFileA
而不是CreateFile
。 - 在没有
UNICODE
的情况下编译您的程序,以便默认情况下宏扩展到A
版本。 - 绑架一位著名的 Microsoft 开发人员并强迫他阅读 UTF-8 Everywhere 直到他同意 Windows 完全支持 UTF-8 作为“ANSI”代码页,从而释放 Windows各地的开发人员都从这个宽字符的东西。
编辑:不知道是不是绑架了,不过Windows10 1903终于支持了for UTF-8 as an ANSI code page.
有很多方法可以解决这个问题
- 打开项目属性,General/Character设置。这将被设置为 Unicode 或多字节字符集。如果您希望使用 char*,请将 Unicode 更改为 MBCS。如果指定了 Unicode,这会将 CreateFile 转换为 CreateFileW,如果指定了 MBCS,则转换为 CreateFileA。
- 将所有字符串括在 _T() 中,例如 _T("COM1")。如果指定了 MBCS,则将字符串编译为 char*,如果指定了 unicode,则 wchar_t
- 强制所有字符串为宽字符串,通过使用 L 作为前缀,例如 L"COM1"
请注意,在某些错误处理例程中,字符串特别是 MBCS