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();这句话,并且读进程读共享内存的时候,写进程不能关闭!

原文地址:https://www.cnblogs.com/kex1n/p/2133926.html