WinXP环境中模仿WinCE的ASSERT表现行为的解决方案

 
//=====================================================================
//TITLE:
//    WinXP环境中模仿WinCE的ASSERT表现行为的解决方案
//AUTHOR:
//    norains
//DATE:
//    Tuesday 23- February-2010
//Environment:
//     WINDOWS CE 5.0
//     WINDOWS XP
//=====================================================================

 

    如果你开发过WinCE的程序,那么想必你对ASSERT宏的用法不陌生。简单点来说,该宏是在DEBUG版本才生效,当其表达式为FALSE时,调试器会自动停在该代码段,并且会在Output窗口输出相应的信息:

 

    如果你将ASSERT(FALSE)放到WinXP的MFC工程的话,习惯于WinCE断言的方式的你,可能就会带你进入地狱。随着"咚"的一声,映入你眼帘的是这么一个警告信息:


    刚在WinXP下编写程序的你,说不定看到这对话框,还以为自己的代码有了致命的错误呢。虽然我们可以点击"忽略"继续进行调试,但这对话框如果多来几个,我相信没几个人能忍受。

 

    如果你不使用MFC,而是直接上WIN32 API的话,结局则更为离谱,你连编译都无法通过,直接提示ASSER没有定义。

 

    查一下文档,WIN32确实没有ASSERT这玩意,但却有相应的替代,则是在该宏前加下划线,为_ASSERT。但这加下划线的也和MFC的ASSERT表现一样,会让你心跳加快:


    好了,好了,基本上我们可以确认_ASSERT和ASSERT是同一个玩意,可以不用折腾了。但如果我们想获得在WinCE下的表现方式,那是不是就没辙了呢?

 

    在讨论这个问题之前,我们先看看WinCE下关于ASSERT的定义是如何的。

 

    归根结底,WinCE下的ASSERT用到了两个函数:NKDbgPrintfW和DebugBreak。我们很容易知道,NKDbgPrintfW是输出信息到Output窗口的函数,而DebugBreak则是让调试器暂停。

 

    因为NKDbgPrintfW是WinCE特有的函数,所以我们先不管它,先看看DebugBreak。很幸运,这个函数在WinXP中也有定义。那么,我们将其放入代码里,看看其是什么表现。

 

    当代码执行到DebugBreak()时,调试器也会跳出个对话框:


    在该对话框中,如果选择Break,则会进入汇编代码的调试;如果是continue,则调试器会进入到下一语句。

 

    虽然没有WinCE的那种静默的方式,但至少比那个带红红的"X",并且还有"咚"一声巨响的ASSERT好多了吧?

 

    调试器的暂停我们算是不完美的解决了,那输出到Output窗口的信息该怎么办呢?NKDbgPrintfW可是WinCE的特权,WinXP可没有这个优待。在WinCE下,我们还能用printf输出到Output窗口,可是同样的调用,printf在WinXP下可就在Output窗口难觅踪影了。

 

    查找文档,发现在WinXP下如果想将字符串输入到Output窗口,我们可以调用OutputDebugString。看起来问题能得到解决了,但其实OutputDebugString有个很大的缺陷,因为它不支持字符串的格式化!

 

    换句话来说,如果将代码printf("Param:%d/r/n",iVal)替换为OutputDebugString("Param:%d/r/n",iVal),那么你将无法编译通过,因为OutputDebugString只支持一个形参!

 

    难道,我们就没有办法在WinXP下实现一个和WinCE类似的ASSERT宏么?

 

    没辙了,既然没有相应的格式化输出函数,那么我们自己弄一个不就行了么?

 

    初始一看,整个函数的难点有两个,一个是可变参数,另一个是字符串格式化。其实这两个难点在wvsprintf上都能迎刃而解。它可以根据将可变形参格式化为字符串,然后保存到特定缓冲去。而这缓冲区的大小,根据文档,则为1024。所以,我们可以写出输出到output窗口的函数:

 

    输出函数有了,那么我们接下来的事情是不是就简单多了?

 

    最后,属于我们自己的ASSERT宏终于横空出世了:

 

posted @ 2010-02-23 17:39  我的一天  阅读(271)  评论(0编辑  收藏  举报