您的位置:首页 > 移动开发

用文件映射(File Mapping)实现进程间内存共享[转]

2011-09-07 10:32 525 查看
我们知道,在Windows中的每个进程都有自己独立的内存空间。该独立的内存空间包含了所有的可执行模块或DLL模块的代码和数据以及动态内存分配的空间。每个进程的内存空间只能被该进程访问,其他进程是不能访问的。

如果我们要想在进程间共享内存(也就是创建一块不同进程都能访问的内存),那就必须使用内核对象。因为内核对象由Windows系统内核所拥有,而不是由进程所拥有。

下面就用文件映射(File Mapping)和互斥量(Mutex)两中内核对象来实现简单的进程间内存共享。文件映射(File Mapping)用来开辟共享的内存空间,而互斥量(Mutex)则是用来使读写互斥。

在该例子里,实现了下面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_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);

下面是函数的实现:

// 自动Lock和Unlock互斥量

struct CAutoMutex

{

CAutoMutex();

~CAutoMutex();

// 互斥量

static CMutex m_mutex;

};

CMutex CAutoMutex::m_mutex(FALSE, "StarLeeMutex");

CAutoMutex::CAutoMutex()

{

m_mutex.Lock();

}

CAutoMutex::~CAutoMutex()

{

m_mutex.Unlock();

}

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()

{

CAutoMutex MutexLock;

// 打开共享内存

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);

return LX_OK;

}

LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize)

{

CAutoMutex MutexLock;

HANDLE hSize = OpenFileMapping(FILE_MAP_READ, FALSE, "StarLeeSharedMemorySize");

if (hSize == NULL)

return LX_INVALID_SHAREDMEMORY;

UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_READ, 0, 0, sizeof(UINT));

if (pSize == NULL)

return LX_INVALID_SHAREDMEMORY;

// 得到共享内存的大小

memcpy(&nSize, pSize, sizeof(UINT));

return LX_OK;

}

LX_RETURN_VALUE WriteToSharedMemory(void *pDate, UINT nSize)

{

UINT nSharedMemorySize = 0;

// 得到共享内存的大小

if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)

return LX_INVALID_SHAREDMEMORY;

// 检查共享内存的大小

if (nSize > nSharedMemorySize)

return LX_INVALID_SIZE;

CAutoMutex MutexLock;

HANDLE hFileMapping = OpenFileMapping(FILE_MAP_WRITE, FALSE, "StarLeeSharedMemory");

if (hFileMapping == NULL)

return LX_INVALID_SHAREDMEMORY;

void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, nSize);

if (pMapView == NULL)

return LX_INVALID_SHAREDMEMORY;

// 清空共享内存

memset(pMapView, 0, nSharedMemorySize);

// 将数据写入共享内存

memcpy(pMapView, pDate, nSize);

UnmapViewOfFile(pMapView);

return LX_OK;

}

LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize)

{

UINT nSharedMemorySize = 0;

if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)

return LX_INVALID_SHAREDMEMORY;

if (nSize > nSharedMemorySize)

return LX_INVALID_SIZE;

CAutoMutex MutexLock;

HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ, FALSE, "StarLeeSharedMemory");

if (hFileMapping == NULL)

return LX_INVALID_SHAREDMEMORY;

void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, nSize);

if (pMapView == NULL)

return LX_INVALID_SHAREDMEMORY;

// 从共享内存读取数据

memcpy(pData, pMapView, nSize);

UnmapViewOfFile(pMapView);

return LX_OK;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: