WINCE下进程间通信(二)

来源:互联网 发布:如何做淘宝客服代理 编辑:程序博客网 时间:2024/05/06 23:56
接着前面的文章《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;}//////////////////////////////////////////////////////////////////////////////////


 

原创粉丝点击