8

MapViewOfFile我使用 WinAPI 的功能遇到了这种情况。互联网搜索没有发现任何明显的修复,所以我将在这里分享我的问题和解决方案。

考虑以下代码段:

const char *name = "Global\\Object_Name";
unsigned long size = get_object_size();

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE,
                                  NULL,
                                  PAGE_READWRITE,
                                  0,
                                  size,
                                  name);

if (!handle || handle == INVALID_HANDLE_VALUE)
    exit(GetLastError());

bool created = GetLastError() == 0;

void *block = MapViewOfFile( handle,
                             FILE_MAP_ALL_ACCESS,
                             0,
                             0,
                             size);

if (block == NULL)
    exit(GetLastError());

在一个特殊情况下,CreateFileMapping成功返回了一个句柄。GetLastError正在回归ERROR_ALREADY_EXISTS,所以created == false。现在,对 的调用MapViewOfFile,使用与我传递给相同的大小CreateFileMapping,返回NULLGetLastError返回0x05: ERROR_ACCESS_DENIED。该进程以管理员权限运行。

MSDN 文档并没有真正提到会发生这种情况的任何原因。那么,为什么CreateFileMapping成功了,却MapViewOfFile失败了?

4

2 回答 2

9

经过一番苦恼,我终于在我的应用程序中找到了导致此错误的原因,以防其他人遇到同样的问题,问题不在于 MapViewOfFile 方法,而在于 CreateFileMapping,createFileMapping 的大小应该是文件的大小,而不是要读取的元素的大小,如果您不知道大小,那么它应该为 0,这不适用于 MapViewOfFile,因为要传递的值是您想要的块的长度读/写。

您的代码工作将如下所示:

const char *name = "Global\\Object_Name";
unsigned long size = get_object_size();

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE,
                                  NULL,
                                  PAGE_READWRITE,
                                  0,
                                  0,
                                  name);

if (!handle || handle == INVALID_HANDLE_VALUE)
    exit(GetLastError());

bool created = GetLastError() == 0;

void *block = MapViewOfFile( handle,
                             FILE_MAP_ALL_ACCESS,
                             0,
                             0,
                             size);

if (block == NULL)
    exit(GetLastError());

只是把它放在这里是为了记录我的发现,不幸的是,当你不知道是什么导致它时,很难搜索到这个错误。我希望这可以为其他人节省几个小时。

于 2015-01-03T09:22:48.113 回答
7

我敢肯定,ERROR_ACCESS_DENIED调用MapViewOfFile. 在我的特殊情况下,这是由于size争论。

暗示在于created == false. 它表明该对象"Global\\Object_Name"已经被创建。无论出于何种原因,创建调用都会以较小的大小初始化该部分。对于看起来像是疏忽的CreateFileMapping情况,即使您要求更大的映射,第二次调用也会很高兴地为您提供已经存在的对象的句柄。

对 now 的调用MapViewOfFile失败,因为它请求的视图大于实际部分。

因此,如果您处于第二次调用MapViewOfFile失败的类似情况,请检查您尝试映射到的大小。

可能是第二个项目正在使用不同的结构对齐方式进行编译,导致sizeof()操作员确定不同的值,或者某些其他大小确定功能未按预期运行。

于 2013-04-16T01:24:07.963 回答