《Windows核心程式設計》 Windows返回值

2021-09-08 14:36:20 字數 3300 閱讀 2076

當呼叫乙個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,乙個基本優先順序,乙個退出 檔案物件則有乙個位元組位移,乙個共享模式,乙個開啟模式 如果核心控制代碼傳遞給另外乙個程序,那麼這另...