c++lpcwstr

LPCWSTR ERROR C++ argument of type is incompatible with parameter of type


#include <iostream>
#include <WS2tcpip.h>
#include "sharedmemory.h"
#pragma comment (lib, "ws2_32.lib")

using namespace std;

#define MAP_OBJECT_NAME "$pcars2$"

void main(int argc, char* argv[]) 
{
    HANDLE fileHandle = OpenFileMapping(PAGE_READONLY, FALSE, MAP_OBJECT_NAME);

I am relatively new to C++, and I happened across this road block. When I'm trying to place any #define into an argument like on the OpenFileMapping() line, I get an error saying:

C++ argument of type is incompatible with parameter of type

My end goal with this program is to send a UDP message that grabs data from shared memory.

Is this a result of me using void instead of int? I don't know.


Solution

  • TCHAR is defined as either wchar_t or char, depending on whether UNICODE has been defined or not in your project setup, respectively.

    OpenFileMapping() is a TCHAR-based preprocessor macro. It is defined as taking a const TCHAR* pointer to a null-terminated string in its 3rd parameter.

    In reality, what happens is that OpenFileMapping() maps to either the OpenFileMappingA() (ANSI) or OpenFileMappingW() (Unicode) function, depending on whether UNICODE is defined:

    // in winbase.h
    WINBASEAPI
    __out
    HANDLE
    WINAPI
    OpenFileMappingA(
        __in DWORD dwDesiredAccess,
        __in BOOL bInheritHandle,
        __in LPCSTR lpName
        );
    WINBASEAPI
    __out
    HANDLE
    WINAPI
    OpenFileMappingW(
        __in DWORD dwDesiredAccess,
        __in BOOL bInheritHandle,
        __in LPCWSTR lpName
        );
    #ifdef UNICODE
    #define OpenFileMapping  OpenFileMappingW
    #else
    #define OpenFileMapping  OpenFileMappingA
    #endif // !UNICODE
    

    Most legacy Win32 APIs that deal with character data are separated into A and W versions like this. Newer APIs introduced in recent years tend to be Unicode-only.

    In your case, UNICODE is defined, so you are trying to pass a narrow string literal (const char[]) where a Unicode string (const wchar_t*) is expected. That is why you are getting a type mismatch error.

    When using character/string literals with TCHAR-based APIs, use the TEXT() macro to ensure the literal uses the correct character type that TCHAR actually maps to, eg:

    #include <iostream>
    #include <WS2tcpip.h>
    #include "sharedmemory.h"
    #pragma comment (lib, "ws2_32.lib")
    
    using namespace std;
    
    #define MAP_OBJECT_NAME TEXT("$pcars2$") // <-- HERE
    
    void main(int argc, char* argv[]) 
    {
        HANDLE fileHandle = OpenFileMapping(PAGE_READONLY, FALSE, MAP_OBJECT_NAME);
    

    Which is effectively doing the following when UNICODE is defined:

    #include <iostream>
    #include <WS2tcpip.h>
    #include "sharedmemory.h"
    #pragma comment (lib, "ws2_32.lib")
    
    using namespace std;
    
    #define MAP_OBJECT_NAME L"$pcars2$"
    
    void main(int argc, char* argv[]) 
    {
        HANDLE fileHandle = OpenFileMappingW(PAGE_READONLY, FALSE, MAP_OBJECT_NAME);
    

    And doing this when UNICODE is not defined:

    #include <iostream>
    #include <WS2tcpip.h>
    #include "sharedmemory.h"
    #pragma comment (lib, "ws2_32.lib")
    
    using namespace std;
    
    #define MAP_OBJECT_NAME "$pcars2$"
    
    void main(int argc, char* argv[]) 
    {
        HANDLE fileHandle = OpenFileMappingA(PAGE_READONLY, FALSE, MAP_OBJECT_NAME);
    

    However, modern coding practices should not rely on TCHAR APIs at all. They are meant for backwards compatibility with legacy Win9x/ME code during Microsoft's push to migrate users to adopt Unicode in the early 2000s. You should use the ANSI or Unicode functions directly instead as needed.