Windows Programming/錯誤處理
在Windows API函數中,一般返回值類型為如下幾種:
- VOID,即C語言的void類型,表示該函數執行期間不會出任何錯誤,這種函數比較少;
- BOOL,即C語言的int類型,返回TRUE(即1)表示函數執行期間沒有錯誤,返回FALSE(即0)表示函數執行期間出現錯誤;
- HANDLE,即C語言的void*,一般返回NULL表示函數執行有錯誤,有時也會返回一個INVALID_HANDLE_VALUE(即指向0xFFFFFFFF),何時返回什麼值文檔中都有說明;
- PVOID,即C語言的void*,返回NULL表示函數執行有錯誤;
- LONG/DWOWD,即C語言裡的long/unsigned int類型,這種類型的值比較難於處理,要嚴格按照文檔說明進行判斷,一般來說,返回0表示程序執行無誤,否則需要根據返回值作具體判斷
GetLastError函數是在程序調用Win32 API函數出現錯誤時,獲取最後一次錯誤的編號,以便進一步確定具體錯誤原因。GetLastError函數返回一個整數,表示錯誤代碼,每個代碼的含義可以在頭文件WinError.h中找到申明。
例子
編輯#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <windows.h>
#define MAX_ERROR 512
int main(int argc, char* argv[])
{
// 保存错误编号
DWORD dwError = NO_ERROR;
// 保存错误信息
TCHAR szBuffer[MAX_ERROR] = TEXT("");
// 保存文件句柄
HANDLE hFile = INVALID_HANDLE_VALUE;
// 调用C函数设置当前区域环境为中国
_tsetlocale(LC_ALL, _T("zhi"));
// 调用API打开一个文件(由于此文件不存在,所以该函数调用不成功)
hFile = CreateFile(TEXT("c:/abc.dat"),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
// 判断文件句柄是否有效,如无效,则调用GetLastError获取错误代码
if (hFile == INVALID_HANDLE_VALUE) {
dwError = GetLastError();
_tprintf(_T("错误代码为: %d。/n"), dwError);
// 根据GetLastError函数返回值判断错误原因
if (dwError == ERROR_INVALID_NAME) {
_tprintf(_T("错误代码显示错误原因为:文件名错误。/n"));
}
}
if (dwError != NO_ERROR) {
// 调用FormatMessage函数获取系统定义的错误信息
DWORD nLen = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, // 设置消息来自于系统且忽略插入词
NULL, // 设置消息源,函数可以通过这个消息源格式化错误信息,此处不使用消息源,所以设置为NULL
dwError, // 错误编号
0, // 语言信息,0表示使用系统默认语言
szBuffer, // 存放错误信息的缓冲区
MAX_ERROR, // 缓冲区长度(最大字数)
NULL // 用于格式化信息的参数,这里为NULL
);
if (nLen > 0) {
_tprintf(_T("系统提示错误信息为: %s"), szBuffer);
} else {
_tprintf(_T("无法获取错误信息。"));
}
}
system("pause");
return 0;
}
FormatMessage的用法
編輯根據一個錯誤碼返回一個錯誤訊息。
DWORD FormatMessage(
DWORD dwFlags,
LPCVOID lpSource,
DWORD dwMessageId,
DWORD dwLanguageId,
LPTSTR lpBuffer,
DWORD nSize,
va_list* Arguments
);
dwFlags:
- FORMAT_MESSAGE_ALLOCATE_BUFFER // 此函數會分配內存以包含描述字串。
- FORMAT_MESSAGE_FROM_SYSTEM, // 在系統的id映射表中尋找描述字串
- FORMAT_MESSAGE_FROM_HMODULE // 在其他資源模塊中尋找描述字串
- FORMAT_MESSAGE_FROM_STRING // 消息ID是個字串,不是個DWORD
lpSource:
- 指定了FORMAT_MESSAGE_FROM_HMODULE的話,此參數表示模塊的HANDLE
- 指定了FORMAT_MESSAGE_FROM_STRING的話,此參數表示id字串
通常為:NULL
dwMessageId: 消息ID;如果指定FORMAT_MESSAGE_FROM_STRING,將被忽略。
dwLanguageId: 消息描述所用的語言 通常為:0表示自動選擇
lpBuffer:
- 如果未指定FORMAT_MESSAGE_ALLOCATE_BUFFER,則為自己提供的緩衝區
- 否則為系統LocalAlloc分配,需要被用戶LocalFree
nSize:
- 如果未指定FORMAT_MESSAGE_ALLOCATE_BUFFER,則為自己提供的緩衝區大小
- 否則為系統LocalAlloc分配之最小緩衝區大小
Arguments: 通常不使用