Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9728079
  • 博文数量: 1227
  • 博客积分: 10026
  • 博客等级: 上将
  • 技术积分: 20273
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-16 12:40
文章分类

全部博文(1227)

文章存档

2010年(1)

2008年(1226)

我的朋友

分类: C/C++

2008-04-23 21:36:53

共享内存封装类
作者:



本文介绍一个共享内存封装类,使共享内存的使用更简单化,特别适合更懒的程序员使用:-)

一、实现目标:简单化使用共享内存

二、使用说明

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等其他应用进行测试,应该也是可以的
阅读(660) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~