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

350 views Asked by At
#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.

3

There are 3 answers

0
Remy Lebeau On BEST ANSWER

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.

0
M.M On

A simple solution is to change OpenFileMapping to OpenFileMappingA . This version takes a narrow character string which you are providing.

1
Dmitry Sokolov On

Wrap your strings in the _T() macro. It will convert LPCSTR strings to LPCWSTR when Unicode WinAPI is selected in project settings.

#define MAP_OBJECT_NAME _T("$pcars2$")