问题
I'm getting an error in my C++ code that I can't quite make sense of. The stripped down code bits are here:
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);
}
I get the following error:
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);
The code was taken from VS code and I am now using Qt creator.
How can I fix this issue? Thanks!
回答1:
The Windows CreateFile function is actually a macro that expands to one of:
CreateFileA
, which takes a file path of typeconst char*
CreateFileW
, which takes a file path of typeconst wchar_t*
.
(The same is true for most of the functions in the Windows API that take a string.)
You're declaring the parameter const char* ComName
, but apparently compiling with UNICODE
defined, so it's calling the W
version of the function. There's no automatic conversion from const wchar_t*
to const char*
, hence the error.
Your options are to:
- Change the function parameter to a UTF-16 (
const wchar_t*
) string. - Keep the
char*
parameter, but have your function explicitly convert it to a UTF-16 string with a function like MultiByteToWideChar. - Explicitly call
CreateFileA
instead ofCreateFile
. - Compile your program without
UNICODE
, so that the macros expand to theA
versions by default. - Kidnap a prominent Microsoft developer and force him to read UTF-8 Everywhere until he agrees to have Windows fully support UTF-8 as an “ANSI” code page, thus freeing Windows developers everywhere from this wide-character stuff.
回答2:
There are many ways of fixing this
- Open the project properties, General/Character Set. This will be set to either Unicode or Multi byte character set. If you wish to use char* change from Unicode to MBCS. This will convert CreateFile to CreateFileW if Unicode is specified and CreateFileA if MBCS is specified.
- Enclose all strings in _T() eg _T("COM1"). What this does is to compile the string as a char* if MBCS is specified, wchar_t if unicode is specified
- Force all strings to be wide strings by prefixing with L eg L"COM1"
Note that in some error handling routine the strings are specifically MBCS
回答3:
Try this:
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);
}
On Windows the wchar_t type is used to represent characters in UTF-16 encoding. This is what the Windows kernel uses internally and therefore modern versions of Visual C++ default to Unicode functions. If you insist on using the ANSI functions instead (thus going back to your original code), remove the L
-prefix from the string "COM1" and change the call from CreateFileW
to CreateFileA
.
Most Windows API functions that deal with strings have both a W
and an A
version; the only exception that I am aware of is the function GetProcAddress which always takes an ANSI string regardless of whether you're working with ANSI or Unicode in your project.
回答4:
const char*
and const wchar_t*
are two different types with no implicit conversion between them. Therefore, you need to perform the conversion to before passing the value on to the CreateFile
function. Take a look at this answer for a possible conversion approach: https://stackoverflow.com/a/3074785/6710751
Alternatively you might just use the CreateFileA
function instead of CreateFile
, as was suggested by Ben Voigt.
来源:https://stackoverflow.com/questions/40641572/cannot-convert-const-char-to-lpcwstr-aka-const-wchar-t