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"));
如何解决这个“错误8”问题?
答案 0 :(得分:4)
CreateFileMapping(..., HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE), ...)
LO / HIWORD宏生成一个16位值的WORD。您要求0xffff0000ffff内存映射文件。这是282太字节。目前的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, ...);
答案 1 :(得分:3)
HIWORD
和LOWORD
宏旨在从32位DWORD
中提取高位和低位16位字。另一方面,CreateFileMapping
期望两个DWORD
一起组成一个64位无符号整数,这是映射对象的大小。
HIWORD(UBS_MEM_SIZE)
和LOWORD(UBS_MEM_SIZE)
都会产生0xffff
(两个16位的一半),然后将它们转换为32位无符号整数(这是函数所期望的)。 / p>
因此,您实际要做的是要求提供大小为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);
}
这样,您就不需要记住有关位,移位和整数类型大小的任何棘手细节。