很多同学都喜欢看代码,但是不喜欢调试代码。其实,在我看来,调试代码本身也是一项重要的能力。一份代码,如果没有经过反复调试和验证,很难说自己是不是理解得够深刻。同样对于win32也是这样,win32的api本来就多,如果不经过反复学习、练习、测试,要真正融会贯通地理解是很难的。所以,今天就说一下,win32上面怎么调试。
1、合理使用vc自带的调试软件
vc工具本身其实自带了调试工具。常用的调试方法,比如设置断点、函数堆栈、变量、线程查看、数据断点、修改内存等等,这些方法都要熟练掌握。win32在调试的时候,app在遇到断点的情况下也会自动hang住的,这时候正常单步调试就可以了,只是原来的界面就没有办法访问了,这个关系都不大。这或许就是一般程序和win32程序最大的区别了。
2、使用windbg
在我看来,windbg是一款非常棒的软件。它不仅提供了vc调试软件的基本功能,而且还提供了命令交互的方法,这点和gdb比较类似。windbg界面比较清新、简洁,是一款不错的调试利器。当然,如果exe程序本身就是debug模式生成的,它还能自动定义到源码,这对于我们来说,使用就十分方便了。
3、安装、使用msdn
如果是一般的c、c++程序开发,找一本c语言的书大概就可以用了。但是win32开发,大部分都是win32专有的api,这个时候没有msdn是万万不行的。msdn上面的英文不复杂,多多训练都是可以掌握的。甚至于msdn上面有很多的demo code,看懂了直接拿过来用问题都不大。
4、利用MS_PAINT信息打印
普通程序开发一般用printf打印,其实win32开发的时候也可以用WM_PAINT打印。首先,我们将需要打印的内容用_snprintf的方法变成字符串,接着调用InvalidateRect函数打印出来,这样也可以达到调试的目的。
比如,我们在前面一节提供的方法,
case WM_PAINT:
g_text += 1;
TCHAR buffer[10];
buffer[9] = '\0';
_snprintf(buffer, 10, "%d\n", g_text);
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, buffer, strlen(buffer), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
5、日志的方法
日志的方法比较原始,但是也最为有用。我们可以在程序运行的时候利用fopen创建一个日志文件,每次打印的时候直接fwrite就可以了,最后在win32 app结束之后保存就可以了,这个问题都不是很大。
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
比如,程序结束之前,都要从GetMessage这边跳出循环,这个时候fclose log文件就可以了。剩下来的事情就是分析日志的内容。