CreateFileMapping error code 8

CreateFileMapping error code 8

本文关键字:code error CreateFileMapping      更新时间:2023-10-16

CreateFileMapping错误码8。没有足够的存储空间来处理这个命令。我试图在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"问题?

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

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

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

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

HIWORDLOWORD宏用于从32位DWORD中提取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++中移位32位是未定义的行为。所以,如果你想用上面的第二个变量作为你的初始值,它必须是类似

的东西
#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);
}

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