當呼叫乙個windows函式時,它首先檢驗傳遞給它的各個引數的有效性,然後再設法執行任務。如果傳遞了乙個無效引數,或者由於某種原因無法執行這項操作,那麼作業系統就會返回乙個值,指明該函式在某種程度上執行失敗了。
下面說說windows常見的返回值型別:
1)void
:表明該函式執行不可能失敗,windows函式的返回值很少是void。
2)bool
:如果函式執行失敗,返回值是0,否則返回值是非0值。最好對返回值進行測試,以確定它是0還是非0,而不是測試返回值是否是true。
3)handle
:如果函式執行失敗,則返回值通常是null,否則返回值是某個handle,用於標識你可以操作的乙個物件。f.y.i,有些函式失敗時會返回乙個控制代碼值invalid_handle_value,它被定義為-1。函式的platform sdk文件將會清楚地說明函式執行失敗時返回值是null還是invalid_handle_value。
4)pvoid
:如果函式執行失敗,返回值是null,否則返回pvoid,以標識資料塊的記憶體位址。
5)long/dword
:這是個難以處理的值。返回數量的函式通常返回long或dword,如果由於某種原因,函式無法對想要進行計數的物件進行計數,那麼該函式通常返回0或-1(根據函式而定)。如果呼叫的函式返回值為long或dword,那麼得閱讀platform sdk以確保能正確檢測潛在的錯誤。
乙個windows函式返回的錯誤**對了解函式執行失敗的原因是很有用的。microsoft編譯了乙個所有可能的錯誤**的列表,並且為每個錯誤**分配了乙個32位的號碼。若要確定這是個什麼錯誤,可以呼叫getlasterror函式:
dword getlasterror();
該函式只返回執行緒的32位錯誤**,我們需要將它轉換成更便於理解的某種東西。在winerror.h標頭檔案中包含了microsoft定義的錯誤**的列表。格式如下:
// dns_info_no_records 0x0000251d
//// messageid: dns_info_no_records
//// messagetext:
//// no records found for given dns query.
//#define
dns_info_no_records 9501l
//(0x0000251d
的十進位制值)
我們可以看到,每個錯誤有三種表示法:乙個訊息id(這是我們可以在源**中使用的乙個巨集,以便於與getlasterror的返回值進行比較)、訊息文字(對錯誤的英文描述)和乙個號碼(應該避免直接使用該號碼,而是使用訊息id)
當windows函式執行失敗時,應該立即呼叫getlasterror函式。因為如果呼叫另乙個windows函式,getlasterror的返回值很可能被改寫。
如果在編寫的應用程式中發現乙個錯誤,可能需要向使用者顯示該錯誤的文字描述。windows提供了乙個函式,可以將錯誤**轉換成它的文字描述。該函式就是formatmessage:
dword formatmessage(
__in dword dwflags,
// source and processing options
__in_opt lpcvoid lpsource,
// pointer to message source
__in dword dwmessageid,
// requested message identifier
__in dword dwlanguageid,
// language identifier for requested message
__out lptstr lpbuffer,
// pointer to message buffer
__in dword nsize,
// maximum size of message buffer
__in_opt va_list *arguments
// pointer to array of message inserts);
formatmessage
函式的功能是非常豐富的,在建立向使用者顯示的字串資訊時,它是首選函式。原因之一是它很容易用多種語言進行操作,該函式能夠檢測出使用者首選地語言,並返回相應的文字。
下面是formatmessage的例項**:
#include
#include
#include
#define
errmsgbuffersize 256
void
fndisplayerror( dword dwerrormsgid )
// hinst not null if the library was successfully loaded.
} // msmq errors only.
else
if( dwerrormsgid >= nerr_base && dwerrormsgid <= max_nerr )
// not null if successfully loaded.
} // could be a network error.
else
// display the string.
if( ret )
else
// free the buffer.
localfree( pbuffer );}
我們如何利用該機制來定義自己函式返回的錯誤**呢?若要指明函式執行失敗,只需要設定執行緒的最後的錯誤**,然後讓我們的函式返回false、invalid_handle_value、null或返回任何合適的資訊。設定執行緒的最後錯誤**只需呼叫下面**:
void setlasterror(dword dwerrcode);
可以將合適的任何32位號碼傳遞給該函式,包括winerror.h中已經存在的**,只要該**能夠正確指明想要報告的錯誤即可。我們也可以建立自己的錯誤**。錯誤**是乙個32位的數字,格式如下表:
位 31~30 29
2827~16
15~0 內容
含義 嚴重性 0=
成功 1=
供參考 2=
警告 3=錯誤
0=microsoft
定義的** 1=
客戶定義的** 保留
必須是0
裝置**
由microsoft定義
異常**
由microsoft或使用者定義
Windows核心程式設計
內容簡介 這是一本經典的windows核心程式設計指南,從第1版到第5版,引領著數十萬程式設計師走入windows開發陣營,培養了大批精英。作為windows開發人員的必備參考,本書是為打算理解windows的c和c 程式設計師精心設計的。第5版全面覆蓋windows xp,windows vist...
WINDOWS核心程式設計 核心物件
今天想把看的第三章的心得寫下來。這章主要介紹了核心物件。在windows中,核心物件是由作業系統來管理,儘管使用者能夠建立它,但是在建立之後,使用者對該核心物件的操作都是委託給作業系統。通常使用者建立和使用的物件分為 使用者物件 如 hicon createicon prama gdi物件函式以及核...
Windows核心程式設計 核心物件
每個核心物件只是核心分配的乙個記憶體塊,只能由核心訪問.該記憶體塊是一種資料結構,它的成員負責維護物件的各種資訊,由得物件型別相同,但大多數不同,比如程序物件有個程序id,乙個基本優先順序,乙個退出 檔案物件則有乙個位元組位移,乙個共享模式,乙個開啟模式 如果核心控制代碼傳遞給另外乙個程序,那麼這另...