参考这个:
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) );
}
转一些其他的文章,作为参考;
头文件:
实现文件:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////一个简单类
#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) );
}