1. 程式人生 > >筆記摘錄:Unicode、核心物件

筆記摘錄:Unicode、核心物件

第一章   對程式錯誤的處理

1、若要確定是什麼錯誤,請呼叫GetLastError函式:該函式只返回執行緒的32位錯誤程式碼。

2、Visual studio還配有一個小的實用程式稱為Error Lookup,可以使用Error Lookup將錯誤程式碼的號碼轉換成相應文字描述。

3、Windows提供了一個函式FormatMessage,可以將錯誤程式碼轉換成它的文字描述。Error Lookup呼叫FormatMessage函式。

 

第二章   Unicode

1、軟體的本地化要解決的真正問題,實際上就是如何來處理不同的字符集。

2、有些文字和書寫規則的字符集中的符號太多了,因此單位元組(提供的符號最多不能超過256個)是根本不夠的,為此出現了雙位元組字符集(字串中的每個字元可以包含一個位元組或兩個位元組)。strlen函式可獲得字串中究竟有多少位元組而不能獲得有多少字元。 

3、Unicode:寬位元組字符集,字串中的所有字元都是16位的(兩個位元組),因此總共可以得到 65000個字元,遠遠超過了單位元組字符集的256個字元的數目。

4、Unicode功能:可以很容易地在不同語言之間進行資料交換 ;使你能夠分配支援所有語言的單個二進位制exe檔案或DLL檔案 ;提高應用程式的執行效率 。

5、Unicode字元的資料型別: typedef unsigned short wchar_t。 Unicode資料型別:WCHAR (Unicode字元)、PWSTR(指向Unicode字串的指標)、PCWSTR(指向一個恆定的Unicode字串的指標)。


6、TCHAR資料型別可以定義一個ANSI/Unicode通用的字串陣列,如果定義了_UNICODE:typedef wchar_t TCHAR;   未定義_UNICODE:typedef char TCHAR。 ANSI/Unicode通用資料型別:PTSTR和PCTSTR,取決於是否定義巨集UNICODE。

7、字串前面的大寫字母L或_T(),用於告訴編譯器該字串應該作為Unicode字串來編譯。

8、Unicode函式均以wcs開頭,用字首wcs來取代ANSI字串函式的字首str,如wcscpy = strcpy。 ANSI/Unicode通用字串函式:lstrcat、lstrcmp、lstrcmpi、lstrcpy、lstrlen,取決於是否定義UNICODE巨集。


9、CreateWindowExW是接受Unicode字串的函式版本,CreateWindowExA是接受ANSI字串的函式版本。

10、成為符合ANSIUnicode的應用程式基本原則 :

  * 將文字串視為字元陣列,而不是chars陣列或位元組陣列;

  * 將通用資料型別(如TCHARPTSTR)用於文字字元和字串;

  * 將顯式資料型別(如BYTEPBYTE)用於位元組、位元組指標和資料快取;

  * TEXT巨集用於原義字元和字串;

  * 執行全域性性替換(例如用PTSTR替換PSTR);

  * 傳遞一個快取的大小: sizeof(szBuffer)/sizeof(TCHAR),  為字串按位元組來分配記憶體塊: malloc(nCharacters *sizeof(TCHAR)) 。

 

第三章   核心物件

1、每個核心物件只是核心分配的一個記憶體塊,並且只能由該核心訪問。該記憶體塊是一種資料結構,它的成員負責維護該物件的各種資訊。

2、應用程式如何才能操作這些核心物件呢?

   Windows提供了一組函式,核心物件可以通過這些函式進行操作。當呼叫一個用於建立核心物件的函式時,該函式就返回一個用於標識該物件的控制代碼。程序中的任何執行緒都可以使用這個控制代碼值,將控制代碼傳遞給Windows的各個函式,系統就能知道你想操作哪個核心物件。

3、每個核心物件都包含一個數據成員:使用計數。當一個物件剛剛建立時,它的使用計數被置為1。當另一個程序訪問一個現有的核心物件時,使用計數就遞增1。如果核心物件的使用計數降為0,核心就撤消該物件(程序終止執行,核心物件不一定被撤消)。

4、安全描述符用於描述誰建立了該物件,誰能夠訪問或使用該物件,誰無權訪問該物件。用於建立核心物件的函式幾乎都有一個指向SECURITY_ATTRIBUTES結構的指標作為其引數,大多數應用程式只是為該引數傳遞NULL,建立帶有預設安全性的核心物件(物件的管理小組的任何成員和物件的建立者都擁有對該物件的全部訪問權,而其他所有人均無權訪問該物件)。

5、應用程式也可使用其他型別的物件,如選單、視窗、滑鼠游標、刷子和字型等。這些物件屬於使用者物件或圖形裝置介面GDI物件。如何確定一個物件是否屬於核心對象? 

   觀察建立該物件所用的函式,建立核心物件的所有函式都有一個設定安全屬性的引數。用於建立使用者物件或GDI物件的函式都沒有PSECURITY_ ATTRIBUTES引數。

6、當程序初次被初始化時,系統為它分配一個空的控制代碼表。當程序中的執行緒呼叫建立核心物件的函式時,核心就為該物件分配一個記憶體塊,並對它初始化,同時核心掃描程序的控制代碼表,找出一個空項放入。建立核心物件的函式返回與程序相關的控制代碼,該控制代碼值實際上是放入程序的控制代碼表中的索引。如果呼叫一個函式建立核心物件失敗了,那麼返回的控制代碼值通常是NULL(0),但是呼叫CreateFile時未能開啟指定的檔案,那麼它將返回INVALID_HANDLE_VALUE(-1)。

7、通過呼叫CloseHandle來關閉核心物件,該函式首先檢查呼叫程序的控制代碼表,如果傳遞給它的索引(控制代碼)是有效的,那麼系統就可以獲得核心物件的資料結構的地址,並可確定該結構中的使用計數。如果使用計數是0,該核心便從記憶體中撤消該核心物件。

8、假如忘記呼叫CloseHandle函式,那麼會不會出現記憶體洩漏呢?

   可能。在程序執行時,程序有可能洩漏核心物件。但是,當程序終止執行時,操作系統能夠確保該程序使用的任何資源或全部資源均被釋放 。

9、在不同程序中執行的執行緒需要共享核心物件,需要共享的原因:

   1)檔案對映物件使你能夠在同一臺機器上執行的兩個程序之間共享資料塊。

   2)郵箱和指定的管道使得應用程式能夠在連網的不同機器上執行的程序之間傳送資料塊。

   3)互斥物件、信標和事件使得不同程序中的執行緒能夠同步它們的連續執行,這與一個應用程式在完成某項任務時需要將情況通知另一個應用程式的情況相同。

10、共享跨越程序邊界的核心物件的三種方法:

  物件控制代碼的繼承性:若要建立能繼承的控制代碼,父程序必須指定一個SECURITY_ATTRIBUTES結構,並對它初始化時將bInheritHandle成員置為TRUE,然後將該結構的地址傳遞給特定的Create函式。

  給物件命名:A程序呼叫Create*函式引數pszName為NULL時,就向系統指明建立一個匿名核心物件,若要按名字共享物件,則為pszName引數傳遞一個以0結尾的字串名字的地址。B程序可通過呼叫Create*函式或Open*數共享物件。 

  使用DuplicateHandle函式:該函式取出一個程序的控制代碼表中的專案,並將該專案拷貝到另一個程序的控制代碼表中。