捣鼓retailmsg那点事儿
最近翻看以前的老代码,想起了当年跟 `retailmsg` 较劲的日子。那时候搞嵌入式开发,具体点就是弄那个 WinCE 系统,板子好像是 S3C2410,老家伙了。
调试信息都用 `DEBUGMSG`,挺顺手的。但问题来了,这玩意儿好像只在 Debug 模式下管用,一编译成 Release 版本,啥信息都没了。可有时候,问题偏偏就在 Release 版下才冒出来,这就抓瞎了。
后来不知道在哪看到,说可以用 `RETAILMSG`。说是这东西 Debug 和 Release 都能打信息出来。行,那就试试呗。
用法看着也简单,`RETAILMSG(条件, 消息)`。第一个参数写 `TRUE`,就肯定打印。我就照猫画虎:
RETAILMSG(TRUE, (_T("这里出错了!")));
确实能打出来了,心里还挺高兴。
但高兴早了。
光打个固定字符串有啥用?我得看变量的值!比如哪个状态不对了,哪个指针地址是试着想像 printf 那样格式化输出:
int status = get_status();
RETAILMSG(TRUE, (_T("当前状态是:%d"), status)); // 这么写好像不行
结果打出来的东西乱七八糟,或者干脆就不对。这才发现,它那个格式化跟 `printf` 不太一样,得用 `_T()` 或者 `TEXT()` 包起来,而且格式符什么的得弄对,特别是处理字符串和数字的时候,挺绕的。
有时候想打个普通的 `char` 字符串,也不是直接扔进去就行,还得转。我记得当时为了方便,还自己封装了个函数,专门把 `char` 转成它能接受的格式,再调用 `RETAILMSG` 打印出来,类似这样:
- 先搞个缓冲区。
- 把要打印的 `char` 字符串内容复制或者转换到宽字符缓冲区里。
- 再调用 `RETAILMSG` 去打印那个宽字符缓冲区。
折腾了好半天,才算能比较顺畅地用它来打印我需要的信息了。虽然比 `DEBUGMSG` 麻烦点,但在关键时候,尤其是在 Release 环境下找问题,它还真是帮了大忙。
为啥对这个记得这么清楚?
因为那会儿接了个急活儿,客户那边等着要结果,设备老是随机性地出问题,又没法连调试器。只能靠打印信息来定位。当时压力山大,整天加班加点,就靠着 `RETAILMSG` 一点点地捞信息,才把那个藏得贼深的 bug 给揪出来。那感觉,真是又累又爽,印象太深了,忘不了。