转载请保留链接,谢谢。
http://blog.youkuaiyun.com/bbw2008/archive/2010/12/20/6087738.aspx
在wince bsp开发中,我们一般会用3个函数来实现打印:DEBUGMSG,RETAILMSG,NKDbgPrintfW。
(1)NKDbgPrintfW(..)函数一般只在OAL中使用,可以直接从串口中打印出信息,不受编译选项的影响。
(2)DEBUGMSG(..)函数只有在工程在Debug模式下编译以后,才会打印出信息来。如果是在Release模式下编译的,就不会打印信息出 来。
(3)RETAILMSG(..)函数在Debug模式下和Release模式下编译都会打印出调试信息,但是如果你在工程的属性中的"Build option"中选择了"Enable ship build",那么RETAILMSG函数就不会打印信息了。
现在我们来分析一下,他们之间的调用关系(宏替换关系)
D:/WINCE600/PUBLIC/COMMON/SDK/INC/dbgapi.h 中,DEBUGMSG,RETAILMSG的实现。
。。。。。。。
#define DEBUGMSG(cond,printf_exp) /
((void)((cond)?(NKDbgPrintfW printf_exp),1:0))
。。。。。。。。。
。。。。。。。。。。
#define RETAILMSG(cond,printf_exp) /
((cond)?(NKDbgPrintfW printf_exp),1:0)
。。。。。。。。。
从摘抄的代码中可以看出,DEBUGMSG,RETAILMSG的实现在,是以条件编译的方式用宏替换NKDbgPrintfW来实现,具体请参考该dbgapi.h的文件。
也许你在这里就会疑问,那NKDbgPrintfW又是怎么来实现呢?
其实NKDbgPrintfW的具体实现是在wince的PRIVATE里,他是由微软直接在kernel里实现的。
在D:/WINCE600/PRIVATE/WINCEOS/COREOS/NK/KERNEL/printf.c
void WINAPIV
NKDbgPrintfW(
LPCWSTR lpszFmt,
...
)
{
va_list arglist;
va_start(arglist, lpszFmt);
NKvDbgPrintfW(lpszFmt, arglist);
va_end(arglist);
}
//这里主要实现了函数的可变参数
调用关系:
NKDbgPrintfW()
|
NKvDbgPrintfW()
|
|
NKvDbgPrintfWOnStack (lpszFmt, lpParms);
或者调用_NKvDbgPrintfW(lpszFmt, lpParms);
|
OutputDebugStringW()
|
OEMWriteDebugString () //oal层的debug.c里来实现
或者又g_pNKGlobal->pfnWriteDebugString ();//g_pNKGlobal全局结构体里,包括了oal层实现的很多函数指针
|
结束