创建文件映射错误代码 8

CreateFileMapping error code 8

CreateFileMapping 错误代码8.Not 有足够的存储空间可用于处理此命令。我正在尝试在 64 位 Win10 visual c++ 上创建 4 Gb (0xFFFFFFFF) 的文件映射。

#define UBS_MEM_SIZE 0xffffffff

HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,           
PAGE_READWRITE, HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE),     
TEXT("dllmemfilemap"));

我该如何解决这个 "ERROR 8" 问题?

HIWORDLOWORD 宏旨在从 32 位 DWORD 中提取高 16 位字和低 16 位字。另一方面,CreateFileMapping 期望两个 DWORD 共同组成一个 64 位无符号整数,即映射对象的大小。

HIWORD(UBS_MEM_SIZE)LOWORD(UBS_MEM_SIZE) 都产生 0xffff(两个 16 位的一半),然后将其转换为 32 位无符号整数(这是函数所期望的) .

所以,您实际上是在请求大小为 0x0000ffff0000ffff 的文件映射。这比255 TB还多。由于您使用的是 INVALID_HANDLE_VALUE,因此必须由 RAM 或系统页面文件支持;我怀疑你那里有那么多可用的东西。

如果 UBS_MEM_SIZE 始终是 32 位,您可以简单地使用

HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,
   PAGE_READWRITE, 0, UBS_MEM_SIZE,
   TEXT("dllmemfilemap"));

如果您确实需要处理超过 4 GB 的尺寸,您可以这样做:

HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 
   static_cast<DWORD>(UBS_MEM_SIZE >> 32), static_cast<DWORD>(UBS_MEM_SIZE), 
   TEXT("dllmemfilemap"));

确保 UBS_MEM_SIZE 实际上有一个大于 32 位的类型(即使它的值可能小于那个值),否则移动 32 位在 C++ 中是未定义的行为。因此,如果您想将上面的第二个变体与您的初始值一起使用,它必须类似于

#define UBS_MEM_SIZE 0xFFFFFFFFull

(顺便说一句,使用const...)

为了更安全,我会将调用包装成这样:

inline HANDLE MyCreateMapping(unsigned long long size, LPCTSTR name)
{
   return CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
      static_cast<DWORD>(size >> 32), static_cast<DWORD>(size), name);
}

这样,您就无需记住任何有关位、移位和整数类型大小的棘手细节。

   CreateFileMapping(..., HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE), ...)

LO/HIWORD 宏生成一个 WORD,一个 16 位值。您正在请求一个 0xffff0000ffff 内存映射文件。那是 282 TB。当前的 x64 处理器仅限于 48 位 VM 地址,大多数最高为 8 TB。所以是的,错误 8 (ERROR_NOT_ENOUGH_MEMORY) 完全在意料之中。

不要使用那些宏。您可以使用 LARGE_INTEGER 作为替代:

LARGE_INTEGER size;
size.QuadPart = UBS_MEM_SIZE;
HANDLE hMapObject = CreateFileMapping(..., size.HighPart, size.LowPart, ...);