创建文件映射错误代码 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" 问题?
HIWORD
和 LOWORD
宏旨在从 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, ...);
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" 问题?
HIWORD
和 LOWORD
宏旨在从 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, ...);