用文件映射(File Mapping)实现进程间内存共享
来源:互联网 发布:设备保养软件 编辑:程序博客网 时间:2024/06/05 20:07
引用自:http://blog.csdn.net/starlee/archive/2007/06/01/1633762.aspx
我们知道,在Windows中的每个进程都有自己独立的内存空间。该独立的内存空间包含了所有的可执行模块或DLL模块的代码和数据以及动态内存分配的空间。每个进程的内存空间只能被该进程访问,其他进程是不能访问的。
如果我们要想在进程间共享内存(也就是创建一块不同进程都能访问的内存),那就必须使用内核对象。因为内核对象由Windows系统内核所拥有,而不是由进程所拥有。
下面就用文件映射(File Mapping)和互斥量(Mutex)两中内核对象来实现简单的进程间内存共享。文件映射(File Mapping)用来开辟共享的内存空间,而互斥量(Mutex)则是用来使读写互斥。 Windows,实际上只有映像文件共享内存一种。
在该例子里,实现了下面5个函数用来进行进程间的内存共享。可以把这5个函数放到一个DLL里面当成输出函数来用。在进程里加载该DLL并调用相应的函数就可实现进程间内存共享。
首先,定义返回值代码:
然后,是函数声明:
下面是函数的实现:
用到的主要接口有:
我们知道,在Windows中的每个进程都有自己独立的内存空间。该独立的内存空间包含了所有的可执行模块或DLL模块的代码和数据以及动态内存分配的空间。每个进程的内存空间只能被该进程访问,其他进程是不能访问的。
如果我们要想在进程间共享内存(也就是创建一块不同进程都能访问的内存),那就必须使用内核对象。因为内核对象由Windows系统内核所拥有,而不是由进程所拥有。
下面就用文件映射(File Mapping)和互斥量(Mutex)两中内核对象来实现简单的进程间内存共享。文件映射(File Mapping)用来开辟共享的内存空间,而互斥量(Mutex)则是用来使读写互斥。 Windows,实际上只有映像文件共享内存一种。
在该例子里,实现了下面5个函数用来进行进程间的内存共享。可以把这5个函数放到一个DLL里面当成输出函数来用。在进程里加载该DLL并调用相应的函数就可实现进程间内存共享。
首先,定义返回值代码:
typedef enum
{
LX_OK = 0, // 正常返回
LX_SHAREDMEMORY_EXISTS = 1, // 共享内存已经存在
LX_INVALID_SHAREDMEMORY = 2, // 共享内存错误返回
LX_INVALID_SIZE = 3 // 共享内存大小错误
}LX_RETURN_VALUE;
{
LX_OK = 0, // 正常返回
LX_SHAREDMEMORY_EXISTS = 1, // 共享内存已经存在
LX_INVALID_SHAREDMEMORY = 2, // 共享内存错误返回
LX_INVALID_SIZE = 3 // 共享内存大小错误
}LX_RETURN_VALUE;
// 创建共享内存
LX_RETURN_VALUE CreateSharedMemory(UINT nSize);
// 释放共享内存
LX_RETURN_VALUE ReleaseSharedMemory();
// 得到共享内存大小
LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize);
// 向共享内存写入数据
LX_RETURN_VALUE WriteToSharedMemory(void *pData, UINT nSize);
// 从共享内存读取数据
LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize);
LX_RETURN_VALUE CreateSharedMemory(UINT nSize);
// 释放共享内存
LX_RETURN_VALUE ReleaseSharedMemory();
// 得到共享内存大小
LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize);
// 向共享内存写入数据
LX_RETURN_VALUE WriteToSharedMemory(void *pData, UINT nSize);
// 从共享内存读取数据
LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize);
// 互斥量
CMutex g_mMutex(FALSE, "StarLeeMutex");
LX_RETURN_VALUE CreateSharedMemory(UINT nSize)
{
// 创建共享内存块
HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nSize, "StarLeeSharedMemory");
// 创建错误
if ((hFileMapping == NULL) || (hFileMapping == INVALID_HANDLE_VALUE))
return LX_INVALID_SHAREDMEMORY;
// 共享内存已经存在
if (GetLastError() == ERROR_ALREADY_EXISTS)
return LX_SHAREDMEMORY_EXISTS;
// 创建另外一块内存存放共享内存的大小
HANDLE hSize = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, sizeof(UINT), "StarLeeSharedMemorySize");
if ((hSize == NULL) || (hSize == INVALID_HANDLE_VALUE) || (GetLastError() == ERROR_ALREADY_EXISTS))
return LX_INVALID_SHAREDMEMORY;
// 得到存放共享内存大小的指针
UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_WRITE, 0, 0, sizeof(UINT));
if (pSize == NULL)
return LX_INVALID_SHAREDMEMORY;
// 写入共享内存的大小
memcpy(pSize, &nSize, sizeof(UINT));
UnmapViewOfFile(pSize);
return LX_OK;
}
LX_RETURN_VALUE ReleaseSharedMemory()
{
g_mMutex.Lock();
// 打开共享内存
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "StarLeeSharedMemory");
// 关闭共享内存
if (hFileMapping != NULL)
CloseHandle(hFileMapping);
// 打开存放共享内存大小的文件映射
HANDLE hSize = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "StarLeeSharedMemorySize");
// 关闭存放共享内存大小的文件映射
if (hSize != NULL)
CloseHandle(hSize);
g_mMutex.Unlock();
return LX_OK;
}
LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize)
{
g_mMutex.Lock();
HANDLE hSize = OpenFileMapping(FILE_MAP_READ, FALSE, "StarLeeSharedMemorySize");
if (hSize == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_READ, 0, 0, sizeof(UINT));
if (pSize == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
// 得到共享内存的大小
memcpy(&nSize, pSize, sizeof(UINT));
g_mMutex.Unlock();
return LX_OK;
}
LX_RETURN_VALUE WriteToSharedMemory(void *pDate, UINT nSize)
{
g_mMutex.Lock();
UINT nSharedMemorySize = 0;
// 得到共享内存的大小
if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)
return LX_INVALID_SHAREDMEMORY;
// 检查共享内存的大小
if (nSize > nSharedMemorySize)
return LX_INVALID_SIZE;
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_WRITE, FALSE, "StarLeeSharedMemory");
if (hFileMapping == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, nSize);
if (pMapView == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
// 将数据写入共享内存
memcpy(pMapView, pDate, nSize);
UnmapViewOfFile(pMapView);
g_mMutex.Unlock();
return LX_OK;
}
LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize)
{
g_mMutex.Lock();
UINT nSharedMemorySize = 0;
if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)
return LX_INVALID_SHAREDMEMORY;
if (nSize > nSharedMemorySize)
return LX_INVALID_SIZE;
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ, FALSE, "StarLeeSharedMemory");
if (hFileMapping == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, nSize);
if (pMapView == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
// 从共享内存读取数据
memcpy(pData, pMapView, nSize);
UnmapViewOfFile(pMapView);
g_mMutex.Unlock();
return LX_OK;
}
CMutex g_mMutex(FALSE, "StarLeeMutex");
LX_RETURN_VALUE CreateSharedMemory(UINT nSize)
{
// 创建共享内存块
HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nSize, "StarLeeSharedMemory");
// 创建错误
if ((hFileMapping == NULL) || (hFileMapping == INVALID_HANDLE_VALUE))
return LX_INVALID_SHAREDMEMORY;
// 共享内存已经存在
if (GetLastError() == ERROR_ALREADY_EXISTS)
return LX_SHAREDMEMORY_EXISTS;
// 创建另外一块内存存放共享内存的大小
HANDLE hSize = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, sizeof(UINT), "StarLeeSharedMemorySize");
if ((hSize == NULL) || (hSize == INVALID_HANDLE_VALUE) || (GetLastError() == ERROR_ALREADY_EXISTS))
return LX_INVALID_SHAREDMEMORY;
// 得到存放共享内存大小的指针
UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_WRITE, 0, 0, sizeof(UINT));
if (pSize == NULL)
return LX_INVALID_SHAREDMEMORY;
// 写入共享内存的大小
memcpy(pSize, &nSize, sizeof(UINT));
UnmapViewOfFile(pSize);
return LX_OK;
}
LX_RETURN_VALUE ReleaseSharedMemory()
{
g_mMutex.Lock();
// 打开共享内存
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "StarLeeSharedMemory");
// 关闭共享内存
if (hFileMapping != NULL)
CloseHandle(hFileMapping);
// 打开存放共享内存大小的文件映射
HANDLE hSize = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "StarLeeSharedMemorySize");
// 关闭存放共享内存大小的文件映射
if (hSize != NULL)
CloseHandle(hSize);
g_mMutex.Unlock();
return LX_OK;
}
LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize)
{
g_mMutex.Lock();
HANDLE hSize = OpenFileMapping(FILE_MAP_READ, FALSE, "StarLeeSharedMemorySize");
if (hSize == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_READ, 0, 0, sizeof(UINT));
if (pSize == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
// 得到共享内存的大小
memcpy(&nSize, pSize, sizeof(UINT));
g_mMutex.Unlock();
return LX_OK;
}
LX_RETURN_VALUE WriteToSharedMemory(void *pDate, UINT nSize)
{
g_mMutex.Lock();
UINT nSharedMemorySize = 0;
// 得到共享内存的大小
if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)
return LX_INVALID_SHAREDMEMORY;
// 检查共享内存的大小
if (nSize > nSharedMemorySize)
return LX_INVALID_SIZE;
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_WRITE, FALSE, "StarLeeSharedMemory");
if (hFileMapping == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, nSize);
if (pMapView == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
// 将数据写入共享内存
memcpy(pMapView, pDate, nSize);
UnmapViewOfFile(pMapView);
g_mMutex.Unlock();
return LX_OK;
}
LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize)
{
g_mMutex.Lock();
UINT nSharedMemorySize = 0;
if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)
return LX_INVALID_SHAREDMEMORY;
if (nSize > nSharedMemorySize)
return LX_INVALID_SIZE;
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ, FALSE, "StarLeeSharedMemory");
if (hFileMapping == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, nSize);
if (pMapView == NULL)
{
g_mMutex.Unlock();
return LX_INVALID_SHAREDMEMORY;
}
// 从共享内存读取数据
memcpy(pData, pMapView, nSize);
UnmapViewOfFile(pMapView);
g_mMutex.Unlock();
return LX_OK;
}
用到的主要接口有:
The CreateFileMapping function creates or opens a named or unnamed file mapping object for the specified file.
HANDLE CreateFileMapping(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCTSTR lpName
);
The MapViewOfFile function maps a view of a file into the address space of the calling process.
To specify a suggested base address, use the MapViewOfFileEx function.
LPVOID MapViewOfFile( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap );The OpenFileMapping function opens a named file mapping object.
HANDLE OpenFileMapping(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName
);
- 用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享
- C++应用:用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享[转]
- 用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享
- 内存映射文件(File Mapping)API
- 内存映射文件(Memory Mapping File)
- 内存映射文件File Mapping
- 【IPC进程间通讯之三】内存映射文件Mapping File
- 内存映射文件进程间共享内存
- 内存映射文件进程间共享内存
- 通过内存映射文件实现进程间数据共享
- 进程间通讯(五)--共享内存(文件映射)
- 【VS开发】内存映射文件进程间共享内存
- 进程间通信:使用file-mapping kernel object(文件映射内核对象)
- 奉献
- 至“善者”或“伪善者”们
- Microsoft .NET Framework 英文教材系列 下载(WROX,微软出版社)
- Redhat9.2(VM)中安装JBOSS4.2
- 简单在单机使用apache-james(开源邮件服务器)
- 用文件映射(File Mapping)实现进程间内存共享
- 写在六月头几天~
- 两个或多个进程之间通过Win32 API实现内存共享的方法(转)
- xp本地策略
- java中字符处理问题
- Eclipse3.2删空configuration文件夹后启动报错的解决
- 共享内存在java中的实现
- jdbc连sql server数据库步骤及有一项操作已被挂起,需重新启动计算机解决办法
- 中文计算机核心期刊目录