简体   繁体   中英

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.

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.

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$")

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM