cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}'


Solution 1

The Windows CreateFile function is actually a macro that expands to one of:

  • CreateFileA, which takes a file path of type const char*
  • CreateFileW, which takes a file path of type const 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:

  1. Change the function parameter to a UTF-16 (const wchar_t*) string.
  2. Keep the char* parameter, but have your function explicitly convert it to a UTF-16 string with a function like MultiByteToWideChar.
  3. Explicitly call CreateFileA instead of CreateFile.
  4. Compile your program without UNICODE, so that the macros expand to the A versions by default.
  5. 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.

Edit: I don't know if a kidnapping was involved, but Windows 10 1903 finally added support for UTF-8 as an ANSI code page.

Solution 2

There are many ways of fixing this

  1. 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.
  2. 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
  3. 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

Solution 3

Try this:

RS232Handle=OpenRS232(L"COM1", 9600);

HANDLE OpenRS232(const wchar_t* ComName, DWORD BaudRate)

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.

Solution 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:

Alternatively you might just use the CreateFileA function instead of CreateFile, as was suggested by Ben Voigt.

Author by


Updated on July 05, 2022


  • sci-guy
    sci-guy 7 months

    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)

    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)'

    The code was taken from VS code and I am now using Qt creator.

    How can I fix this issue? Thanks!

  • Ben Voigt
    Ben Voigt about 6 years
    Or just call CreateFileA which will do the conversion for you.
  • Ben Voigt
    Ben Voigt about 6 years
    If your datatype is hardcoded as wchar_t*, use CreateFileW. The CreateFile function macro should only be used together with the TCHAR or LPCTSTR type macros.
  • Ben Voigt
    Ben Voigt about 6 years
    #5 isn't a distinct option, it just lets #2, #3, and #4 work when the string contains extended characters.
  • Striezel
    Striezel about 6 years
    Thanks for the suggestion, I've added this to the answer.
  • Govind Parmar
    Govind Parmar about 6 years
    @BenVoigt Expanded my answer
  • Cypher
    Cypher over 2 years
    Changing the Character Set in Visual C++ did the trick for me...