WINCE下进程间通信(一)

在WINCE开发中经常需要在不同的进程之间传递、共享数据,总结了一下,WINCE下进程间通信常用的方式有:Windows消息,共享内存,socket通信,管道,全局原子,邮槽等,下面就分别对这几种方法做个小结。(当然还可以采用注册表,磁盘文件以及数据库方式,只是这几种方式的通信效率和实时性比较低,所以一般不考虑。)

一、Windows消息

        通过Windows消息,可以很方便的在进程与进程之间传递数据。对于传递像字符串这种小的数据,可以直接将字符串以消息参数wParam、lParam的方式传递给其他进程,对于大一点的数据,可以采用发送WM_COPYDATA消息,参考代码如下:

 

void SendMsg(HWND hwnd,LPVOID lpData,DWORD dwSize)
{
	// 填充COPYDATASTRUCT结构
	COPYDATASTRUCT cpd;
	cpd.cbData = dwSize;
	cpd.lpData = lpData; 
    
	// 向指定窗口发送WM_COPYDATA消息,不能用PostMessage方式发送
	::SendMessage(hwnd, WM_COPYDATA, NULL,(LPARAM)&cpd);
}

// 发送端
TCHAR *data=_T("要发送的内容");
SendMsg(::FindWindow(NULL,_T("processB")),(void*)data,_tcslen(data)*2);


 在接收端的窗口过程处理函数中添加对WM_COPYDATA消息的处理

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR data[256]={0};
	
    switch (message) 
    {
        case WM_COPYDATA:
			{
				COPYDATASTRUCT *pCopyDataStruct=(COPYDATASTRUCT *)lParam;	
				memcpy(data,pCopyDataStruct->lpData,pCopyDataStruct->cbData);
			}
			break;
        // ...
   }
   return DefWindowProc(hWnd, message, wParam, lParam);
}


需要注意的是在发送数据量较大且数据交换频繁的时候通过发送WM_COPYDATA消息是不可取的,因为当数据传输过于频繁时将有可能导致数据的丢失。

二、共享内存  

      共享内存顾名思义是在内存中创建一个公共区域,供不同的进程间的数据共享。因为是直接对内存进行读写操作,效率非常高,所以共享内存特别适用于大批量的数据传输且实时性要求比较高的场合。

      具体操作步骤如下:

      1.进程A调用CreateFileMapping创建一个内存映射文件。

      2.进程A调用MapViewOfFile获取到映射到文件的内存起始地址,调用memcpy往内存中拷贝数据。

      3.进程B调用CreateFileMapping打开进程A创建的内存映射文件。

      4.进程B调用MapViewOfFile获取到映射到文件的内存起始地址,调用memcpy从内存中读出数据。

      5.通信完后进程A,B分别调用UnmapViewOfFile,CloseHandle取消内存映射和关闭内存映射对象句柄。

      为了简化操作,这里封装了一个共享内存操作类,参考代码如下:

      头文件CShareMemory.h:

/*******************************************************************
 filename: CShareMemory.h
 purpose:	封装了共享内存操作类
 author:	firehood
 created:	2011.03.16
********************************************************************/
#ifndef _SHARE_MEMORY_H
#define _SHARE_MEMORY_H

class CShareMemory
{
public:
	CShareMemory();
	~CShareMemory();
public:
	/**********************************************************
	函数名:Open
	功能:  创建或打开内存映射文件	
	参数:
	        [in]szMapName:		要创建的共享内存名称
	        [in]dwSize:		    创建共享内存的大小
	返回值:
	        0:	    失败
            1:		创建成功
	        2:      文件已存在
	***********************************************************/
	DWORD Open(LPCTSTR szMapName,DWORD dwSize);

	/**********************************************************
	函数名:Read
	功能:  从共享内存指定位置读取数据	
	参数:
	        [out]pBuf:		    存放读取的数据
	        [in]dwSize:		    读取数据的大小
	        [in]dwOffset        距共享内存起始位置的偏移量
	返回值:
	        TRUE: 成功 FALSE:失败
	***********************************************************/
	BOOL Read(void* pBuf,DWORD dwSize,DWORD dwOffset = 0);

	/**********************************************************
	函数名:Write
	功能:  从共享内存指定位置写入数据	
	参数:
	        [in]pBuf:		    待写入的数据指针
	        [in]dwSize:		    写入数据的大小
	        [in]dwOffset        距共享内存起始位置的偏移量
	返回值:
	        TRUE: 失败 FALSE:失败
	***********************************************************/
	BOOL Write(const void* pBuf,DWORD dwSize,DWORD dwOffset = 0);
	void Close(void);
private:
	HANDLE m_hShareMemory;
	LPVOID m_pMapBuffer;
	HANDLE m_hAccessMutex;
};

#endif


源文件CShareMemory.cpp:

#include "stdafx.h"
#include "CShareMemory.h"

CShareMemory::CShareMemory()
{
	m_hShareMemory = NULL;
	m_pMapBuffer = NULL;
	m_hAccessMutex =NULL;
}

CShareMemory::~CShareMemory()
{
	Close();
}

DWORD CShareMemory::Open(LPCTSTR szMapName,DWORD dwSize)
{
	DWORD dwRet = 1;
	if(szMapName == NULL)
		return 0;

	if(m_hShareMemory)
	{
		Close();
	} 

	// 创建内存映射文件对象
	m_hShareMemory = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,dwSize,szMapName);
	if(!m_hShareMemory)
	{
		return 0;
	}
    // 内存映射文件对象已存在
	if(GetLastError() == ERROR_ALREADY_EXISTS)
	{
        dwRet = 2;
	}
	// 获取内存映射文件指针
	m_pMapBuffer = MapViewOfFile(m_hShareMemory,FILE_MAP_ALL_ACCESS,0,0,0);
	if(!m_pMapBuffer)
	{
		CloseHandle(m_hShareMemory);
		return 0;
	}

	// 创建互斥体,用于读写同步   
    TCHAR szMutexName[MAX_PATH];   
    _tcscpy(szMutexName, szMapName);      
    _tcscat(szMutexName, _T("_Mutex"));     
    m_hAccessMutex=CreateMutex(NULL, FALSE, szMutexName);   
	if(!m_hAccessMutex)
	{
		Close();
		return 0;
	}	
	return dwRet;
}

BOOL CShareMemory::Read(void* pBuf,DWORD dwSize,DWORD dwOffset)
{
	BOOL bRet;
	if(!m_pMapBuffer) return FALSE;

	if(WaitForSingleObject(m_hAccessMutex,INFINITE)==WAIT_OBJECT_0)
	{
		memcpy(pBuf,(BYTE*)m_pMapBuffer+dwOffset,dwSize);	
		bRet = TRUE;
	}
	ReleaseMutex(m_hAccessMutex);
	return bRet;
}

BOOL CShareMemory::Write(const void* pBuf,DWORD dwSize,DWORD dwOffset)
{
	BOOL bRet;
	if(!m_pMapBuffer) return FALSE;

	if(WaitForSingleObject(m_hAccessMutex,INFINITE)==WAIT_OBJECT_0)
	{
		memcpy((BYTE*)m_pMapBuffer+dwOffset,pBuf,dwSize);
		bRet = TRUE;
	}
	ReleaseMutex(m_hAccessMutex);
	return TRUE;  
}

void CShareMemory::Close(void)
{
	if(m_hShareMemory)
	{
		UnmapViewOfFile(m_pMapBuffer);
		CloseHandle(m_hShareMemory);
		m_pMapBuffer = NULL;
		m_hShareMemory = NULL;
		
	}
	if(m_hAccessMutex)
	{
		CloseHandle(m_hAccessMutex);
		m_hAccessMutex = NULL;
	}
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值