http://blog.chinaunix.net/u1/59687/showart_496412.html
本文介绍一个共享内存封装类,使共享内存的使用更简单化,特别适合更懒的程序员使用:-)
一、实现目标:简单化使用共享内存
二、使用说明:
1. 创建共享内存CSFMServer对象, 需要为CSFMServer对象指定专用的名字,只要
系统中存在一个这样的对象,就可以在其他程序中简单方便地使用该共享内存。
CSFMServer(char *szFileName, char *szMapName, DWORD dwSize);
Create(char *szFileName, char *szMapName, DWORD dwSize);
参数1:NULL或指定的文件(将创建或打开并读写/麻烦)
参数2:要创建的共享内存对象名
参数3:要创建的共享内存对象大小
例如
m_SFMS.Create(NULL, "_ZZZ_OBJ_", 1);
2. 本地使用共享内存
使用 LPVOID GetBuffer() 返回共享内存地址,例如
char *p = (char*)m_SFMS.GetBuffer();
if (p)
strcpy(p, "1234567890");
3. 创建共享内存CSFMClient对象,也需要为CSFMClient对象指定专用的名字(上一步使用的那个),即可使用共享内存。
CSFMClient(DWORD dwAccess, char *szMapName);
Open(DWORD dwAccess, char *szMapName);
参数1:共享内存对象访问方式(FILE_MAP_READ|FILE_MAP_WRITE)
参数2:共享内存对象名
例如:
CSFMClient *pCSFMC = new CSFMClient(FILE_MAP_READ, "_OBJ_ZZZ_");
4. 本地使用共享内存
使用 LPVOID GetBuffer() 返回共享内存地址,例如
char *p = (char*)pCSFMC->GetBuffer();
if (p) strcpy(p, "1234567890");
三、该类的具体实现代码如下:
//------------------------------------------------
// 2002/07/05
// awzzz
// SFMMem.h: interface for the CSFMServer class.
//------------------------------------------------
#if !defined(AFX_SFMSERVER_H__2D76A439_6388_4B07_AE7A_C82F458642ED__INCLUDED_)
#define AFX_SFMSERVER_H__2D76A439_6388_4B07_AE7A_C82F458642ED__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define DEFAULT_FILENAME NULL
#define DEFAULT_MAPNAME "_SFM_OBJ_"
#define DEFAULT_MAPSIZE (0xFFFF + 1)
// Shared FileMap Server
class CSFMServer
{
public:
CSFMServer();
virtual ~CSFMServer();
CSFMServer(char *szFileName, char *szMapName, DWORD dwSize);
protected:
HANDLE m_hFile;
HANDLE m_hFileMap;
LPVOID m_lpFileMapBuffer;
char *m_pFileName;
char *m_pMapName;
DWORD m_dwSize;
int m_iCreateFlag;
private:
void _Init();
void _Destory();
public:
void Create(char *szFileName, char *szMapName, DWORD dwSize);
LPVOID GetBuffer();
DWORD GetSize();
};
// Shared FileMap Client
class CSFMClient
{
public:
CSFMClient();
virtual ~CSFMClient();
CSFMClient(DWORD dwAccess, char *szMapName);
protected:
HANDLE m_hFileMap;
LPVOID m_lpFileMapBuffer;
char *m_pMapName;
int m_iOpenFlag;
private:
void _Init();
void _Destory();
public:
void Open(DWORD dwAccess, char *szMapName);
LPVOID GetBuffer();
DWORD GetSize();
};
#endif // !defined(AFX_SFMSERVER_H__2D76A439_6388_4B07_AE7A_C82F458642ED__INCLUDED_)
//------------------------------------------------------
// SFMMem.cpp: implementation of the CSFMServer class.
//------------------------------------------------------
#include "stdafx.h"
#include "SFMMem.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// Construction/Destruction
CSFMServer::CSFMServer()
{
_Init();
//
Create(DEFAULT_FILENAME, DEFAULT_MAPNAME, DEFAULT_MAPSIZE);
}
CSFMServer::~CSFMServer()
{
_Destory();
}
CSFMServer::CSFMServer(char *szFileName, char *szMapName, DWORD dwSize)
{
_Init();
//
Create(szFileName, szMapName, dwSize);
}
void CSFMServer::_Init()
{
m_hFile = NULL;
m_hFileMap = NULL;
m_lpFileMapBuffer = NULL;
m_pFileName = NULL;
m_pMapName = NULL;
m_dwSize = 0;
m_iCreateFlag = 0;
}
void CSFMServer::_Destory()
{
if (m_lpFileMapBuffer)
{
UnmapViewOfFile(m_lpFileMapBuffer);
m_lpFileMapBuffer = NULL;
}
if (m_hFileMap)
{
CloseHandle(m_hFileMap);
m_hFileMap = NULL;
}
if (m_hFile && m_hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
m_hFile = NULL;
}
if (m_pFileName)
{
free(m_pFileName);
m_pFileName = NULL;
}
if (m_pMapName)
{
free(m_pMapName);
m_pMapName = NULL;
}
_Init();
}
void CSFMServer::Create(char *szFileName, char *szMapName, DWORD dwSize)
{
if (m_iCreateFlag)
_Destory();
if (szFileName)
m_pFileName = _strdup(szFileName);
//else m_pFileName = NULL;
if (szMapName)
m_pMapName = _strdup(szMapName);
else m_pMapName = _strdup(DEFAULT_MAPNAME);
if (dwSize > 0)
m_dwSize = dwSize;
else m_dwSize = DEFAULT_MAPSIZE;
if (m_pFileName)
{
// file
m_hFile = CreateFile(
m_pFileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,//OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
else
{
// system
m_hFile = (HANDLE)0xFFFFFFFF;
}
if (m_hFile)
{
m_hFileMap = CreateFileMapping(
m_hFile,
NULL,
PAGE_READWRITE,
0,
m_dwSize,
m_pMapName
);
//使只有一个CSFMServer对象能操作内存对象
//if (m_hFileMap != NULL && ERROR_ALREADY_EXISTS == GetLastError())
//{
// CloseHandle(m_hFileMap);
// m_hFileMap = NULL;
//}
}
if (m_hFileMap)
{
m_lpFileMapBuffer = MapViewOfFile(
m_hFileMap,
FILE_MAP_ALL_ACCESS,//FILE_MAP_WRITE|FILE_MAP_READ,
0,
0,
m_dwSize
);
}
m_iCreateFlag = 1;
}
LPVOID CSFMServer::GetBuffer()
{
return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);
}
DWORD CSFMServer::GetSize()
{
return m_dwSize;
}
// Construction/Destruction
CSFMClient::CSFMClient()
{
_Init();
//
Open(FILE_MAP_READ, DEFAULT_MAPNAME);
}
CSFMClient::~CSFMClient()
{
_Destory();
}
CSFMClient::CSFMClient(DWORD dwAccess, char *szMapName)
{
_Init();
//
Open(dwAccess, szMapName);
}
void CSFMClient::Open(DWORD dwAccess, char *szMapName)
{
if (m_iOpenFlag)
_Destory();
if (szMapName)
m_pMapName = _strdup(szMapName);
else m_pMapName = _strdup(DEFAULT_MAPNAME);
m_hFileMap = OpenFileMapping(
dwAccess,
TRUE,
m_pMapName
);
if (m_hFileMap)
{
m_lpFileMapBuffer = MapViewOfFile(
m_hFileMap,
dwAccess,
0,
0,
0
);
}
m_iOpenFlag = 1;
}
void CSFMClient::_Init()
{
m_hFileMap = NULL;
m_lpFileMapBuffer = NULL;
m_pMapName = NULL;
m_iOpenFlag = 0;
}
void CSFMClient::_Destory()
{
if (m_lpFileMapBuffer)
{
UnmapViewOfFile(m_lpFileMapBuffer);
m_lpFileMapBuffer = NULL;
}
if (m_hFileMap)
{
CloseHandle(m_hFileMap);
m_hFileMap = NULL;
}
if (m_pMapName)
{
free(m_pMapName);
m_pMapName = NULL;
}
_Init();
}
LPVOID CSFMClient::GetBuffer()
{
return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);
}
DWORD CSFMClient::GetSize()
{
// unnable use
return 0;
}
测试环境:Win2K+VC6+普通应用程序
未对服务程序/ISAPI等其他应用进行测试,应该也是可以的