Qt4中的一个关于消息处理的BUG
王忠家 2016年8月24日
最近这段时间利用Qt的消息处理机制截获qDebug等函数的输出生成日志的工作,Qt提供的机制也很简单:
QtMsgHandler *h=qInstallMsgHandler(我自己定义的消息处理函数);
Void myMessageOut(QtMsgType type,const char *msg)
{
//做自己的事
//调用前面的实现
h(type,msg);
}
有的朋友会问,自己截获输出就好了,干嘛要调用前面的,其实这跟面向对象的函数重新实现是类似的,“成全了自己,也不要忘了别人”,因为在系统中可能有多处为了实现特定的功能而重新安装了消息处理函数。
为了方便起见,我利用全局变量在main前会自动初始化的的特点,在相关的动态链接库加载时便安装消息函数:
Static QtMsgHandler *h=qInstallMsgHandler(我自己定义的消息处理函数);
了解C++的朋友对这个应该很熟悉了,毫无疑问,在main之前Qt默认的消息处理函数已经被覆盖。事实上,Qt默认的消息处理函数是没有的也就是零蛋:
以为完事大吉了,写了简单的main.cpp一测试,发现根本不是那么回事,使用qDebug()<<”Hello World”;的输出雷打不动的是Qt的默认效果,利用qInstallMsgHandler()把安装的消息处理函数的指针拿出来一看根本与我自己写的函数指针对不上:
很显然,Qt在某处自己安装了一个消息处理函数,且这个过程在我的安装代码之后再main之前!
经测试,这个机制在linux没有问题,仅在windows才有问题,略微想想windows下乱八七糟的各种自定义类型和接口就明白了:肯定是windows下游特殊的东西,通过在Qt的代码中搜索qInstallMsgHandler,终于找到了元凶:
不晓得为啥windows下要为其单独安装一个看起来没有什么特殊处理的消息处理(或许有,但是没有表现出来,反正都要跨平台的,管它呢):
上面针对windows的消息处理也不必细研究了,问题有了定论:在Qt4的版本下,不能再main之前安装消息处理器,否则会被windows默认的处理给覆盖!
好在Qt5已经解决了这个问题,经查实,Qt5中没有类似的代码了!