一個操作共享記憶體的類!可以方面的新增,刪除資料,包括各種結構體! (轉)

gugu99發表於2008-08-07
一個操作共享記憶體的類!可以方面的新增,刪除資料,包括各種結構體! (轉)[@more@]

// ShareMem.h: interface for the CShareMem class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SHAREMEM_H__DC737B1E_1A7A_427E_8852_A7E98F696F05__INCLUDED_)
#define AFX_SHAREMEM_H__DC737B1E_1A7A_427E_8852_A7E98F696F05__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CShareMem 
{
public:
 CShareMem();
 CShareMem(int cCount,size_t cSize);
 virtual ~CShareMem();
 BOOL InitializeMem(int cCount,size_t cSize );
 size_t GetDataSize() {return m_cDataSize;};
 int GetDataCount() {return m_cDataCount;};
 BOOL Clear() ;
 BOOL Lock(D dwMilliSeconds = INFINITE);
 BOOL Unlock();
 LPVOID GetData(int nIndex = 0);
 BOOL GetData(int nIndex ,LPVOID lpvData,size_t cSize);
 BOOL AddData(LPVOID lpvData,size_t cSize);
 BOOL SetData(int nIndex ,LPVOID lpvData,size_t cSize);
 BOOL Delete(int nIndex );
protected:
 LPVOID m_lpvData; //資料指標
 size_t m_cDataSize; //資料元素大小(BYTE)
 int m_cDataCount; //資料元素個數
 BOOL m_fInit; //是否初始化成功
 HANDLE m_hMutant; //互斥量
 HANDLE m_hSharedMemoryFile; //共享核心控制程式碼
 CString m_strMutantName; //互斥量名字
 CString m_strShareMemName; //共享記憶體區域名字
 BOOL m_fExist ; //是否已存在

};

#endif // !defined// ShareMem.cpp: implementation of the CShareMem class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ShareMem.h"

#ifdef _DE
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CShareMem::CShareMem()
{
 m_cDataCount = 0;
 m_cDataSize = 0;
 m_fInit = FALSE;
 m_fExist = FALSE;
 m_lpvData = NULL;
 m_hSharedMemoryFile = NULL;
 m_strMutantName = L"ShareMemMutant";
 m_strShareMemName = L"ShareMemSection";
}
//清除所有共享記憶體區域的資料
BOOL CShareMem::Clear()
{
 try
 {
 memset((PBYTE)m_lpvData,0,m_cDataSize*m_cDataCount);
 return TRUE;
 }
 catch(...)
 {
 return FALSE;
 }
}
CShareMem::~CShareMem()
{
 if (m_fInit) //
 {
 UnmapViewOfFile(m_lpvData);
 CloseHandle(m_hSharedMemoryFile);
 }
}
CShareMem::CShareMem(int cCount,size_t cSize)
{
 m_cDataCount = cCount;
 m_cDataSize = cSize;
 m_fInit = FALSE;
 m_lpvData = NULL;
 m_hSharedMemoryFile = NULL;
 m_fExist = FALSE;
 m_strMutantName = L"ShareMemMutant";
 m_strShareMemName = L"ShareMemSection";
}
//取得nIndex位置上的資料指標
LPVOID CShareMem::GetData(int nIndex )
{
 if (m_fInit)
 {
 if (nIndex < 0 || nIndex >= m_cDataCount)
 return NULL;
 return (PBYTE)m_lpvData + nIndex * m_cDataSize;
 }
 else
 {
 return NULL;
 }
}
//取得nIndex位置上的資料
BOOL CShareMem::GetData(int nIndex,LPVOID lpvData,size_t cSize)
{
 if (m_fInit)
 {
 if (nIndex < 0 || nIndex >= m_cDataCount)
 return FALSE;
 if (cSize != m_cDataSize )
 {
 return FALSE;
 }
 memcpy(lpvData,(PBYTE)m_lpvData + nIndex * m_cDataSize,cSize);
 return TRUE;
 }
 else
 {
 return FALSE;
 }
}
//刪除 nIndex位置的資料
BOOL CShareMem::Delete(int nIndex)
{
 if (m_fInit)
 {
 if (nIndex < 0 || nIndex >= m_cDataCount)
 return FALSE;
 int nLeft = m_cDataCount - nIndex - 1;
 PBYTE pbBuff = new BYTE[nLeft * m_cDataSize];
 if (0== nIndex ) //刪除頭
 {
 memcpy(pbBuff,(PBYTE)m_lpvData + m_cDataSize ,(m_cDataCount -1)*m_cDataSize);
 memset(m_lpvData,0,m_cDataCount * m_cDataSize);
 memcpy(m_lpvData,pbBuff,(m_cDataCount -1)*m_cDataSize);
 }
 else if ((m_cDataCount -1) == nIndex ) //刪除尾
 {
 memset((PBYTE)m_lpvData + (nIndex *m_cDataSize),0 ,m_cDataSize);
 }
 else
 {
 memcpy(pbBuff,(PBYTE)m_lpvData + (nIndex + 1)*m_cDataSize,nLeft * m_cDataSize);
 memset((PBYTE)m_lpvData + (nIndex  )*m_cDataSize,0,(m_cDataCount - nIndex) * m_cDataSize);
 memcpy((PBYTE)m_lpvData + (nIndex )*m_cDataSize,pbBuff,nLeft *m_cDataSize);
 }
 delete [] pbBuff;
 m_cDataCount --;
 return TRUE;
 }
 else
 {
 return FALSE;
 }
}
//新增資料到資料尾
BOOL CShareMem::AddData(LPVOID lpvData,size_t cSize)
{
 try
 {
 //
 if ((m_cDataSize!= 0 && m_cDataSize != cSize))
 {
 return FALSE;
 }
 if (!m_fInit)
 {
 return FALSE;
 }
 //
 //if (m_cDataCount == 0)
 memcpy((PBYTE)m_lpvData + (m_cDataCount )*m_cDataSize, lpvData,cSize);
 m_cDataCount ++ ;
 return TRUE;
 }
 catch(CMemoryException *memE)
 {
 memE->ReportError();
 memE->Delete();
 return FALSE;
 }
 catch(...)
 {
 return FALSE;
 }
}
//設定nIndex位置上的資料
BOOL CShareMem::SetData(int nIndex,LPVOID lpvData,size_t cSize)
{
 if (m_fInit)
 {
 if (nIndex < 0 || nIndex >= m_cDataCount)
 return FALSE;
 if (m_cDataSize != cSize)
 {
 TRACE(_T("資料大小不匹配!!!n"));
 return FALSE;
 }
 memset((PBYTE)m_lpvData + nIndex * m_cDataSize,0,cSize);
 memcpy((PBYTE)m_lpvData + nIndex * m_cDataSize,lpvData,cSize);
 return TRUE;
 }
 else
 {
 return FALSE;
 }
}
//初始化 共享記憶體和各個變數
BOOL CShareMem::InitializeMem(int cCount,size_t cSize)
{
 m_hMutant = CreateMutex(NULL,FALSE,m_strMutantName);
 m_cDataSize = cSize;
 m_cDataCount = cCount;
 
 //建立一記憶體對映檔案,設定共享記憶體區域
 m_hSharedMemoryFile = ::CreateFileMap(
  (HANDLE)0xFFFFFFFF,  // 檔案控制程式碼
  NULL,  // 屬性(WIN95忽略)
  PAGE_READWRITE,  // 檔案的保護屬性
  0,  // 使用頁面檔案
  1<<16,  // 共享記憶體大小
 m_strShareMemName.GetBuffer(0));// 共享記憶體名稱

 if(m_hSharedMemoryFile == NULL)
 {
 m_fExist = FALSE;
 m_fInit = FALSE;
 return FALSE;
 }
 else
 {
 if(GetLastError() == ERROR_ALREADY_EXISTS)
 m_fExist = TRUE;
 }
 m_lpvData = ::MapViewOfFile(
  m_hSharedMemoryFile,  // 核心的檔案HANDLE
  FILE_MAP_ALL_ACCESS, // Read/Write
  0,  // 使用頁面檔案
  0,  // 對映整個共享記憶體區域
  0);  // 對映整個空間
 if(m_lpvData == NULL)
 {
 m_fInit = FALSE;
 CloseHandle(m_hSharedMemoryFile);
 return FALSE;
 }
 else
 m_fInit = TRUE;
 return TRUE; 
}
//互斥鎖定共享記憶體
BOOL CShareMem::Lock(DWORD dwMilliSeconds )
{
 if( WaitForSingle(m_hMutant,dwMilliSeconds) == WAIT_OBJECT_0)
 return TRUE;
 return FALSE;
}
//互斥解鎖共享記憶體
BOOL CShareMem::Unlock()
{
 return ReleaseMutex(m_hMutant);
}

實在不好意思!開始有個地方有點小錯誤!:)

memcpy(pbBuff,(PBYTE)m_lpvData + (nIndex + 1)*m_cDataSize,nLeft * m_cDataSize);

 memset((PBYTE)m_lpvData + (nIndex +1 )*m_cDataSize,0,(m_cDataCount - nIndex) * m_cDataSize);

memcpy((PBYTE)m_lpvData + (nIndex +1 )*m_cDataSize,pbBuff,nLeft *m_cDataSize); 改為:

 memcpy(pbBuff,(PBYTE)m_lpvData + (nIndex + 1)*m_cDataSize,nLeft * m_cDataSize);

memset((PBYTE)m_lpvData + (nIndex )*m_cDataSize,0,(m_cDataCount - nIndex) * m_cDataSize);

memcpy((PBYTE)m_lpvData + (nIndex )*m_cDataSize,pbBuff,nLeft *m_cDataSize); 一不小心就複製了!

現在的是重新修改後的,望大家見諒!!:)這個類可以方便的進行資料新增,刪除!!建議大家使用時將它作為CWinApp派生子類的public成員變數,這樣就可以方便的在工程的任何地方了!希望對大家有用!:)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1008681/,如需轉載,請註明出處,否則將追究法律責任。

相關文章