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

全部博文(1227)

文章存档

2010年(1)

2008年(1226)

我的朋友

分类: C/C++

2008-03-14 15:49:23

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

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

二、使用说明

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