Windows via c/c++ 之我见(二) 错误处理
您的程序都需要调用Windows API的,当然您需要知道该调用是否成功,如果失败就要取得失败的原因。对于调用是否成功的查看,一般可以通过调用的返回值查看,下面是Windows函数的一般返回值情况:
(1) VOID. 该函数不可能调用失败,只有非常少的函数返回类型是VOID
(2) BOOL. 如果失败返回值是0,否则非0。使用时您最好不要把返回值与TRUE比较,而应该判断它是否非FALSE。
(3) HANDLE. 如果失败返回值一般是NULL,否则就返回你可操作的对象HANDLE。但要注意的是,有些该类型的函数失败时返回的是INVALID_HANDLE_VALUE,这个值是定义成-1。SDK文档上有这些函数的详细说明。
(4) PVOID. 如果失败返回NULL,否则返回数据块的内存地址。
(5) LONG/DWORD. 这是最任意的一个返回,它通常用于计数返回。这样失败的就返回0或-1。所有使用这类型函数应该详细查看SDK文档。
在内部,当调用函数内检测到一个错误时,它使用TLS在当前调用线程中关联一个相应的错误码,你可以使用GetLastError函数获取。相应的错误码及其描述可以在WinError.h文件中查看,该文件有39,000行!
如果一个函数调用失败,你应该立即调用GetLastError查看错误原因。因为后面调用函数失败会覆盖前面的信息。另外如果想查看函数成功的原因(函数调用成功也有不同原因!如创建Event内核对象时,可能新建成功,有可能已存在一同名对象),也可以使用该函数(可查看SDK文档,如CreateEvent函数在同名Event对象存在时,用GetLastError就返回ERROR_ALREADY_EXISTS)。
查看错误信息在调用时也很有用,在VS中,Microsoft的调试器支持这个特征:你只要在Watch窗口输入$err,hr便可查看这些信息。另外VS也带了Error Lookup工具,它可以把错误号与错误信息匹配起来。