程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 共享內存封裝類

共享內存封裝類

編輯:關於VC++

本文介紹一個共享內存封裝類,使共享內存的使用更簡單化,特別適合更懶的程序員使用:-)

一、實現目標:簡單化使用共享內存

二、使用說明:

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等其他應用進行測試,應該也是可以的.

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved