WINCE下进程间通信(二)

接着前面的文章《 WINCE下进程间通信(一)》,现在介绍进程间通信的另一种方法。

 三、管道(消息队列)

       WINCE并不支持类似于PC机上匿名管道、命名管道的通信方式,但CE下提供了一种点对点消息队列的方法,其工作原理与管道非常类似:在通信的两端分别建立一个读队列和写队列,写进程往消息队列一端写入数据,读进程从消息队列另一端读取数据。

       消息队列相关的系统API主要有:CreateMsgQueue()、ReadMsgQueue()、WriteMsgQuue()和CloseMsgQueue()。为了方便消息队列的操作,封装了一个消息队列操作类,参考代码如下:

       头文件(CMsgQueue.h)

 

/*******************************************************************
 filename: CMsgQueue.h
 purpose:	封装了WINCE下消息队列操作类
 author:	firehood
 created:	2011.03.23
********************************************************************/
#ifndef _MSG_QUEUE_H
#define _MSG_QUEUE_H

// 消息队列访问模式
enum ACCESSMODE
{
	ReadMode = 0,
	WriteMode
};

// 定义消息回调函数
typedef BOOL (CALLBACK *MsgQueueCallBack)(PVOID pData, DWORD dwSize);

class CMsgQueue
{
public:
	CMsgQueue();
	CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);
	~CMsgQueue();
public:
	/**********************************************************************
	函数名:Create
	功能:  创建或打开消息队列	
	参数:
	        [in]lpQueueName:	消息队列名称
	        [in]dwSize:		    每条消息的最大长度
			[in]accessMode      消息队列访问模式 ReadMode:只读  WriteMode:只写
	返回值:
	        成功:TRUE  失败:FALSE
	**********************************************************************/
	BOOL Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);

	/**********************************************************************
	函数名:Read
	功能:  从消息队列中读取一条消息
	参数:
	        [out]lpBuffer:	          存放读取的数据
	        [in] dwSize:		      读取数据的大小
			[out]lpNumberOfBytesRead  实际读取数据的大小
			[in] dwTimeout            读取超时时间(ms) 0 立即返回  INFINITE 永远等待直至消息队列中有数据
	返回值:
	        成功:TRUE  失败:FALSE
	***********************************************************************/
	BOOL Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout = 0);

	/**********************************************************************
	函数名:Write
	功能:  向消息队列中写入一条消息	
	参数:
	        [in]lpBuffer:	   待写入的数据
	        [in]dwSize:		   写入数据的大小
	返回值:
	        成功:TRUE  失败:FALSE
	**********************************************************************/
	BOOL Write(LPVOID lpBuffer,DWORD dwSize);

	// 设置消息回调函数
	BOOL SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam);
	// 关闭消息队列
	void Close(void);
private:
    // 开启读取消息线程
	BOOL StartRevMsgThread(void);
	// 停止读取消息线程
	BOOL StopRevMsgThread(void);
	// 读取消息线程
	static void WINAPI RevMsgThread(LPVOID pParam);
private:
	HANDLE m_hMsgQueue;
	DWORD m_dwQueueSize;
	MsgQueueCallBack m_MsgCallBack;
	HANDLE m_hRevMsgThread;
	BOOL m_bThreadExit;
};
#endif


 源文件(CMsgQueue.cpp)

#include "stdafx.h"
#include "CMsgQueue.h"

CMsgQueue::CMsgQueue()
{
	m_hMsgQueue = NULL;
	m_dwQueueSize = 0;
	m_hRevMsgThread = NULL;
	m_bThreadExit = FALSE;
	m_MsgCallBack = NULL;
}

CMsgQueue::CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
{
	Create(lpQueueName,dwSize,accessMode);
}

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

BOOL CMsgQueue::Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
{
	if(!m_hMsgQueue)
	{
		m_hRevMsgThread = NULL;
		m_bThreadExit = FALSE;
		m_MsgCallBack = NULL;
		m_dwQueueSize = dwSize;
		// 创建消息队列
		MSGQUEUEOPTIONS options;
		options.dwSize = sizeof(options);
		options.dwFlags = MSGQUEUE_NOPRECOMMIT|MSGQUEUE_ALLOW_BROKEN;
		options.dwMaxMessages = 0;
		options.cbMaxMessage = dwSize;
		options.bReadAccess = (accessMode==ReadMode) ? TRUE : FALSE;
		m_hMsgQueue =::CreateMsgQueue(lpQueueName,&options);
	}
	return TRUE;
}

void CMsgQueue::Close(void)
{
	if(m_hMsgQueue)
	{
		::CloseMsgQueue(m_hMsgQueue);
		m_hMsgQueue = NULL;
	}
	// 注销回调函数
	SetMsgCallBack(NULL,NULL);
}

BOOL CMsgQueue::Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout)
{
	if(m_hMsgQueue == NULL || lpBuffer == NULL)
	{
		return FALSE;
	}
    DWORD dwFlag = 0;
	// 从消息队列头部读出数据 
	if(!::ReadMsgQueue(m_hMsgQueue,lpBuffer,dwSize,lpNumberOfBytesRead,dwTimeout,&dwFlag))
	{
		return FALSE;
	}
	return TRUE;
}
BOOL CMsgQueue::Write(LPVOID lpBuffer,DWORD dwSize)
{
	if(m_hMsgQueue == NULL || lpBuffer == NULL)
	{
		return FALSE;
	}
	// 向消息队列尾部写入数据
	if(!::WriteMsgQueue(m_hMsgQueue,lpBuffer,dwSize,0,0))
	{
		return FALSE;
	}
	return TRUE;
}

BOOL CMsgQueue::SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam)
{
	m_MsgCallBack = pCallBackFun;
	if (m_MsgCallBack)
	{
		if (m_hRevMsgThread == NULL)
		{
			// 开启读取线程
			return StartRevMsgThread();
		}
	}
	else
	{
		if (m_hRevMsgThread)
		{
			// 关闭读取线程
			return StopRevMsgThread();
		}
	}
	return TRUE;
}

BOOL CMsgQueue::StartRevMsgThread(void)
{
	if(m_hRevMsgThread == NULL)
	{
		// 创建读取消息线程
		m_hRevMsgThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CMsgQueue::RevMsgThread, this, 0, NULL);
	}
	return (m_hRevMsgThread ? TRUE : FALSE);
}

BOOL CMsgQueue::StopRevMsgThread(void)
{
	if(m_hRevMsgThread)
	{
		m_bThreadExit = TRUE;
		// 等待线程成功退出
		WaitForSingleObject(m_hRevMsgThread,INFINITE);
		CloseHandle(m_hRevMsgThread);
		m_hRevMsgThread = NULL;
		m_hRevMsgThread = FALSE;
	}
	return ((m_hRevMsgThread==NULL) ? TRUE : FALSE);
}

void WINAPI CMsgQueue::RevMsgThread(LPVOID pParam)
{
	 CMsgQueue *pMsgQueue=(CMsgQueue*)pParam;
	 LPVOID lpBuffer;
	 DWORD dwReadNums=0;
	 lpBuffer=(LPVOID)malloc(pMsgQueue->m_dwQueueSize);
	 while(!pMsgQueue->m_bThreadExit)
	 {
		 if(!pMsgQueue->m_hMsgQueue )
			 break;
		 // 从消息队列中读取一条消息(阻塞模式)
		 BOOL ret=pMsgQueue->Read(lpBuffer,pMsgQueue->m_dwQueueSize,&dwReadNums,INFINITE);
		 printf("Read ret=%d,dwReadNums=%d/n",ret,dwReadNums);
		 if(dwReadNums>0)
		 {
			 // 调用回调函数
			 if(pMsgQueue->m_MsgCallBack)
				 pMsgQueue->m_MsgCallBack(lpBuffer,dwReadNums);
		 }
	 }
	 printf("RevMsgThread exit.../n");
	 free(lpBuffer);
}


 使用CMsgQueue类实现进程间通信

// 发送进程
//
// 创建只写消息队列
CMsgQueue cMsgQueue(L"MsgQueueTest",1024,WriteMode);
// 往消息队列写数据
cMsgQueue.Write(L"Hello Word!",22);
cMsgQueue.Close();
//

// 接收进程
//
// 声明消息回调函数
BOOL CALLBACK RecvMsgProc(PVOID pData, DWORD dwSize);

// 创建只读消息队列
CMsgQueue cMsgQueue(L"MsgQueueTest",1024,ReadMode);
// 设置消息回调函数
cMsgQueue.SetMsgCallBack(RecvMsgProc,NULL);

// 处理消息
BOOL CALLBACK RecvMsgProc(PVOID pData, DWORD dwSize)
{
	printf("RecvMsgProc:Rev data Size=%d/n",dwSize);
	wchar_t data[256];
	memcpy(data, pData,dwSize);
	return TRUE;
}
//


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值