背景:我正在尝试创建一个可以被多个进程访问的内存映射文件。在下面的代码中,我只放入了与我目前提出的问题有关的代码,以使事情更简单。根据msdn的说法,我应该能够创建一个文件映射,映射文件的视图,并关闭我从CreateFileMapping接收到的句柄,而MapViewOfFile将保持我的FileMap处于活动状态。FileMap应该仍然可访问,直到我取消映射UnmapViewOfFile。
MSDN:CreateFileMapping 函数
文件映射对象的映射视图维护对该对象的内部引用,只有当所有对它的引用都已释放时,文件映射对象才关闭。因此,要完全关闭文件映射对象,应用程序必须通过调用UnmapViewOfFile取消映射文件映射对象的所有映射视图,并通过调用CloseHandle关闭文件映射对象句柄。这些函数可以按任何顺序调用。
问题:成功映射文件视图后,关闭由CreateFileMapping接收的句柄后,FileMap不再存在(它应该仍然存在),我的MemMapFileReader能够创建一个新的映射,并出现错误为0。(而不是应该接收到错误183“已经存在”)
不好的解决方案:不关闭句柄允许MemMapFileReader程序访问该句柄,但会导致MemMapFileCreator中的句柄泄漏,因为该句柄直到进程关闭才被关闭。
问题:我错过了什么或者做错了什么?
MemMapFileCreator
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#define BUF_SIZE 256
TCHAR szName[] = TEXT("MyFileMappingObject");
TCHAR szMsg[] = TEXT("Message from first process.");
int _tmain()
{
HANDLE hMapFile;
LPCTSTR pBuf;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
BUF_SIZE, // maximum object size (low-order DWORD)
szName); // name of mapping object
DWORD lastError = GetLastError();
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
std::cin.get();
return 1;
}
pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
CloseHandle(hMapFile);
std::cin.get();
return 1;
}
CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
CloseHandle(hMapFile);
_getch();
UnmapViewOfFile(pBuf);
return 0;
}
MemMapFileReader
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#pragma comment(lib, "user32.lib")
#define BUF_SIZE 256
TCHAR szName[] = TEXT("MyFileMappingObject");
int _tmain()
{
HANDLE hMapFile;
LPCTSTR pBuf;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE, // read/write access
0,
BUF_SIZE,
szName); // name of mapping object
DWORD lastError = GetLastError();
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not open file mapping object (%d).\n"),
GetLastError());
std::cin.get();
return 1;
}
pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
CloseHandle(hMapFile);
std::cin.get();
return 1;
}
MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
std::cin.get();
return 0;
}