LPCWSTR ERROR C++ 类型参数与类型参数不兼容

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

我是 C++ 的新手,碰巧遇到了这个障碍。当我尝试将任何 #define 放入 OpenFileMapping() 行中的参数时,我收到一条错误消息:

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

我对这个程序的最终目标是发送一个从共享内存中获取数据的 UDP 消息。

这是我使用 void 而不是 int 的结果吗?我不知道。

将您的字符串包装在 _T() 宏中。当在项目设置中选择 Unicode WinAPI 时,它会将 LPCSTR 字符串转换为 LPCWSTR。

#define MAP_OBJECT_NAME _T("$pcars2$")

TCHAR 定义为 wchar_tchar,具体取决于 UNICODE 是否已在您的项目设置中定义。

OpenFileMapping() 是一个基于 TCHAR 的预处理器宏。它被定义为在其第三个参数中采用 const TCHAR* 指向 null-terminated 字符串的指针。

实际上,OpenFileMapping() 映射到 OpenFileMappingA() (ANSI) or OpenFileMappingW() (Unicode) 函数,这取决于是否定义了 UNICODE

// 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

大多数处理字符数据的遗留 Win32 API 都像这样分为 AW 版本。近年来引入的较新的 API 往往是 Unicode-only.

在您的例子中,定义了 UNICODE,因此您试图传递一个窄字符串文字 (const char[]),而预期是一个 Unicode 字符串 (const wchar_t*)。这就是您收到类型不匹配错误的原因。

在基于 TCHAR 的 API 中使用 character/string 文字时,请使用 TEXT() 宏来确保文字使用 TCHAR 实际映射到的正确字符类型,例如:

#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);

当定义 UNICODE 时,它有效地执行以下操作:

#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);

并在未定义 UNICODE 时执行此操作:

#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);

但是,现代编码实践根本不应依赖 TCHAR API。在 2000 年代初微软推动用户迁移以采用 Unicode 期间,它们旨在向后兼容遗留 Win9x/ME 代码。您应该根据需要直接使用 ANSI 或 Unicode 函数。

一个简单的解决方案是将 OpenFileMapping 更改为 OpenFileMappingA 。此版本采用您提供的窄字符串。