二、08年2月29日
作者:青青子衿
email:anzijin@sina.com
1、 main函数
运行时的提示:
[1/10] Agobot3 (0.2.1-pre3 Alpha) "Debug" on "Win32" starting up...
[2/10] Debugging with debuglevel of 10...
2、 CConsDbg 类
有四个成员函数分别是:其中后两个只在 DBGCONSOLE 模式下调用,无构造和析构函数
void Init ( int iDebugLevel ) ;
void DeInit ();
void Log ( int iDebugLevel , const char * logfmt , ...);
void LogErr ( int iDebugLevel , const char * logfmt , ...);
4个成员变量:前两个只在windows平台下使用
#ifdef WIN32
HANDLE m_hStdOut ;
HANDLE m_hStdErr ;
#endif
bool m_bEnabled ;
int m_iDebugLevel ;
(1) Init函数,完成初始化过程
void CConsDbg :: Init ( int iDebugLevel )
{
#ifdef WIN32 //##判断是否是Win平台
if ( g_cMainCtrl . m_cCmdLine . m_cConfig . bDebug ) //##判断状态是否是Debug模式
{
AllocConsole (); //在进程中创建一个新的控制台窗口
m_hStdOut = GetStdHandle ( STD_OUTPUT_HANDLE ); //获得标准输出窗口
m_hStdErr = GetStdHandle ( STD_ERROR_HANDLE ); //获得标准输入窗口
}
#endif
m_bEnabled = true ;
m_iDebugLevel = iDebugLevel ; //##iDebugLevel=10
}
(2) DeInit () 函数,完成对象的注销工作
void CConsDbg :: DeInit ()
{
#ifdef WIN32
if ( g_cMainCtrl . m_cCmdLine . m_cConfig . bDebug )
{
FreeConsole (); //##detaches the calling process from its console
m_hStdOut = INVALID_HANDLE_VALUE ; //##标准输出设备句柄置为无效
m_hStdErr = INVALID_HANDLE_VALUE ; //##错误输出设备句柄置为无效
}
#endif
m_bEnabled = false ; //##标识日志对象无效
}
(3) Log 将日志信息以指定格式写入输出窗口
#ifdef DBGCONSOLE
//##函数的特点是函数的参数个数可变
void CConsDbg :: Log ( int iDebugLevel , const char * logfmt , ...)
{
if (! m_bEnabled || m_iDebugLevel < iDebugLevel )
{
return ;
}
va_list va_alist ;
char logbuf [ LOGBUF_SIZE ]; //##LOGBUF_SIZE == 8192
char logbuf2 [ LOGBUF_SIZE ];
va_start ( va_alist , logfmt );
vsprintf ( logbuf2 , logfmt , va_alist ); /*##va_alist指向不确定参数中的第二个参数,即本函数的第三个参数
logfmt指向不确定参数中的第1个参数,即本函数中的第二个参数,保存了输出字符串的格式*/
va_end ( va_alist );
sprintf ( logbuf , "[%d/%d] %s" , iDebugLevel , m_iDebugLevel , logbuf2 );
#ifdef WIN32
DWORD dwWritten ;
WriteFile ( m_hStdOut , logbuf , strlen ( logbuf ), & dwWritten , NULL );
if ( m_iDebugLevel >4)
{
OutputDebugString ( logbuf );
}
#else
fprintf ( stdout , "%s" , logbuf ); //Linux版程序直接使用标准输出stdout
#endif
}
关于 va_list 的使用
使用目的:处理函数参数不确定的情况
使用方法及原理参见《 va_start va_arg va_end 的使用和原理 》
(4) LogErr 函数的原理与 Log 函数类似
3、 CCmdLine 类
三个成员函数有:
CCmdLine ();
virtual ~ CCmdLine ();
void Parse ( const char * szCmdLine );
两个成员变量
config_t m_cConfig ;
char * m_szCmdLine ;
其中主要实现功能的是 Parse 函数,主要实现的功能是将程序运行时的一系列参数进行分解,并对当 m_cConfig 变量中设置相关数值 , 前调试环境中,参数为空,该函数不起作用。
typedef struct config_s
{ bool bDebug ; //##Debug版时设为true
int iDebugLevel ; //##Debug版时设为10
bool bUpdate ; //##设置是否升级
} config_t ;
4、 CThread 类
使用了pthread封装起来的一个用来支持windows的类库,该类库封装了众多的线程操作,这方面的内容需要以后投入经历进一步学习。