进程间通信_共享内存类_C++实现
来源:互联网 发布:命令启动mysql 编辑:程序博客网 时间:2024/05/17 01:00
参考这个:
http://www.codeproject.com/Articles/1547/Shared-memory
设置一个非常好用的内存共享类,目前实在VC6下开发的,所以如果要在高版本VC用,要简单修改一下循环中的变量;
这个类功能非常强大,而且也很好用,有示例工程,这里我简单写一个示例:
注意的地方:创建的共享内存大小,一定要大于写入的内存大小 + sizeof(DEWORD)以上的字节数;
#include "SharedMemory.h"
CSharedMemory * m_psm = NULL;
#define MEMORY_SIZE 10000
char * pstr = "abcdefghijklmnopqrstuvwxyz";
void Ctmfc1Dlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);
SECURITY_ATTRIBUTES sa = { sizeof sa, &sd, FALSE };
m_psm = new CSharedMemory(_T("TestMemory"),MEMORY_SIZE);
// if ((m_psm) && (m_psm->IsCreated()) && (! m_psm->ExistValue(_T("Test"))))
// {
// m_psm->AddDwordValue(_T("Test"),1);
// }
}
void Ctmfc1Dlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
if ( (m_psm) && (m_psm->IsCreated()) )
{
m_psm->Write( (BYTE*)pstr, strlen(pstr) );
}
}
void Ctmfc1Dlg::OnBnClickedButton6()
{
// TODO: 在此添加控件通知处理程序代码
char strch[1000]={0};
if ( (m_psm) && (m_psm->IsCreated()) )
{
m_psm->Read( (BYTE*)strch, 100 );
}
MessageBox( CString(strch) );
}
转一些其他的文章,作为参考;
头文件:
- /******************************************************************
- ++ File Name : FFMClass.h
- ++ Description: 共享內存類
- ---------------------------------------------------------------
- ++ Author: Fei ZhaoDong
- ++ Create time: 2004/3/25 上午 10:00:00
- ++ Version: 1.1
- ++ Modifier:
- ++ Activities:
- ++ Update List: 2004/3/30 下午 02:59:45
- *******************************************************************/
- // FFMClass.h: interface for the CFFMClass.
- //
- //////////////////////////////////////////////////////////////////////
- #ifndef FZD_FFMCLASS_H
- #define FZD_FFMCLASS_H
- //#include <Winbase.h>
- #include <aclapi.h>
- //////////////////////////////////////////////////////////////////////
- // Macro definition
- // 以下為共享內存定義
- #define DEFAULT_FILENAME NULL // 默認的文件名
- #define DEFAULT_MAPNAME "Local//_FZD_MAP_" // 默認的共享內存名
- #define DEFAULT_MAPSIZE (0xFFFF + 1) // 默認的共享內存大小
- const DWORD NETRGUSER_CFM_CODE = 0x1211DBFF;// 校驗碼, 用於命令數據
- const DWORD NETRGUSER_CMD_NONE = 0; // 初始化指令碼, 無指令
- // 以下為錯誤碼定義
- #define ERROR_LEN 256 // 錯誤描述長度
- #define ERROR_INVALID_CMDCODE 0xE00001FF // 已經存在完全一樣的共享內存
- #define ERROR_NO_MAPFILE 0xE00002FF // 未分配共享內存文件
- #define ERROR_INVALID_CFMCODE 0xE00003FF // 校驗碼不匹配
- //////////////////////////////////////////////////////////////////////
- // 內存文件格式定義
- #pragma pack(1)
- // 用於存儲命令數據的內存文件格式
- typedef struct _tagDATA_HEADER
- {
- DWORD dwConfirmCode;// 校驗碼
- DWORD nCommandCode; // 指令識別碼
- DWORD dwDataSize; // 數據的大小
- BYTE dwReserved[19]; // 保留
- BYTE bInfo[1]; // 數據起始地址
- _tagDATA_HEADER()
- {
- dwConfirmCode = NETRGUSER_CFM_CODE;
- nCommandCode = NETRGUSER_CMD_NONE;
- dwDataSize = 0;
- ZeroMemory(dwReserved, 19);
- ZeroMemory(bInfo, 1);
- }
- }DATA_HEADER, *LPDATA_HEADER;
- typedef DWORD (WINAPI *PSetEntriesInAcl)(ULONG, PEXPLICIT_ACCESS, PACL, PACL*);
- // 用於存儲應答數據的共享內存文件格式 (暫不用)
- typedef struct _tagANS_HEADER
- {
- }ANS_HEADER, *LPANS_HEADER;
- #pragma pack()
- //////////////////////////////////////////////////////////////////////
- // 類定義,共享內存服務端
- class CFFMServer
- {
- public:
- CFFMServer();
- virtual ~CFFMServer();
- CFFMServer(char *szFileName, char *szMapName, DWORD dwSize);
- protected:
- PSetEntriesInAcl m_fnpSetEntriesInAcl;
- HANDLE m_hFile; // 映射文件句柄
- HANDLE m_hFileMap; // 內存文件句柄
- LPVOID m_lpFileMapBuffer;// 緩衝區指針
- char *m_pFileName; // 映射文件名
- char *m_pMapName; // 內存文件名
- DWORD m_dwSize; // 緩衝區大小
- BOOL m_bCreateFlag; // 是否已創建共享內存
- DWORD m_dwLastError; // 錯誤代碼
- private:
- void _Init(); // 初始化參數
- BOOL _IsWinNTLater(); // 判斷當前操作系統
- public:
- BOOL Create(char *szFileName = DEFAULT_FILENAME,
- char *szMapName = DEFAULT_MAPNAME,
- DWORD dwSize = DEFAULT_MAPSIZE);// 新建共享內存
- LPVOID GetBuffer(); // 獲取內存文件指針
- DWORD GetSize(); // 獲取內存文件大小
- void Destory(); // 銷毀已有的共享內存
- BOOL WriteCmdData( // 寫入命令數據
- DWORD nCommandCode,
- DWORD dwDataSize,
- const LPVOID pBuf);
- };
- //////////////////////////////////////////////////////////////////////
- // 類定義,共享內存客戶端
- class CFFMClient
- {
- public:
- CFFMClient();
- virtual ~CFFMClient();
- CFFMClient(DWORD dwAccess,char *szMapName,DWORD dwSize);
- protected:
- HANDLE m_hFileMap; // 內存文件句柄
- LPVOID m_lpFileMapBuffer; // 內存文件指針
- char *m_pMapName; // 內存文件名
- DWORD m_dwSize; // 緩衝區大小
- BOOL m_bOpenFlag; // 是否已經打開了一個內存文件
- DWORD m_dwLastError; // 錯誤代碼
- private:
- void _Init(); // 初始化參數
- public:
- BOOL Open(DWORD dwAccess = FILE_MAP_READ | FILE_MAP_WRITE,
- char *szMapName = DEFAULT_MAPNAME,
- DWORD dwSize = 0); // 打開一個內存文件
- LPVOID GetBuffer(); // 獲取當前內存文件的指針
- void Destory(); // 關閉當前對內存文件的訪問
- DWORD GetSize(); // 獲取內存文件大小
- BOOL GetCmdDataSize(DWORD *pDataSize); // 讀取命令數據大小
- BOOL ReadCmdData( // 讀取命令數據
- DWORD dwCommandCode,
- DWORD dwBufSize,
- LPVOID pOutBuf);
- BOOL WriteCmdData( // 寫入命令數據
- DWORD memSize,
- DWORD nCommandCode,
- DWORD dwDataSize,
- const LPVOID pBuf);
- };
- #endif // FZD_FFMCLASS_H
实现文件:
- /******************************************************************
- ++ File Name : FFMClass.cpp
- ++ Description: 共享內存類
- ---------------------------------------------------------------
- ++ Author: Fei ZhaoDong
- ++ Create time: 2004/3/25 上午 10:00:00
- ++ Version: 1.0
- ++ Modifier:
- ++ Activities:
- ++ Update List: 2004/3/29 下午 02:59:45
- *******************************************************************/
- // FFMClass.cpp: implementation of the CFFMClass.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "FFMClass.h"
- //#include <aclapi.h>
- //#include <windows.h>
- //#include <aclapi.h>
- //#include <lmerr.h>
- //
- //#include <stdio.h>
- //////////////////////////////////////////////////////////////////////
- // CFFMServer
- //////////////////////////////////////////////////////////////////////
- CFFMServer::CFFMServer()
- {
- m_dwLastError = 0;
- m_fnpSetEntriesInAcl = NULL;
- _Init();
- }
- CFFMServer::~CFFMServer()
- {
- Destory();
- }
- CFFMServer::CFFMServer(char *szFileName,char *szMapName,DWORD dwSize)
- {
- // 以自定義設置創建共享內存塊
- _Init();
- Create(szFileName, szMapName, dwSize);
- }
- // 初始化各個參數
- void CFFMServer::_Init()
- {
- m_hFile = NULL;
- m_hFileMap = NULL;
- m_lpFileMapBuffer = NULL;
- m_pFileName = NULL;
- m_pMapName = NULL;
- m_dwSize = 0;
- m_bCreateFlag = FALSE;
- }
- // 判斷是否NT4.0以上操作系統
- BOOL CFFMServer::_IsWinNTLater()
- {
- OSVERSIONINFO Ver;
- BOOL bAbleVersion = FALSE;
- Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (GetVersionEx(&Ver))
- {
- if (Ver.dwPlatformId == VER_PLATFORM_WIN32_NT
- && Ver.dwMajorVersion >= 4)
- {
- bAbleVersion = TRUE;
- }
- }
- else
- {
- m_dwLastError = GetLastError();
- }
- return bAbleVersion;
- }
- // 釋放當前共享內存,並重新初始化參數
- void CFFMServer::Destory()
- {
- if (m_lpFileMapBuffer != NULL)
- {
- UnmapViewOfFile(m_lpFileMapBuffer);
- m_lpFileMapBuffer = NULL;
- }
- if (m_hFileMap != NULL)
- {
- CloseHandle(m_hFileMap);
- m_hFileMap = NULL;
- }
- if (m_hFile && m_hFile != INVALID_HANDLE_VALUE)
- {
- CloseHandle(m_hFile);
- m_hFile = NULL;
- }
- if (m_pFileName != NULL)
- {
- free(m_pFileName);
- m_pFileName = NULL;
- }
- if (m_pMapName != NULL)
- {
- free(m_pMapName);
- m_pMapName = NULL;
- }
- _Init();
- }
- static void FreeSidEx(PSID oSID)
- {
- try
- {
- FreeSid(oSID);
- }
- catch(...)
- {
- }
- }
- // 創建共享內存塊
- BOOL CFFMServer::Create(char *szFileName,char *szMapName,DWORD dwSize)
- {
- // 釋放已有的共享內存塊
- if (m_bCreateFlag)
- {
- Destory();
- }
- // 拷貝各個參數
- if (szFileName)
- {
- m_pFileName = _strdup(szFileName);
- }
- 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)
- {
- m_hFile = CreateFile(
- m_pFileName,
- GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL
- );
- }
- else
- {
- // 默認情況下,在頁面文件中創建共享內存
- m_hFile = INVALID_HANDLE_VALUE;
- }
- if (_IsWinNTLater())
- {
- // Set DACL
- const int NUM_ACES = 2; // number if ACEs int DACL
- // evryone -- read
- // creator -- full access
- // 初始化參數
- PSID pEveryoneSID = NULL; // everyone群組SID
- PSID pCreatorSID = NULL; // creator群組SID
- PACL pFileMapACL = NULL; // 準備新內存文件的DACL
- PSECURITY_DESCRIPTOR pSD = NULL; // 內存文件的SD
- SECURITY_ATTRIBUTES saFileMap; // 內存文件的SA
- EXPLICIT_ACCESS ea[NUM_ACES]; // 外部訪問結構
- BOOL bHasErr = FALSE;// 返回值
- // 以下創建SID
- SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
- SID_IDENTIFIER_AUTHORITY SIDAuthCreator = SECURITY_CREATOR_SID_AUTHORITY;
- // Evryone
- if (!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID,
- 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID))
- {
- bHasErr = TRUE;
- goto Finish;
- }
- // Creator
- if (!AllocateAndInitializeSid(&SIDAuthCreator, 1, SECURITY_CREATOR_OWNER_RID,
- 0, 0, 0, 0, 0, 0, 0, &pCreatorSID))
- {
- bHasErr = TRUE;
- goto Finish;
- }
- // 填充ACE
- ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));
- // S-1-1-0 evryone, 唯讀權限
- ea[0].grfAccessPermissions = GENERIC_READ | GENERIC_WRITE;
- ea[0].grfAccessMode = SET_ACCESS;
- ea[0].grfInheritance= NO_INHERITANCE;
- ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
- ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
- ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
- // S-1-3-0 creator owner, 完全權限
- ea[1].grfAccessPermissions = STANDARD_RIGHTS_ALL;
- ea[1].grfAccessMode = SET_ACCESS;
- ea[1].grfInheritance= NO_INHERITANCE;
- ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
- ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
- ea[1].Trustee.ptstrName = (LPTSTR) pCreatorSID;
- // 創建並填充ACL
- if(NULL == m_fnpSetEntriesInAcl)
- {
- HINSTANCE hLib = ::LoadLibrary("Advapi32.dll");
- if(NULL != hLib)
- {
- m_fnpSetEntriesInAcl = (PSetEntriesInAcl)GetProcAddress(hLib,"SetEntriesInAclA");
- ::FreeLibrary(hLib);
- hLib = NULL;
- }
- }
- if (ERROR_SUCCESS != m_fnpSetEntriesInAcl(NUM_ACES, ea, NULL, &pFileMapACL))
- {
- bHasErr = TRUE;
- goto Finish;
- }
- // 創建並初始化SD
- pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
- if (NULL == pSD)
- {
- bHasErr = TRUE;
- goto Finish;
- }
- if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
- {
- bHasErr = TRUE;
- goto Finish;
- }
- // 添加ACL到SD中去
- if (!SetSecurityDescriptorDacl(pSD,
- TRUE, // fDaclPresent flag
- pFileMapACL,
- FALSE)) // not a default DACL
- {
- bHasErr = TRUE;
- goto Finish;
- }
- // 設置SA
- saFileMap.nLength = sizeof(SECURITY_ATTRIBUTES);
- saFileMap.bInheritHandle = FALSE;
- saFileMap.lpSecurityDescriptor = pSD;
- // 創建共享內存文件
- if (m_hFile != NULL)
- {
- m_hFileMap = CreateFileMapping(
- m_hFile,
- &saFileMap,
- PAGE_READWRITE,
- 0,
- m_dwSize,
- m_pMapName);
- if (NULL == m_hFileMap)
- {
- m_hFileMap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE,
- TRUE, m_pMapName);
- if (NULL == m_hFileMap)
- {
- m_dwLastError = GetLastError();
- Destory();
- goto Finish;
- }
- }
- }
- Finish:
- //if (pSD != NULL)
- //{
- // LocalFree(pSD);
- //}
- pSD = NULL;
- if (pFileMapACL != NULL)
- {
- LocalFree(pFileMapACL);
- pFileMapACL = NULL;
- }
- if (pEveryoneSID != NULL)
- {
- FreeSidEx(pEveryoneSID);
- pEveryoneSID = NULL;
- }
- if (pCreatorSID != NULL)
- {
- FreeSidEx(pCreatorSID);
- pCreatorSID = NULL;
- }
- if (bHasErr)
- {
- m_dwLastError = GetLastError();
- return FALSE;
- }
- }
- else
- {
- // 創建共享內存文件
- if (m_hFile)
- {
- m_hFileMap = CreateFileMapping(
- m_hFile,
- NULL,
- PAGE_READWRITE,
- 0,
- m_dwSize,
- m_pMapName);
- if (NULL == m_hFileMap)
- {
- m_dwLastError = GetLastError();
- Destory();
- return FALSE;
- }
- }
- }
- // 映射文件指針到用戶
- if (m_hFileMap)
- {
- m_lpFileMapBuffer = MapViewOfFile(
- m_hFileMap,
- FILE_MAP_ALL_ACCESS,
- 0,
- 0,
- m_dwSize);
- if (NULL == m_lpFileMapBuffer)
- {
- m_dwLastError = GetLastError();
- Destory();
- return FALSE;
- }
- }
- m_bCreateFlag = TRUE;
- return TRUE;
- }
- // 獲取內存文件指針
- LPVOID CFFMServer::GetBuffer()
- {
- return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);
- }
- // 獲取內存文件大小
- DWORD CFFMServer::GetSize()
- {
- return m_dwSize;
- }
- BOOL CFFMServer::WriteCmdData(DWORD nCommandCode,DWORD dwDataSize,constLPVOID pBuf)
- {
- // 檢驗數據的合理性
- if (NULL == GetBuffer())
- {
- m_dwLastError = ERROR_NO_MAPFILE;
- SetLastError(ERROR_NO_MAPFILE);
- return FALSE;
- }
- if (NETRGUSER_CMD_NONE == nCommandCode)
- {
- m_dwLastError = ERROR_INVALID_CMDCODE;
- SetLastError(ERROR_INVALID_CMDCODE);
- return FALSE;
- }
- if (dwDataSize > 0 && pBuf == NULL)
- {
- m_dwLastError = ERROR_INVALID_USER_BUFFER;
- SetLastError(ERROR_INVALID_USER_BUFFER);
- return FALSE;
- }
- if (dwDataSize + sizeof(DATA_HEADER) > GetSize())
- {
- m_dwLastError = ERROR_BUFFER_OVERFLOW;
- SetLastError(ERROR_BUFFER_OVERFLOW);
- return FALSE;
- }
- // 填寫數據結構
- // 文件頭
- DATA_HEADER dataHeader;
- dataHeader.nCommandCode = nCommandCode;
- dataHeader.dwDataSize = dwDataSize;
- ZeroMemory(GetBuffer(), GetSize());
- memcpy(GetBuffer(), &dataHeader, sizeof(DATA_HEADER));
- // 數據塊
- LPDATA_HEADER pData = (LPDATA_HEADER)GetBuffer();
- memcpy(pData->bInfo, pBuf, dwDataSize);
- return TRUE;
- }
- //////////////////////////////////////////////////////////////////////
- // CFFMClient
- //////////////////////////////////////////////////////////////////////
- CFFMClient::CFFMClient()
- {
- m_dwLastError = 0;
- _Init();
- }
- CFFMClient::~CFFMClient()
- {
- Destory();
- }
- CFFMClient::CFFMClient(DWORD dwAccess,char *szMapName,DWORD dwSize)
- {
- _Init();
- if (!Open(dwAccess, szMapName, dwSize))
- {
- Destory();
- }
- }
- // 初始化參數
- void CFFMClient::_Init()
- {
- m_hFileMap = NULL;
- m_lpFileMapBuffer = NULL;
- m_pMapName = NULL;
- m_bOpenFlag = FALSE;
- }
- // 關閉當前對內存文件的訪問
- void CFFMClient::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();
- }
- // 打開一個內存文件
- BOOL CFFMClient::Open(DWORD dwAccess,char *szMapName,DWORD dwSize)
- {
- if (m_bOpenFlag)
- {
- Destory();
- }
- if (szMapName != NULL)
- {
- m_pMapName = _strdup(szMapName);
- }
- else
- {
- m_pMapName = _strdup(DEFAULT_MAPNAME);
- }
- m_hFileMap = OpenFileMapping(dwAccess, TRUE, m_pMapName);
- if (NULL == m_hFileMap)
- {
- m_dwLastError = GetLastError();
- Destory();
- return FALSE;
- }
- m_lpFileMapBuffer = MapViewOfFile(m_hFileMap, dwAccess, 0, 0, dwSize);
- if (NULL == m_lpFileMapBuffer)
- {
- m_dwLastError = GetLastError();
- Destory();
- return FALSE;
- }
- m_bOpenFlag = TRUE;
- return TRUE;
- }
- // 獲取當前內存文件的指針
- LPVOID CFFMClient::GetBuffer()
- {
- return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);
- }
- // 讀取命令數據大小
- BOOL CFFMClient::GetCmdDataSize(DWORD *pDataSize)
- {
- _ASSERT(pDataSize != NULL);
- *pDataSize = 0;
- LPDATA_HEADER pHeader = (LPDATA_HEADER)GetBuffer();
- if (NULL == pHeader)
- {
- m_dwLastError = ERROR_NO_MAPFILE;
- SetLastError(ERROR_NO_MAPFILE);
- return FALSE;
- }
- if (NETRGUSER_CFM_CODE != pHeader->dwConfirmCode)
- {
- m_dwLastError = ERROR_INVALID_CFMCODE;
- SetLastError(ERROR_INVALID_CFMCODE);
- return FALSE;
- }
- if (NETRGUSER_CMD_NONE == pHeader->nCommandCode)
- {
- m_dwLastError = ERROR_INVALID_CMDCODE;
- SetLastError(ERROR_INVALID_CMDCODE);
- return FALSE;
- }
- *pDataSize = pHeader->dwDataSize;
- return TRUE;
- }
- // 讀取命令數據
- BOOL CFFMClient::ReadCmdData(DWORD dwCommandCode,DWORD dwBufSize,LPVOID pOutBuf)
- {
- _ASSERT (pOutBuf != NULL);
- LPDATA_HEADER pHeader = (LPDATA_HEADER)GetBuffer();
- if (NULL == pHeader)
- {
- m_dwLastError = ERROR_NO_MAPFILE;
- SetLastError(ERROR_NO_MAPFILE);
- return FALSE;
- }
- if (NETRGUSER_CFM_CODE != pHeader->dwConfirmCode)
- {
- m_dwLastError = ERROR_INVALID_CFMCODE;
- SetLastError(ERROR_INVALID_CFMCODE);
- return FALSE;
- }
- if (NETRGUSER_CMD_NONE == pHeader->nCommandCode)
- {
- m_dwLastError = ERROR_INVALID_CMDCODE;
- SetLastError(ERROR_INVALID_CMDCODE);
- return FALSE;
- }
- if (pHeader->dwDataSize > dwBufSize)
- {
- m_dwLastError = ERROR_BUFFER_OVERFLOW;
- SetLastError(ERROR_BUFFER_OVERFLOW);
- return FALSE;
- }
- if (pHeader->nCommandCode != dwCommandCode)
- {
- m_dwLastError = ERROR_INVALID_CMDCODE;
- SetLastError(ERROR_INVALID_CMDCODE);
- return FALSE;
- }
- ZeroMemory(pOutBuf, dwBufSize);
- // 拷貝數據到緩衝區
- memcpy(pOutBuf, pHeader->bInfo, pHeader->dwDataSize);
- return TRUE;
- }
- BOOL CFFMClient::WriteCmdData(DWORD memSize,DWORD nCommandCode,DWORD dwDataSize,constLPVOID pBuf)
- {
- if(!memSize)
- memSize = DEFAULT_MAPSIZE;
- m_dwSize = memSize;
- // 檢驗數據的合理性
- if (NULL == GetBuffer())
- {
- m_dwLastError = ERROR_NO_MAPFILE;
- SetLastError(ERROR_NO_MAPFILE);
- return FALSE;
- }
- if (NETRGUSER_CMD_NONE == nCommandCode)
- {
- m_dwLastError = ERROR_INVALID_CMDCODE;
- SetLastError(ERROR_INVALID_CMDCODE);
- return FALSE;
- }
- if (dwDataSize > 0 && pBuf == NULL)
- {
- m_dwLastError = ERROR_INVALID_USER_BUFFER;
- SetLastError(ERROR_INVALID_USER_BUFFER);
- return FALSE;
- }
- if (dwDataSize + sizeof(DATA_HEADER) > GetSize())
- {
- m_dwLastError = ERROR_BUFFER_OVERFLOW;
- SetLastError(ERROR_BUFFER_OVERFLOW);
- return FALSE;
- }
- // 填寫數據結構
- // 文件頭
- DATA_HEADER dataHeader;
- dataHeader.nCommandCode = nCommandCode;
- dataHeader.dwDataSize = dwDataSize;
- ZeroMemory(GetBuffer(), GetSize());
- memcpy(GetBuffer(), &dataHeader, sizeof(DATA_HEADER));
- // 數據塊
- LPDATA_HEADER pData = (LPDATA_HEADER)GetBuffer();
- memcpy(pData->bInfo, pBuf, dwDataSize);
- return TRUE;
- }
- // 獲取內存文件大小
- DWORD CFFMClient::GetSize()
- {
- return m_dwSize;
- }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////一个简单类
#ifndef _CSHAREMEMORY
#define _CSHRREMEMORY
class CShareMemory
{
public:
CShareMemory();
~CShareMemory();
bool CreateShareMemory(DWORD MemorySize,char *ShareMemoryName); //创建共享内存
bool OpenShareMemory(char *ShareMemoryName); //打开一个现有的共享内存
void CloseShare(); //关闭释放共享内存
public:
HANDLE m_filemapp; //文件映射
char *m_shareAddress; //共享内存起始地址
};
#endif
#include"StdAfx.h"
#include"CShareMemory.h"
CShareMemory::CShareMemory()
{
m_filemapp=NULL;
m_shareAddress=NULL;
}
CShareMemory::~CShareMemory()
{
CloseShare();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//DWORD MemorySizy 共享内存大小;
// char *ShareMemeoryName 共享内存名称
////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CShareMemory::CreateShareMemory(DWORD MemorySize,char *ShareMemoryName)
{
//创建文件映射对象;
HANDLE sh=CreateFileMapping(INVALID_HANDLE_VALUE,0,PAGE_READWRITE,0,MemorySize,ShareMemoryName);
//将文件映射对象映射到当前应用程序的地址空间;
m_shareAddress=(char *)MapViewOfFile(sh,FILE_MAP_ALL_ACCESS,0,0,0);
if(sh==NULL)
return false;
//若创建的共享内存命名空间 与现有的内存映射,互斥量,信号量,临界区 同名,则返回失败;
if(GetLastError()==ERROR_INVALID_HANDLE)
{
CloseShare();
return false;
}
//若创建的共享内存为创建,则创建新的共享内存,清空共享内存空间;
if(GetLastError()!=ERROR_ALREADY_EXISTS)
ZeroMemory(m_shareAddress,MemorySize);
m_filemapp=sh;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//CShareMemory::OpenShareMemory 打开现有的共享内存
//ÐβΣºchar *ShareMemeoryName 共享内存名称
////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CShareMemory::OpenShareMemory(char *ShareMemoryName)
{
//打开现有的共享内存
HANDLE sh=OpenFileMapping(FILE_MAP_ALL_ACCESS,false,ShareMemoryName);
m_shareAddress=(char *)MapViewOfFile(sh,FILE_MAP_ALL_ACCESS,0,0,0);
if(sh==NULL)
{
return false;
}
m_filemapp=sh;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//CShareMemory::CloseShare() 关闭释放共享内存
////////////////////////////////////////////////////////////////////////////////////////////////////////
void CShareMemory::CloseShare()
{
UnmapViewOfFile(m_shareAddress);
CloseHandle(m_filemapp);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////另一篇,简单参考
// 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 "TestShareMemory"
#define DEFAULT_MAPSIZE (0x0FFF + 1)
// Shared FileMap Server
// 使用说明
// 1.
// 创建CSFMServer对象
// CSFMServer(char *szFileName, char *szMapName, DWORD dwSize);
// Create(char *szFileName, char *szMapName, DWORD dwSize);
// 参数1:NULL或指定的文件(将创建或打开并读写/麻烦)
// 参数2:要创建的共享内存对象名
// 参数3:要创建的共享内存对象大小
// 2.
// 本地使用内存
// LPVOID GetBuffer()
// 返回共享内存地址
//
// 自动销毁
class
CSFMServer
{
public
:
CSFMServer();
virtual
~CSFMServer();
CSFMServer(
char
*szFileName,
char
*szMapName,
DWORD
dwSize);
HANDLE
m_hMutex;
protected
:
HANDLE
m_hFile;
HANDLE
m_hFileMap;
LPVOID
m_lpFileMapBuffer;
string m_strMutexName;
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
// 使用说明
// 1.
// 创建CSFMClient对象
// CSFMClient(DWORD dwAccess, char *szMapName);
// Open(DWORD dwAccess, char *szMapName);
// 参数1:共享内存对象访问方式(FILE_MAP_READ|FILE_MAP_WRITE)
// 参数2:共享内存对象名
// 2.
// 本地使用内存
// LPVOID GetBuffer()
// 返回共享内存地址
//
// 自动销毁
class
CSFMClient
{
public
:
CSFMClient();
virtual
~CSFMClient();
CSFMClient(
DWORD
dwAccess,
char
*szMapName,
DWORD
size);
HANDLE
m_hMutex;
protected
:
HANDLE
m_hFileMap;
LPVOID
m_lpFileMapBuffer;
string m_strMutexName;
char
*m_pMapName;
DWORD
m_dwSize;
//共享缓冲区的大小
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);
//Create(DEFAULT_FILENAME, DEFAULT_MAPNAME, DEFAULT_MAPSIZE);
}
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)
{
if
(!UnmapViewOfFile(m_lpFileMapBuffer))
{
printf
(
"Server UnmapViewOfFile失败!rn"
);
}
m_lpFileMapBuffer = NULL;
}
if
(m_hFileMap)
{
if
(!CloseHandle(m_hFileMap))
{
printf
(
"Server CloseHandle 关闭映射文件句柄失败!rn"
);
}
m_hFileMap = NULL;
}
if
(m_hFile && m_hFile != INVALID_HANDLE_VALUE)
{
if
(!CloseHandle(m_hFile))
{
printf
(
"Server CloseHandle 关闭互斥体句柄失败!rn"
);
}
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);
m_strMutexName=szMapName;
m_strMutexName+=
"mutex"
;
}
else
{
m_pMapName = _strdup(DEFAULT_MAPNAME);
m_strMutexName=DEFAULT_MAPNAME;
m_strMutexName+=
"mutex"
;
}
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;
}
DWORD
error;
//OutputDebugString((LPCSTR)m_hFile);
//error=GetLastError();
if
(m_hFile)
{
m_hFileMap = CreateFileMapping(
m_hFile,
NULL,
PAGE_READWRITE,
0,
m_dwSize,
m_pMapName
);
//OutputDebugString((LPCSTR)m_hFile);
//使只有一个CSFMServer对象能操作内存对象(郝兴峰修改)
if
(m_hFileMap != NULL)
{
error=GetLastError();
if
( ERROR_ALREADY_EXISTS == error)
//如果已经存在了,就不要创建操作了。
{
m_hMutex=OpenMutex(SYNCHRONIZE,FALSE,m_strMutexName.c_str());
}
else
{
m_hMutex=CreateMutex(NULL,FALSE,m_strMutexName.c_str());
}
}
else
{
printf
(
"Server CreateFileMapping失败!rn"
);
}
}
else
{
printf
(
"Server CreateFile 失败!rn"
);
}
if
(m_hFileMap)
{
m_lpFileMapBuffer = MapViewOfFile(
m_hFileMap,
FILE_MAP_ALL_ACCESS,
//FILE_MAP_WRITE|FILE_MAP_READ,
0,
0,
0
//m_dwSize改成0,在这里把它改为0,和读取写入的程序一样。郝兴峰修改09.11.13
);
if
(NULL==m_lpFileMapBuffer)
{
printf
(
"Server MapViewOfFile 失败!rn"
);
}
}
memset
(m_lpFileMapBuffer,
''
,m_dwSize);
//设置共享内存中的数据为0
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_ALL_ACCESS, DEFAULT_MAPNAME);
}
CSFMClient::~CSFMClient()
{
Destory();
}
CSFMClient::CSFMClient(
DWORD
dwAccess,
char
*szMapName,
DWORD
isizemap)
{
Init();
m_dwSize=isizemap;
//打开共享缓冲区
Open(dwAccess, szMapName);
}
void
CSFMClient::Open(
DWORD
dwAccess,
char
*szMapName)
{
if
(m_iOpenFlag)
Destory();
if
(szMapName)
{
m_pMapName = _strdup(szMapName);
m_strMutexName=szMapName;
m_strMutexName+=
"mutex"
;
}
else
{
m_pMapName = _strdup(DEFAULT_MAPNAME);
m_strMutexName=DEFAULT_MAPNAME;
m_strMutexName+=
"mutex"
;
}
try
{
m_hFileMap = OpenFileMapping(
FILE_MAP_ALL_ACCESS,
FALSE,
m_pMapName
);
if
(m_hFileMap)
{
m_lpFileMapBuffer = MapViewOfFile(
m_hFileMap,
FILE_MAP_ALL_ACCESS,
0,
0,
0
//hxf修改,把0改成m_dwSize。把m_dwSize改成0,和上面的创建性质一样、郝兴峰,09.11.13
);
if
(NULL==m_lpFileMapBuffer)
{
printf
(
"Client MapViewOfFile失败!rn"
);
}
m_hMutex=OpenMutex(SYNCHRONIZE,FALSE,m_strMutexName.c_str());
}
else
{
printf
(
"Client OpenFileMapping失败!rn"
);
}
}
catch
(exception &e)
{
printf
(
"Client MapViewOfFile或者Client OpenFileMapping异常rn"
);
printf
(
"%srn"
,e.what());
}
m_iOpenFlag = 1;
}
void
CSFMClient::Init()
{
m_hFileMap = NULL;
m_lpFileMapBuffer = NULL;
m_hMutex=NULL;
m_pMapName = NULL;
m_dwSize=0;
m_iOpenFlag = 0;
}
void
CSFMClient::Destory()
{
if
(m_lpFileMapBuffer)
{
if
(!UnmapViewOfFile(m_lpFileMapBuffer))
{
printf
(
"Client UnmapViewOfFile 失败!rn"
);
}
m_lpFileMapBuffer = NULL;
}
if
(m_hFileMap)
{
if
(!CloseHandle(m_hFileMap))
{
printf
(
"Client 关闭映射文件句柄失败!rn"
);
}
m_hFileMap = NULL;
}
if
(m_pMapName)
{
free
(m_pMapName);
m_pMapName = NULL;
}
if
(m_hMutex)
{
if
(!CloseHandle(m_hMutex))
{
printf
(
"Client 关闭互斥体句柄失败!rn"
);
}
m_hMutex=NULL;
}
Init();
}
LPVOID
CSFMClient::GetBuffer()
{
return
(m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);
}
//这里可能有点问题
DWORD
CSFMClient::GetSize()
{
// unnable use
return
m_dwSize;
}
也可以参考这个:
http://www.codeproject.com/Articles/1547/Shared-memory
设置一个非常好用的内存共享类,目前实在VC6下开发的,所以如果要在高版本VC用,要简单修改一下循环中的变量;
这个类功能非常强大,而且也很好用,有示例工程,这里我简单写一个示例:
#include "SharedMemory.h"
CSharedMemory * m_psm = NULL;
#define MEMORY_SIZE 10000
char * pstr = "abcdefghijklmnopqrstuvwxyz";
void Ctmfc1Dlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);
SECURITY_ATTRIBUTES sa = { sizeof sa, &sd, FALSE };
m_psm = new CSharedMemory(_T("TestMemory"),MEMORY_SIZE);
// if ((m_psm) && (m_psm->IsCreated()) && (! m_psm->ExistValue(_T("Test"))))
// {
// m_psm->AddDwordValue(_T("Test"),1);
// }
}
void Ctmfc1Dlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
if ( (m_psm) && (m_psm->IsCreated()) )
{
m_psm->Write( (BYTE*)pstr, strlen(pstr) );
}
}
void Ctmfc1Dlg::OnBnClickedButton6()
{
// TODO: 在此添加控件通知处理程序代码
char strch[1000]={0};
if ( (m_psm) && (m_psm->IsCreated()) )
{
m_psm->Read( (BYTE*)strch, 100 );
}
MessageBox( CString(strch) );
}
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++实现
- 进程间通信_共享内存类_C++
- Windows 进程间通信 共享内存(FileMapping)_C#实现
- 利用共享内存实现进程间通信
- 利用共享内存实现进程间通信
- 共享内存实现进程间通信
- 共享内存实现进程间通信
- 共享内存----实现进程间通信
- 利用共享内存实现进程间通信
- 共享内存实现进程间通信
- 中南大学2012年8月月赛Problem E: Enjoy treasure 3维迷宫
- Flex与Java通过blazeds.war实现通讯
- MFC使用ToolBar工具栏添加真彩色图标
- c#如何查看动态链接库接口
- 伤感日志发布:如果一切重来。我会更加珍惜
- 进程间通信_共享内存类_C++实现
- FreeRDP
- SVN
- ntohs, ntohl, htons,htonl的比较
- 【C++模版之旅】项目中一次活用C++模板(traits)的经历
- Mstar虚拟按键触摸屏驱动(芯片msg2133,按键使用android虚拟按键实现,特定报点,识别为按键)
- 学习java要经常看的网站
- 手动打包sun java jdk [Installing the latest JDK on Debian by creating a .deb package from Sun binaries]
- 从google code svn下载代码 提示svn url不存在的解决方法