我们知道,在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);
下面是函数的实现:
-
- 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;
- }
对于代码中能自动锁定和结锁互斥量的结构AutoMutex,可以参考我的《巧用构造函数与析构函数对数据进行设置和恢复》。
(starlee) |