承接上文,接下来讲讲CCLOG这个宏的一些调整。
很多时候,调试程序不能断点,或者不方便断点的时候,就只能靠LOG输出了,所以,一个方便的LOG
函数对于调试的帮助是巨大的。
什么才算方便呢?
能显示需要的内容,中文不乱码
能方便的定位输出内容的代码位置
好了,那就开始吧,CCLOG的输出支持中文,当然不是直接写中文,而是utf8格式,怎么获得呢,用字符串直接转就行了,还不会?好吧,下次专门说下吧。
这次的重头戏来了,如何方便的定位输出内容的代码位置,这个真的很重要,能根据输出反查到代码,就再也不需要设置唯一的输出字符了。
C++的编译器其实支持了很多预定义的宏:
宏 | 说明 |
---|---|
__DATE__ | 当前代码文件的编译日期。格式: Mmm dd yyyy ,生成的格式和 ‘’asctime(定义于TIME.H)‘’生成的日期格式一致 |
__FILE__ | 当前代码文件的文件名。 |
__LINE__ | 当前代码文件的行号。 |
__TIME__ | 当前代码文件的编译时间。格式: hh:mm:ss ,24 小时制 |
__STDC__ | 如果编译C代码,值为1;其他情况,值未定义(undefined) |
__func__ | 当前的函数名。新的ANSI/ISO C99 标准 |
接下来,直接上代码:
1.
#define KZLOG(format,...) cocos2d::CCLog("%s,%d:"format,__FILE__,__LINE__, ##__VA_ARGS__)
2.
#define KZERROR(format,...) cocos2d::CCLog("%s,%d:[error]"format,__FILE__,__LINE__, ##__VA_ARGS__)
然后来看下输出吧:
文件有了,行号也有了,小伙伴们再也不担心了。
然后呢?这些还不够嘛……下面的这些内容是为了那些好学的小伙伴们,其余的可以自动忽略。
好了,终于做好了windows版本,到了各处显摆的时候。什么,有bug,没事,我早加了log的,让我看下log……
呃,天啊……
于是,这时候,你就需要一个输出log的地方,它在哪里…………
命令行窗口?这个可以有,好了,不多说,直接上代码
01.
// ConsoleWinApp.cpp : implementation file
02.
//
03.
#define WIN32_LEAN_AND_MEAN
04.
#include <windows.h>
05.
#include <tchar.h>
06.
#define _CONSOLEWIN
07.
#ifdef _CONSOLEWIN
08.
//Set subsystem to console
09.
#pragma comment ( linker, "/subsystem:console" )
10.
BOOL
WINAPI ConsoleWinHandlerRoutine(
DWORD
dwCtrlType )
11.
{
12.
// Signal type
13.
switch
( dwCtrlType )
14.
{
15.
case
CTRL_C_EVENT:
16.
case
CTRL_BREAK_EVENT:
17.
case
CTRL_CLOSE_EVENT:
18.
case
CTRL_LOGOFF_EVENT:
19.
case
CTRL_SHUTDOWN_EVENT:
20.
// You can stop here gracefully:
21.
//
22.
// AfxGetMainWnd()->SendMessage( WM_CLOSE, 0, 0 );
23.
// WaitForSingleObject( AfxGetThread(), INFINITE );
24.
//
25.
ExitProcess(0);
26.
break
;
27.
}
28.
return
TRUE;
29.
}
30.
// Console main function
31.
int
_tmain(
DWORD
,
TCHAR
**,
TCHAR
** )
32.
{
33.
#define SPACECHAR _T(' ')
34.
#define DQUOTECHAR _T('\"')
35.
// Set the new handler
36.
SetConsoleCtrlHandler( ConsoleWinHandlerRoutine, TRUE );
37.
// Get command lin
38.
LPTSTR
lpszCommandLine = ::GetCommandLine();
39.
if
(lpszCommandLine == NULL)
40.
return
-1;
41.
// Skip past program name (first token in command line).
42.
// Check for and handle quoted program name.
43.
if
(*lpszCommandLine == DQUOTECHAR)
44.
{
45.
// Scan, and skip over, subsequent characters until
46.
// another double-quote or a null is encountered.
47.
do
48.
{
49.
lpszCommandLine = ::CharNext(lpszCommandLine);
50.
}
51.
while
((*lpszCommandLine != DQUOTECHAR) && (*lpszCommandLine != _T(
'\0'
)));
52.
// If we stopped on a double-quote (usual case), skip over it.
53.
if
(*lpszCommandLine == DQUOTECHAR)
54.
lpszCommandLine = ::CharNext(lpszCommandLine);
55.
}
56.
else
57.
{
58.
while
(*lpszCommandLine > SPACECHAR)
59.
lpszCommandLine = ::CharNext(lpszCommandLine);
60.
}
61.
// Skip past any white space preceeding the second token.
62.
while
(*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
63.
lpszCommandLine = ::CharNext(lpszCommandLine);
64.
STARTUPINFO StartupInfo;
65.
StartupInfo.dwFlags = 0;
66.
::GetStartupInfo(&StartupInfo);
67.
return
_tWinMain(::GetModuleHandle(NULL), NULL, lpszCommandLine,
68.
SW_SHOW
/*(StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ?
69.
StartupInfo.wShowWindow : SW_HIDE*/
);
70.
}
71.
#endif // _CONSOLEWIN
用法其实很简单,把这个文件编译进工程,然后就见证奇迹吧……
再然后呢?这些还不够嘛……不够吗?好吧,下面的这些内容是为了更加好学的小伙伴们,其余的可以自动忽略。
好了,再编译个手机版,然后再去显摆下……
什么,有bug,没事,我早加了log的,让我看下log……
呃,天啊……
好了,不是调试的话,怎么查看log呢?好吧,我们写下来吧。
01.
void
kzlib::CUtility::Log(
const
char
* szMsg)
02.
{
03.
#if (COCOS2DX_VER==1)
04.
kz_string strFile(cocos2d::CCFileUtils::sharedFileUtils()->getWritablePath());
05.
#else
06.
kz_string strFile(cocos2d::CCFileUtils::sharedFileUtils()->getWriteablePath());
07.
#endif
08.
strFile += m_strLogFile;
09.
FILE
*fp =
fopen
(strFile.c_str(),
"a+"
);
10.
fwrite
(szMsg,1,
strlen
(szMsg),fp);
11.
fclose
(fp);
12.
}
好了,这个怎么用,就当作业吧,大家可以好好发挥下。
那么,再接下去呢?crash report如何?不过这个就太复杂了,下次再开专门主题讨论吧。
摘自:http://www.it165.net/pro/html/201401/9019.html
这几天陆陆续续把调试篇写完了,需要能够帮到各位。有问题啥的,可以直接联系我,好了下次见。