|
发表于 2017-5-27 06:38:23
|
显示全部楼层
本帖最后由 Gorgon_Meducer 于 2017-5-27 06:45 编辑
思考这个问题,主要还要从你自己对消息的理解,以及你所掌握的消息处理技术入手。
先举个简单的例子:
- void xxxxx_message_handler(uint8_t *pchStream, uint_fast16_t hwSize)
- {
- ...
- }
复制代码
在你眼里,这个由指针传入的数据流可否是一个消息呢?还是说仅仅只是一个字节数组?
也许它可以被“解释”为一个结构体?
- typedef struct {
- uint8_t chCMD;
- uint8_t chDevice;
- uint16_t hwSerialNo.
- ...
- } item_t;
- void xxxxx_message_handler(uint8_t *pchStream, uint_fast16_t hwSize)
- {
- item_t __packed * ptItem = (item_t __packed *)pchStream;
- ...
- }
复制代码
也许我们可以对一个消息有完全不同的理解——所以我们需要对消息的类型进行区别?
- typedef struct {
- enum {
- // message types
- MSG_TYPE_STRING = 0,
- MSG_TYPE_STREAM,
- ...
- } tMSGType;
- } msg_base_t;
- typedef struct {
- msg_base_t;
- uint8_t *pchStream;
- uint_fast16_t hwSize;
- } msg_stream_t;
- typedef struct {
- msg_base_t;
- char *pchString;
- } msg_string_t;
- ...
复制代码
也许,我们需要唯一的识别一个Message,所以我们需要增加一个ID?
- typedef struct {
- uint32_t wID;
- enum {
- // message types
- MSG_TYPE_STRING = 0,
- MSG_TYPE_STREAM,
- ...
- } tMSGType;
- } msg_base_t;
复制代码
也许,我们区分消息类型的目的就是为了让不同的消息由不同的消息处理函数专门处理?
- extern bool stream_msg_frontend(uint8_t *pchStream, uint_fast16_t hwSize);
- extern bool string_msg_frontend(char *pchString);
- bool message_dispacher(msg_base_t *ptMessage)
- {
- ...
- switch (ptMessage->tMSGType) {
- case MSG_TYPE_STRING:
- return string_msg_frontend( ((msg_string_t *) ptMessage) -> pchString );
- case MSG_TYPE_STREAM:
- {
- stream_msg_t *ptMSG = (stream_msg_t *)ptMessage;
-
- return stream_msg_frontend(ptMSG->pchStream, ptMSG->hwSize);
- }
- ...
- }
- ...
- return true;
- }
复制代码
也许?也许还有别的需求?总的来说,就是要根据自己对应用需求的理解,适当的加入确实
必要的要素,不要过分追求通用性,而要切实追求实用性。不要把消息处理当成万能解药,
虽然它好用,但要避免不必要的“花拳绣腿”。
其它常见的消息要素可能但不限于:
消息的发送者标识,消息的接收者标识,消息的优先级,消息发送者用于处理消息接收者快速
回复的处理函数,消息接收者的消息处理函数……消息的存活时间……
总之非常多啦,并非每个都是必要的……通常根据你自己的理解选择就好。
当然,有一个经验值得分享:先能做的复杂了,才会懂得如何做的简单。
加油,做出适合你具体应用的消息系统吧。所谓消息队列……就是给这个结构体做个队列而已。 |
|