MFC訊息映射機制在Linux C++編程環境下的應用)

來源:互聯網
上載者:User

#ifndef MSG_CONSTANT_H
#define MSG_CONSTANT_H

#define MAX_MSG_PARA_SIZE 2048 /*訊息參數大小*/
#define MAX_QUEUE_LENGTH  3000 /*隊列限制長度*/

#define EVENTMSG_QUIT      100 /*退出*/

#define RW_SUCCESS           0
#define EMPTY_QUE            1
#define RW_ERROR_QUE        -1
#define FULL_QUE            -2
#define LOCK_ERROR          -3
#define UNLOCK_ERROR        -4
#define REALESE_LOCK_ERROR  -5
#define UN_INI                   -6

#define PER_BUFF_LENGTH     1000 /*訊息輸入緩衝區大小(條)*/

/*!
*
* 定義訊息映射段內項目的宏 參考MFC 訊息映射機制
*/

/*訊息處理函數調用時,加上this,必須是訊息機的成員函數*/
#define MSG_MAP_FUN(MSG_CODE,MSG_ACTION_FUN)  case MSG_CODE:this->MSG_ACTION_FUN(msg);break;
            
/*實現訊息轉寄到其他訊息處理對象指標,用於某些訊息需要長時間處理的情況,接受對象必須為msg_machine的子類*/            
#define MSG_MAP_OBJ(MSG_CODE,MSG_ACTION_OBJ)  case MSG_CODE:SendMessage(msg,MSG_ACTION_OBJ);break;

/*!訊息映射宏
*
* BEGIN_MSG_MAP為定義訊息映射段開始的宏
* 訊息映射段必須出現在類體內,不是實現部分
*形式如下 
*  BEGIN_MSG_MAP
*    MSG_MAP_FUN(message code ,member function that must return void and have a Msg type parameter)
*   MSG_MAP_OBJ(message code ,message machine class instance)
*  END_MSG_MAP
*/            

#define BEGIN_MSG_MAP   virtual void Dispatch(struct Msg msg) \
               {                                      \
                                                \
                unsigned int msg_code;                  \
                msg_code=msg.msg_code;                  \
                switch(msg_code)                      \
                {
            

/*!
*
* 定義訊息映射段結束的宏
*/            
#define END_MSG_MAP(base) default:         \
            base::Dispatch(msg);        \
            break;     \
            }\
     }

#endif

  1. #ifndef MESSAGE_STRUCT_H
  2. #define MESSAGE_STRUCT_H
  3. #ifdef _cplusplus
  4. extern "C"
  5. {
  6. #include <pthread.h>
  7. #include <semaphore.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. }
  13. #endif //_cplusplus
  14. #include "msg_macro.h"
  15. typedef unsigned char u_char;
  16. struct Msg
  17. {
  18. unsigned int msg_code;     // Message Code
  19. u_char   msg_para[MAX_MSG_PARA_SIZE]; // Message Parameter
  20. };
  21. class Msg_queue
  22. {
  23. public:
  24. Msg_queue(){ initialized=false; };
  25. ~Msg_queue();
  26. int Initialize();
  27. int GetHead(struct Msg *p_msg);
  28. int AddTail(struct Msg *p_msg);
  29. private:
  30. pthread_mutex_t mutex_wr;
  31. bool initialized; 
  32.     int msg_count;
  33. int head;
  34.     int tail; 
  35. struct Msg   msg_array[MAX_QUEUE_LENGTH];
  36. };
  37. #endif // MESSAGE_STRUCT_H

複製代碼

  1. #include "msg.h"
  2. extern "C"
  3. {
  4. #include <error.h>
  5. #include <errno.h>
  6. }
  7. int  Msg_queue::Initialize()
  8. {
  9. int error;
  10. if(initialized)return 0;
  11. error=pthread_mutex_init(&mutex_wr,NULL);
  12. switch(error){
  13.   case EAGAIN: initialized=false; return -1;
  14.   case ENOMEM: initialized=false; return -2;
  15.   case EPERM:  initialized=false;  return -3;
  16. }
  17.   initialized=true;
  18. msg_count=0;
  19. head=0;
  20. tail=0;
  21. memset(msg_array,0,sizeof(msg_array));
  22. return 0;    
  23. }
  24. int  Msg_queue::GetHead(struct Msg *p_msg)
  25. {
  26. int result;
  27. int error;
  28. if(!initialized)return UN_INI;
  29. if(p_msg==NULL) return RW_ERROR_QUE;
  30. if(error=pthread_mutex_lock(&mutex_wr))
  31. return -3;//取鎖失敗
  32. if(msg_count>0)
  33. {
  34.   memcpy((void*)p_msg,(void*)&msg_array[head],sizeof(struct Msg));
  35.   memset((void*)&msg_array[head],0,sizeof(struct Msg));
  36.   head++;
  37.   if(head==MAX_QUEUE_LENGTH)head=0;
  38.   msg_count--;
  39.   result= RW_SUCCESS;
  40. }
  41. else
  42. {
  43.   p_msg->msg_code=EMPTY_QUE;
  44.   result=EMPTY_QUE; 
  45. }
  46. if(error=pthread_mutex_unlock(&mutex_wr))
  47. return -4;//解鎖失敗
  48. return result;
  49. }
  50. int Msg_queue::AddTail(struct Msg *p_msg)
  51. {
  52. int ilock;
  53. int result;
  54. int error;
  55. if(p_msg==NULL)return RW_ERROR_QUE;
  56. if(!initialized)return UN_INI;
  57. if(error=pthread_mutex_lock(&mutex_wr))
  58. return -3;
  59. if(msg_count<MAX_QUEUE_LENGTH)
  60. {
  61.   memcpy((void*)&msg_array[tail],(void*)p_msg,sizeof(struct Msg));
  62.   tail++;
  63.   if(tail==MAX_QUEUE_LENGTH)
  64.   tail=0;
  65.   msg_count++;
  66.   result=RW_SUCCESS;
  67. }
  68. else
  69. result=FULL_QUE;
  70. if(error=pthread_mutex_unlock(&mutex_wr))
  71. result=-4;
  72. return result;
  73. }
  74. Msg_queue::~Msg_queue()
  75. {
  76.   pthread_mutex_destroy(&mutex_wr);   
  77. }

複製代碼

  1. #ifndef  MSGMACHINE_H
  2. #define  MSGMACHINE_H
  3. #include "msg.h"
  4. #include "msg_macro.h"
  5. #include "msg_input_buf.h"
  6. #ifdef _cplusplus
  7. extern "C"
  8. {
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include <signal.h>
  14. #include <unistd.h>
  15. }
  16. #endif //_cplusplus
  17. //----------------------------------------------------------------------------- 
  18.         
  19. class MsgMachine
  20. {
  21. public:
  22. bool cmd_run;
  23. MsgMachine();
  24. virtual ~MsgMachine(); 
  25. void Msg_Deal_Loop();
  26. /*從各一緩衝區讀訊息到訊息佇列,非同步檢查某個緩衝區是否可讀*/
  27. int ReadInputBuf(InputBuff *pbuff) ;
  28. /*!
  29. *啟動訊息迴圈處理線程
  30. *字類如果改寫Execute,必須調用父類的Execute才能啟動訊息處理迴圈
  31. */
  32. virtual void Dispatch(struct Msg msg)
  33. {
  34.   unsigned int msg_code;      
  35.       msg_code=msg.msg_code;      
  36.          switch(msg_code)       
  37.          {
  38.       default:break;  
  39.          } 
  40. private: 
  41. bool DetectorActive;
  42. Msg_queue *pMsg_que;
  43.   
  44. };               
  45.                
  46. #endif // MSGMACHINE_H

複製代碼

  1. #include "msg_machine.h"
  2. MsgMachine::~MsgMachine()
  3. {
  4. delete pMsg_que;
  5. }
  6. MsgMachine::MsgMachine()
  7. {
  8. pMsg_que=new Msg_queue;
  9. if(pMsg_que->Initialize()==-1) 
  10. {
  11.   delete pMsg_que;
  12.   //printf("Initialize message queue error!\n");
  13.   //u_log("Initialize message queue error!\n");
  14.   exit(-1);
  15. }
  16. DetectorActive=true; 
  17. }
  18. void MsgMachine::Msg_Deal_Loop()
  19. {
  20. struct Msg msg;
  21. while(cmd_run)
  22. {
  23.   
  24.   if(pMsg_que->GetHead(&msg)==0)
  25.   {
  26.    if(msg.msg_code==EVENTMSG_QUIT)
  27.    break;
  28.    Dispatch(msg); 
  29.   }
  30.   else 
  31.    continue;
  32. }
  33. }
  34. int MsgMachine::ReadInputBuf(InputBuff  *pbuff)
  35. {
  36.   struct Msg msg;
  37.   
  38.   if(pbuff->Read(&msg)==0)
  39.   {
  40.    if(pMsg_que->AddTail(&msg)==RW_SUCCESS)
  41.    { 
  42.     return 0;
  43.    }
  44.    else 
  45.    return -1;
  46.   }
  47.   else
  48.   {
  49.     return -1;
  50.   }
  51. }

複製代碼

以上是偶們的某個項目(Redhat Linux下C++開發實現與某Portal Server的基於UDP訊息的介面
的daemon,參考MFC的訊息映射機制,目前已經實現,上述代碼給大家參考,請多多指教

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.