OpenFileMapping失败 原因ERROR_FILE_NOT_FOUND
两个win32 console的工程,每个代表一个进程,利用共享内存在两个进程之间通信,过程中遇到了OpenFileMapping失败 原因ERROR_FILE_NOT_FOUND的错误,google了很久没找到原因,下午终于找到原因了。
两个工程的公共代码部分:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <cassert>
using namespace std;
#define SHARE_MEMORY_NAME TEXT("shareMemoryName")
#define SHARE_MEMORY_SIZE_NAME TEXT("shareMemorySizeName")
typedef enum
{
LX_OK = 0, // 正常返回
LX_SHAREDMEMORY_EXISTS = 1, // 共享内存已经存在
LX_INVALID_SHAREDMEMORY = 2, // 共享内存错误返回
LX_INVALID_SIZE = 3 // 共享内存大小错误
}LX_RETURN_VALUE;
// 创建共享内存
LX_RETURN_VALUE CreateSharedMemory(UINT nSize);
// 释放共享内存
LX_RETURN_VALUE ReleaseSharedMemory();
// 得到共享内存大小
LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize);
// 向共享内存写入数据
LX_RETURN_VALUE WriteToSharedMemory(void *pData, UINT nSize);
// 从共享内存读取数据
LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize);
class CAutoMutex
{
public:
CAutoMutex()
{
Create(TEXT("mutex"));
Wait();
}
~CAutoMutex()
{
Release();
}
private:
bool Create(TCHAR* pName)
{
m_mutex = ::CreateMutex(NULL, FALSE, pName);
if (m_mutex == NULL || ::GetLastError() == ERROR_ALREADY_EXISTS)
{
return false;
}
else
return true;
}
void Release()
{
if (m_mutex != NULL)
{
ReleaseMutex(m_mutex);
CloseHandle(m_mutex);
m_mutex = NULL;
}
}
bool Wait()
{
UINT32 ret = ::WaitForSingleObject(m_mutex, 0);
if (WAIT_FAILED == ret || WAIT_TIMEOUT == ret)
{
return false;
}
else
return true;
}
// 互斥量
HANDLE m_mutex;
};
LX_RETURN_VALUE CreateSharedMemory(UINT nSize)
{
// 创建共享内存块
HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nSize, SHARE_MEMORY_NAME);
// 创建错误
if ((hFileMapping == NULL) || (hFileMapping == INVALID_HANDLE_VALUE))
return LX_INVALID_SHAREDMEMORY;
// 共享内存已经存在
if (GetLastError() == ERROR_ALREADY_EXISTS)
return LX_SHAREDMEMORY_EXISTS;
// 创建另外一块内存存放共享内存的大小
HANDLE hSize = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, sizeof(UINT), SHARE_MEMORY_SIZE_NAME);
if ((hSize == NULL) || (hSize == INVALID_HANDLE_VALUE) || (GetLastError() == ERROR_ALREADY_EXISTS))
return LX_INVALID_SHAREDMEMORY;
// 得到存放共享内存大小的指针
UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_WRITE, 0, 0, sizeof(UINT));
if (pSize == NULL)
return LX_INVALID_SHAREDMEMORY;
// 写入共享内存的大小
memcpy(pSize, &nSize, sizeof(UINT));
// FlushViewOfFile(hSize,sizeof(UINT));
UnmapViewOfFile(pSize);
return LX_OK;
}
LX_RETURN_VALUE ReleaseSharedMemory()
{
CAutoMutex MutexLock;
// 打开共享内存
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARE_MEMORY_NAME);
// 关闭共享内存
if (hFileMapping != NULL)
CloseHandle(hFileMapping);
// 打开存放共享内存大小的文件映射
HANDLE hSize = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARE_MEMORY_SIZE_NAME);
// 关闭存放共享内存大小的文件映射
if (hSize != NULL)
CloseHandle(hSize);
return LX_OK;
}
LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize)
{
CAutoMutex MutexLock;
HANDLE hSize = OpenFileMapping(FILE_MAP_READ, FALSE, SHARE_MEMORY_SIZE_NAME);
if (hSize == NULL)
return LX_INVALID_SHAREDMEMORY;
UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_READ, 0, 0, sizeof(UINT));
if (pSize == NULL)
return LX_INVALID_SHAREDMEMORY;
// 得到共享内存的大小
memcpy(&nSize, pSize, sizeof(UINT));
return LX_OK;
}
LX_RETURN_VALUE WriteToSharedMemory(void *pDate, UINT nSize)
{
UINT nSharedMemorySize = 0;
// 得到共享内存的大小
if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)
return LX_INVALID_SHAREDMEMORY;
// 检查共享内存的大小
if (nSize > nSharedMemorySize)
return LX_INVALID_SIZE;
CAutoMutex MutexLock;
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_WRITE, FALSE, SHARE_MEMORY_NAME);
if (hFileMapping == NULL)
return LX_INVALID_SHAREDMEMORY;
void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, nSize);
if (pMapView == NULL)
return LX_INVALID_SHAREDMEMORY;
// 清空共享内存
memset(pMapView, 0, nSharedMemorySize);
// 将数据写入共享内存
memcpy(pMapView, pDate, nSize);
UnmapViewOfFile(pMapView);
return LX_OK;
}
LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize)
{
UINT nSharedMemorySize = 0;
if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)
return LX_INVALID_SHAREDMEMORY;
if (nSize > nSharedMemorySize)
return LX_INVALID_SIZE;
CAutoMutex MutexLock;
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ, FALSE, SHARE_MEMORY_NAME);
if (hFileMapping == NULL)
return LX_INVALID_SHAREDMEMORY;
void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, nSize);
if (pMapView == NULL)
return LX_INVALID_SHAREDMEMORY;
// 从共享内存读取数据
memcpy(pData, pMapView, nSize);
UnmapViewOfFile(pMapView);
return LX_OK;
}
写共享内存的进程:
int _tmain()
{
LX_RETURN_VALUE rv;
rv = CreateSharedMemory(1024);
assert(rv == LX_OK);
struct Test
{
int x;
int y;
};
Test t;
t.x = 10;
t.y = 100;
rv = WriteToSharedMemory(&t, sizeof(t));
assert(rv == LX_OK);
wcout<<"write to shared memory"<<endl;
getchar();
return 0;
}
读共享内存的进程:
int _tmain()
{
LX_RETURN_VALUE rv;
struct Test
{
int x;
int y;
};
Test t;
rv = ReadFromSharedMemory(&t, sizeof(t));
assert(rv == LX_OK);
wcout<<"read from shared memory:"<<endl;
wcout<<t.x<<endl<<t.y<<endl;
rv = ReleaseSharedMemory();
return 0;
}
OPenFileMapping失败的原因是:
第一个进程运行之后马上关闭,所以一定要加上getchar();这句话,并且读进程读共享内存的时候,写进程不能关闭!