程序員 必讀

? ? ?對程序錯誤的處理在開始介紹Microsoft Windows 的特性之前,必須首先了解Wi n d o w s的各個(gè)函數(shù)是如何進(jìn)行錯誤處理的。當(dāng)調(diào)用一個(gè)Wi n d o w s函數(shù)時(shí),它首先要檢驗(yàn)傳遞給它的的各個(gè)參數(shù)的有效性,然后再設(shè)法執(zhí)行任務(wù)。如果傳遞了一個(gè)無效參數(shù),或者由于某種原因無法執(zhí)行這項(xiàng)操作,那么操作系統(tǒng)就會返回一個(gè)值,指明該函數(shù)在某種程度上運(yùn)行失敗了。表 1 - 1列出了大多數(shù)Wi n d o w s函數(shù)使用的返回值的數(shù)據(jù)類型。表1-1 Wi n d o w s函數(shù)常用的返回值類型數(shù) 據(jù) 類 型 表示失敗的值V O I D 該函數(shù)的運(yùn)行不可能失敗。Wi n d o w s函數(shù)的返回值類型很少是V O I DB O O L 如果函數(shù)運(yùn)行失敗,那么返回值是0,否則返回的是非0值。最好對返回值進(jìn)行測試,以確定它是0還是非0。不要測試返回值是否為T R U EH A N D L E 如果函數(shù)運(yùn)行失敗,則返回值通常是N U L L,否則返回值為H A N D L E,用于標(biāo)識你可以操作的一個(gè)對象。注意,有些函數(shù)會返回一個(gè)句柄值I N VALID_ HANDLE_VA L U E,它被定義為- 1。函數(shù)的Platform SDK文檔將會清楚地說明該函數(shù)運(yùn)行失敗時(shí)返回的是N U L L還是I N VA L I D _ H A N D L E _ VA L I DP V O I D 如果函數(shù)運(yùn)行失敗,則返回值是N U L L,否則返回P V O I D,以標(biāo)識數(shù)據(jù)塊的內(nèi)存地址L O N G / D W O R D 這是個(gè)難以處理的值。返回?cái)?shù)量的函數(shù)通常返回 L O N G或D W O R D。如果由于某種原因,函數(shù)無法對想要進(jìn)行計(jì)數(shù)的對象進(jìn)行計(jì)數(shù),那么該函數(shù)通常返回 0或- 1(根據(jù)函數(shù)而定)。如果調(diào)用的函數(shù)返回了L O N G / D W O R D,那么請認(rèn)真閱讀Platform SDK文檔,以確保能正確檢查潛在的錯誤


一個(gè)Wi n d o w s函數(shù)返回的錯誤代碼對了解該函數(shù)為什么會運(yùn)行失敗常常很有用。 M i c r o s o f t公司編譯了一個(gè)所有可能的錯誤代碼的列表,并且為每個(gè)錯誤代碼分配了一個(gè) 3 2位的號碼。從系統(tǒng)內(nèi)部來講,當(dāng)一個(gè)Wi n d o w s函數(shù)檢測到一個(gè)錯誤時(shí),它會使用一個(gè)稱為線程本地存儲器(thread-local storage)的機(jī)制,將相應(yīng)的錯誤代碼號碼與調(diào)用的線程關(guān)聯(lián)起來(線程本地存儲器將在第2 1章中介紹)。這將使線程能夠互相獨(dú)立地運(yùn)行,而不會影響各自的錯誤代碼。當(dāng)函數(shù)返回時(shí),它的返回值就能指明一個(gè)錯誤已經(jīng)發(fā)生。若要確定這是個(gè)什么錯誤,請調(diào)用G e t L a s t E r r o r函數(shù):該函數(shù)只返回線程的3 2位錯誤代碼。當(dāng)你擁有3 2位錯誤代碼的號碼時(shí),必須將該號碼轉(zhuǎn)換成更有用的某種對象。 Wi n E r r o r. h頭文件包含了M i c r o s o f t公司定義的錯誤代碼的列表。下面顯示了該列表的某些內(nèi)容,使你能夠看到它的大概樣子:

免使用這個(gè)號碼,可使用消息I D)。請記住,這里只顯示了Wi n E r r o r. h頭文件中的很少一部分內(nèi)容,整個(gè)文件的長度超過2 1 0 0 0行。當(dāng)Wi n d o w s函數(shù)運(yùn)行失敗時(shí),應(yīng)該立即調(diào)用G e t L a s t E r r o r函數(shù)。如果調(diào)用另一個(gè)Wi n d o w s函數(shù),它的值很可能被改寫。注意 G e t L a s t E r r o r能返回線程產(chǎn)生的最后一個(gè)錯誤。如果該線程調(diào)用的Wi n d o w s函數(shù)運(yùn)行成功,那么最后一個(gè)錯誤代碼就不被改寫,并且不指明運(yùn)行成功。有少數(shù)Wi n d o w s函數(shù)并不遵循這一規(guī)則,它會更改最后的錯誤代碼;但是 Platform SDK文檔通常指明,當(dāng)函數(shù)運(yùn)行成功時(shí),該函數(shù)會更改最后的錯誤代碼。Wi n d o w s 9 8 許多Windows 98的函數(shù)實(shí)際上是用M i c r o s o f t公司的1 6位Windows 3.1產(chǎn)品產(chǎn)生的1 6位代碼來實(shí)現(xiàn)的。這種比較老的代碼并不通過 G e t L a s t E r r o r之類的函數(shù)來報(bào)告錯誤,而且M i c r o s o f t公司并沒有在Windows 98中修改1 6位代碼,以支持這種錯誤處理方式。對于我們來說,這意味著Windows 98中的許多Wi n 3 2函數(shù)在運(yùn)行失敗時(shí)不能設(shè)置最后的錯誤代碼。該函數(shù)將返回一個(gè)值,指明運(yùn)行失敗,這樣你就能夠發(fā)現(xiàn)該函數(shù)確實(shí)已經(jīng)運(yùn)行失敗,但是你無法確定運(yùn)行失敗的原因。有些Wi n d o w s函數(shù)之所以能夠成功運(yùn)行,其中有許多原因。例如,創(chuàng)建指明的事件內(nèi)核對象之所以能夠取得成功,是因?yàn)槟銓?shí)際上創(chuàng)建了該對象,或者因?yàn)橐呀?jīng)存在帶有相同名字的事件內(nèi)核對象。你應(yīng)搞清楚成功的原因。為了將該信息返回, M i c r o s o f t公司選擇使用最后錯誤代碼機(jī)制。這樣,當(dāng)某些函數(shù)運(yùn)行成功時(shí),就能夠通過調(diào)用 G e t L a d t E r r o r函數(shù)來確定其他的一些信息。對于具有這種行為特性的函數(shù)來說, Platform SDK文檔清楚地說明了G e t L a s t E r r o r函數(shù)可以這樣使用。請參見該文檔,找出C r e a t e E v e nt函數(shù)的例子。進(jìn)行調(diào)試的時(shí)候,監(jiān)控線程的最后錯誤代碼是非常有用的。在Microsoft Visual studio 6.0中,M i c r o s o f t的調(diào)試程序支持一個(gè)非常有用的特性,即可以配置 Wa t c h窗口,以便始終都能顯示線程的最后錯誤代碼的號碼和該錯誤的英文描述。通過選定 Wa t c h窗口中的一行,并鍵入“@ e r r, h r”,就能夠做到這一點(diǎn)。觀察圖1 - 1,你會看到已經(jīng)調(diào)用了C r e a t e F i l e函數(shù)。該函數(shù)返回I N VA L I D _ H A N D L E _ VA L U E(- 1)的H A N D L E,表示它未能打開指定的文件。但是Wa t c h窗口向我們顯示最后錯誤代碼(即如果調(diào)用 G e t L a s t E r r o r函數(shù),該函數(shù)返回的錯誤代碼)是0 x 0 0 0 0 0 0 0 2。該Wa t c h窗口又進(jìn)一步指明錯誤代碼2是指“系統(tǒng)不能找到指定的文件?!蹦銜l(fā)現(xiàn)它與Wi n E r r o r. h頭文件中的錯誤代碼2所指的字符串是相同的。圖1-1 在Visual Studio 6.0的Wa t c h窗口中鍵入“@ e r r, h r”,就可以查看當(dāng)前線程的最后錯誤代碼F o r m a t M e s s a g e函數(shù)的功能實(shí)際上是非常豐富的,在創(chuàng)建向用戶顯示的字符串信息時(shí),它是首選函數(shù)。該函數(shù)之所以有這樣大的作用,原因之一是它很容易用多種語言進(jìn)行操作。該函數(shù)能夠檢測出用戶首選的語言(在Regional Settings Control Panel小應(yīng)用程序中設(shè)定),并返回相應(yīng)的文本。當(dāng)然,首先必須自己轉(zhuǎn)換字符串,然后將已轉(zhuǎn)換的消息表資源嵌入你的 . e x e文件或D L L模塊中,然后該函數(shù)會選定正確的嵌入對象。 E r r o r S h o w示例應(yīng)用程序(本章后面將加以介紹)展示了如何調(diào)用該函數(shù),以便將M i c r o s o f t公司定義的錯誤代碼轉(zhuǎn)換成它的文本描述。有些人常常問我,M i c r o s o f t公司是否建立了一個(gè)主控列表,以顯示每個(gè)Wi n d o w s函數(shù)可能返回的所有錯誤代碼??上?,回答是沒有這樣的列表,而且 M i c r o s o f t公司將永遠(yuǎn)不會建立這樣的一個(gè)列表。因?yàn)樵趧?chuàng)建系統(tǒng)的新版本時(shí),建立和維護(hù)該列表實(shí)在太困難了。建立這樣一個(gè)列表存在的問題是,你可以調(diào)用一個(gè) Wi n d o w s函數(shù),但是該函數(shù)能夠在內(nèi)部調(diào)用另一個(gè)函數(shù),而這另一個(gè)函數(shù)又可以調(diào)用另一個(gè)函數(shù),如此類推。由于各種不同的原因,這些函數(shù)中的任何一個(gè)函數(shù)都可能運(yùn)行失敗。有時(shí),當(dāng)一個(gè)函數(shù)運(yùn)行失敗時(shí),較高級的函數(shù)對它進(jìn)行恢復(fù),并且仍然可以執(zhí)行你想執(zhí)行的操作。為了創(chuàng)建該主控列表, M i c r o s o f t公司必須跟蹤每個(gè)函數(shù)的運(yùn)行路徑,并建立所有可能的錯誤代碼的列表。這項(xiàng)工作很困難。而且,當(dāng)創(chuàng)建系統(tǒng)的新版本時(shí),這些函數(shù)的運(yùn)行路徑還會改變。1.1 定義自己的錯誤代碼前面已經(jīng)說明 Wi n d o w s函數(shù)是如何向函數(shù)的調(diào)用者指明發(fā)生的錯誤,你也能夠?qū)⒃摍C(jī)制用于自己的函數(shù)。比如說,你編寫了一個(gè)希望其他人調(diào)用的函數(shù),你的函數(shù)可能因?yàn)檫@樣或那樣的原因而運(yùn)行失敗,你必須向函數(shù)的調(diào)用者說明它已經(jīng)運(yùn)行失敗。若要指明函數(shù)運(yùn)行失敗,只需要設(shè)定線程的最后的錯誤代碼,然后讓你的函數(shù)返回FA L S E、I N VA L I D _ H A N D L E _ VA L U E、N U L L或者返回任何合適的信息。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,486評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,462評論 2 378

推薦閱讀更多精彩內(nèi)容

  • 一年級語文上冊生字表 生字表一(共400字) 啊(ā)愛(ài)安(ān)岸(àn)爸(bà)八(bā)巴(bā)...
    meychang閱讀 2,838評論 0 6
  • sì 支zhī茶chá 對duì 酒jiǔ,賦fù 對duì 詩shī,燕yàn子zi 對duì 鶯yīng 兒é...
    每個(gè)人的孟母堂閱讀 1,249評論 0 6
  • 1. 關(guān)于診斷X線機(jī)準(zhǔn)直器的作用,錯誤的是()。 (6.0 分) A. 顯示照射野 B. 顯示中心線 C. 屏蔽多...
    我們村我最帥閱讀 10,771評論 0 5
  • 網(wǎng)上眾多教程針對Windows,幸運(yùn)地在逼乎上看到了一篇回答(已感謝答主:單蕓峰)。 一 下載pip (Pytho...
    toedwy閱讀 3,044評論 3 7
  • 老人們常說的老話兒:“病由心生”。不生氣就不會生病。真的,其實(shí)很多病都是自己作的,大多數(shù)疾病都和生氣有關(guān),不生氣就...
    簡書粉粉閱讀 1,365評論 0 1