• WINCE下进程间通信(二)


    WINCE下进程间通信(二)

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

     三、管道(消息队列)

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

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

           头文件(CMsgQueue.h)

    1. /******************************************************************* 
    2.  filename: CMsgQueue.h 
    3.  purpose:   封装了WINCE下消息队列操作类 
    4.  author:    firehood 
    5.  created:   2011.03.23 
    6. ********************************************************************/  
    7. #ifndef _MSG_QUEUE_H   
    8. #define _MSG_QUEUE_H   
    9.   
    10. // 消息队列访问模式   
    11. enum ACCESSMODE  
    12. {  
    13.     ReadMode = 0,  
    14.     WriteMode  
    15. };  
    16.   
    17. // 定义消息回调函数   
    18. typedef BOOL (CALLBACK *MsgQueueCallBack)(PVOID pData, DWORD dwSize);  
    19.   
    20. class CMsgQueue  
    21. {  
    22. public:  
    23.     CMsgQueue();  
    24.     CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);  
    25.     ~CMsgQueue();  
    26. public:  
    27.     /********************************************************************** 
    28.     函数名:Create 
    29.     功能:  创建或打开消息队列   
    30.     参数: 
    31.             [in]lpQueueName:    消息队列名称 
    32.             [in]dwSize:         每条消息的最大长度 
    33.             [in]accessMode      消息队列访问模式 ReadMode:只读  WriteMode:只写 
    34.     返回值: 
    35.             成功:TRUE  失败:FALSE 
    36.     **********************************************************************/  
    37.     BOOL Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);  
    38.   
    39.     /********************************************************************** 
    40.     函数名:Read 
    41.     功能:  从消息队列中读取一条消息 
    42.     参数: 
    43.             [out]lpBuffer:            存放读取的数据 
    44.             [in] dwSize:              读取数据的大小 
    45.             [out]lpNumberOfBytesRead  实际读取数据的大小 
    46.             [in] dwTimeout            读取超时时间(ms) 0 立即返回  INFINITE 永远等待直至消息队列中有数据 
    47.     返回值: 
    48.             成功:TRUE  失败:FALSE 
    49.     ***********************************************************************/  
    50.     BOOL Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout = 0);  
    51.   
    52.     /********************************************************************** 
    53.     函数名:Write 
    54.     功能:  向消息队列中写入一条消息    
    55.     参数: 
    56.             [in]lpBuffer:      待写入的数据 
    57.             [in]dwSize:        写入数据的大小 
    58.     返回值: 
    59.             成功:TRUE  失败:FALSE 
    60.     **********************************************************************/  
    61.     BOOL Write(LPVOID lpBuffer,DWORD dwSize);  
    62.   
    63.     // 设置消息回调函数   
    64.     BOOL SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam);  
    65.     // 关闭消息队列   
    66.     void Close(void);  
    67. private:  
    68.     // 开启读取消息线程   
    69.     BOOL StartRevMsgThread(void);  
    70.     // 停止读取消息线程   
    71.     BOOL StopRevMsgThread(void);  
    72.     // 读取消息线程   
    73.     static void WINAPI RevMsgThread(LPVOID pParam);  
    74. private:  
    75.     HANDLE m_hMsgQueue;  
    76.     DWORD m_dwQueueSize;  
    77.     MsgQueueCallBack m_MsgCallBack;  
    78.     HANDLE m_hRevMsgThread;  
    79.     BOOL m_bThreadExit;  
    80. };  
    81. #endif  

     源文件(CMsgQueue.cpp)

    1. #include "stdafx.h"   
    2. #include "CMsgQueue.h"   
    3.   
    4. CMsgQueue::CMsgQueue()  
    5. {  
    6.     m_hMsgQueue = NULL;  
    7.     m_dwQueueSize = 0;  
    8.     m_hRevMsgThread = NULL;  
    9.     m_bThreadExit = FALSE;  
    10.     m_MsgCallBack = NULL;  
    11. }  
    12.   
    13. CMsgQueue::CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)  
    14. {  
    15.     Create(lpQueueName,dwSize,accessMode);  
    16. }  
    17.   
    18. CMsgQueue::~CMsgQueue()  
    19. {  
    20.     Close();  
    21. }  
    22.   
    23. BOOL CMsgQueue::Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)  
    24. {  
    25.     if(!m_hMsgQueue)  
    26.     {  
    27.         m_hRevMsgThread = NULL;  
    28.         m_bThreadExit = FALSE;  
    29.         m_MsgCallBack = NULL;  
    30.         m_dwQueueSize = dwSize;  
    31.         // 创建消息队列   
    32.         MSGQUEUEOPTIONS options;  
    33.         options.dwSize = sizeof(options);  
    34.         options.dwFlags = MSGQUEUE_NOPRECOMMIT|MSGQUEUE_ALLOW_BROKEN;  
    35.         options.dwMaxMessages = 0;  
    36.         options.cbMaxMessage = dwSize;  
    37.         options.bReadAccess = (accessMode==ReadMode) ? TRUE : FALSE;  
    38.         m_hMsgQueue =::CreateMsgQueue(lpQueueName,&options);  
    39.     }  
    40.     return TRUE;  
    41. }  
    42.   
    43. void CMsgQueue::Close(void)  
    44. {  
    45.     if(m_hMsgQueue)  
    46.     {  
    47.         ::CloseMsgQueue(m_hMsgQueue);  
    48.         m_hMsgQueue = NULL;  
    49.     }  
    50.     // 注销回调函数   
    51.     SetMsgCallBack(NULL,NULL);  
    52. }  
    53.   
    54. BOOL CMsgQueue::Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout)  
    55. {  
    56.     if(m_hMsgQueue == NULL || lpBuffer == NULL)  
    57.     {  
    58.         return FALSE;  
    59.     }  
    60.     DWORD dwFlag = 0;  
    61.     // 从消息队列头部读出数据    
    62.     if(!::ReadMsgQueue(m_hMsgQueue,lpBuffer,dwSize,lpNumberOfBytesRead,dwTimeout,&dwFlag))  
    63.     {  
    64.         return FALSE;  
    65.     }  
    66.     return TRUE;  
    67. }  
    68. BOOL CMsgQueue::Write(LPVOID lpBuffer,DWORD dwSize)  
    69. {  
    70.     if(m_hMsgQueue == NULL || lpBuffer == NULL)  
    71.     {  
    72.         return FALSE;  
    73.     }  
    74.     // 向消息队列尾部写入数据   
    75.     if(!::WriteMsgQueue(m_hMsgQueue,lpBuffer,dwSize,0,0))  
    76.     {  
    77.         return FALSE;  
    78.     }  
    79.     return TRUE;  
    80. }  
    81.   
    82. BOOL CMsgQueue::SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam)  
    83. {  
    84.     m_MsgCallBack = pCallBackFun;  
    85.     if (m_MsgCallBack)  
    86.     {  
    87.         if (m_hRevMsgThread == NULL)  
    88.         {  
    89.             // 开启读取线程   
    90.             return StartRevMsgThread();  
    91.         }  
    92.     }  
    93.     else  
    94.     {  
    95.         if (m_hRevMsgThread)  
    96.         {  
    97.             // 关闭读取线程   
    98.             return StopRevMsgThread();  
    99.         }  
    100.     }  
    101.     return TRUE;  
    102. }  
    103.   
    104. BOOL CMsgQueue::StartRevMsgThread(void)  
    105. {  
    106.     if(m_hRevMsgThread == NULL)  
    107.     {  
    108.         // 创建读取消息线程   
    109.         m_hRevMsgThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CMsgQueue::RevMsgThread, this, 0, NULL);  
    110.     }  
    111.     return (m_hRevMsgThread ? TRUE : FALSE);  
    112. }  
    113.   
    114. BOOL CMsgQueue::StopRevMsgThread(void)  
    115. {  
    116.     if(m_hRevMsgThread)  
    117.     {  
    118.         m_bThreadExit = TRUE;  
    119.         // 等待线程成功退出   
    120.         WaitForSingleObject(m_hRevMsgThread,INFINITE);  
    121.         CloseHandle(m_hRevMsgThread);  
    122.         m_hRevMsgThread = NULL;  
    123.         m_hRevMsgThread = FALSE;  
    124.     }  
    125.     return ((m_hRevMsgThread==NULL) ? TRUE : FALSE);  
    126. }  
    127.   
    128. void WINAPI CMsgQueue::RevMsgThread(LPVOID pParam)  
    129. {  
    130.      CMsgQueue *pMsgQueue=(CMsgQueue*)pParam;  
    131.      LPVOID lpBuffer;  
    132.      DWORD dwReadNums=0;  
    133.      lpBuffer=(LPVOID)malloc(pMsgQueue->m_dwQueueSize);  
    134.      while(!pMsgQueue->m_bThreadExit)  
    135.      {  
    136.          if(!pMsgQueue->m_hMsgQueue )  
    137.              break;  
    138.          // 从消息队列中读取一条消息(阻塞模式)   
    139.          BOOL ret=pMsgQueue->Read(lpBuffer,pMsgQueue->m_dwQueueSize,&dwReadNums,INFINITE);  
    140.          printf("Read ret=%d,dwReadNums=%d/n",ret,dwReadNums);  
    141.          if(dwReadNums>0)  
    142.          {  
    143.              // 调用回调函数   
    144.              if(pMsgQueue->m_MsgCallBack)  
    145.                  pMsgQueue->m_MsgCallBack(lpBuffer,dwReadNums);  
    146.          }  
    147.      }  
    148.      printf("RevMsgThread exit.../n");  
    149.      free(lpBuffer);  
    150. }  

     使用CMsgQueue类实现进程间通信:

    1. // 发送进程   
    2. //////////////////////////////////////////////////////////////////////////////////   
    3. // 创建只写消息队列   
    4. CMsgQueue cMsgQueue(L"MsgQueueTest",1024,WriteMode);  
    5. // 往消息队列写数据   
    6. cMsgQueue.Write(L"Hello Word!",22);  
    7. cMsgQueue.Close();  
    8. //////////////////////////////////////////////////////////////////////////////////   
    9.   
    10. // 接收进程   
    11. //////////////////////////////////////////////////////////////////////////////////   
    12. // 声明消息回调函数   
    13. BOOL CALLBACK RecvMsgProc(PVOID pData, DWORD dwSize);  
    14.   
    15. // 创建只读消息队列   
    16. CMsgQueue cMsgQueue(L"MsgQueueTest",1024,ReadMode);  
    17. // 设置消息回调函数   
    18. cMsgQueue.SetMsgCallBack(RecvMsgProc,NULL);  
    19.   
    20. // 处理消息   
    21. BOOL CALLBACK RecvMsgProc(PVOID pData, DWORD dwSize)  
    22. {  
    23.     printf("RecvMsgProc:Rev data Size=%d/n",dwSize);  
    24.     wchar_t data[256];  
    25.     memcpy(data, pData,dwSize);  
    26.     return TRUE;  
    27. }  
    28. //////////////////////////////////////////////////////////////////////////////////  
  • 相关阅读:
    Mysql数据库快速备份还原-mysqldump
    写给年轻人的交友和人脉建议
    令人担忧的趋势:科技崇拜与人文失落
    高情商的特征
    高情商与朋友圈
    数据库临时表空间设置
    oracle 临时表空间的增删改查
    语言表达能力写作能力决定一个人的发展和未来
    一个人如何从平庸到优秀,再到卓越?
    06.堆排序
  • 原文地址:https://www.cnblogs.com/qingchen1984/p/4500521.html
Copyright © 2020-2023  润新知