1
#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++ 比较陌生,我碰巧遇到了这个障碍。当我试图将 any#define放入诸如OpenFileMapping()在线之类的参数中时,我收到一条错误消息:

类型的 C++ 参数与类型的参数不兼容

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

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

4

3 回答 3

4

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

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

实际上,会发生什么OpenFileMapping()映射到OpenFileMappingA()(ANSI) 或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。

在您的情况下,UNICODE已定义,因此您尝试const char[]在需要 Unicode 字符串(const wchar_t*)的地方传递一个窄字符串文字()。这就是您收到类型不匹配错误的原因。

将字符/字符串文字与TCHAR基于 - 的 API 一起使用时,请使用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);

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

于 2020-09-01T21:37:18.007 回答
0

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

于 2020-09-01T21:54:30.597 回答
0

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

#define MAP_OBJECT_NAME _T("$pcars2$")
于 2020-09-01T20:42:38.280 回答