2010-10-07 36 views
1

正如我們所知,在Windows系統中,我們可以在「控制面板\時鐘,語言和區域」中爲非Unicode程序設置區域語言。但是,當地語言對於應用程序意味着什麼?據我瞭解,一個應用程序是一個編譯後的二進制可執行文件,它只包含機器代碼指令和沒有數據,所以字符編碼如何影響它們的運行?什麼是非Unicode應用程序

一個猜測是,如果可執行文件在代碼段中包含一些文字字符串,它將使用一些內部字符集來編碼它們。如果字符集不是unicode,那麼它將顯示垃圾。但是,不是內部的Charset是固定的嗎?就像在Java中一樣,java規範定義了內部編碼是UTF-16。

希望有人能回答我的問題,

感謝。

+1

請記住,Unicode並不意味着UTF16,但它在Windows上。他們應該在15年前使用UTF8,而這個問題不存在。 – 2010-10-07 09:20:18

+0

@Matt喬伊納:實際上,這個問題依然存在。請記住,我們在這裏正在討論_non-Unicode_程序。他們根本不關心_Unicode_程序是否使用UTF8或UTF16。 – MSalters 2010-10-08 14:35:11

回答

4

Windows有兩種方法可以讓程序與之通話,稱爲「ANSI API」和「Unicode API」,而「非unicode應用程序」是通過「ANSI API」與Windows通話的方式比「Unicode API」。

這意味着應用程序傳遞給Windows的任何字符串只是一串字節,而不是一串Unicode字符。 Windows必須決定哪些字符序列與之對應,並且您正在討論的控制面板設置是如何實現的。

所以例如,設置爲使用Windows西方將顯示字符ä在PC上輸出值爲0xE4字節,而一個設置爲希伯來語將顯示字符ה非Unicode程序。

+0

並且在「ANSI API」中的一個字節意味着屏幕上的一個字符。在Unicode中,屏幕上的字符可以由多個字節表示。 – 2010-10-07 08:23:04

+1

@Amigable Clark Kant:並非總是如此 - 「雙字節字符集」(請參閱​​http://msdn.microsoft.com/en-us/library/dd317794%28VS.85%29.aspx)仍然使用ANSI API 。否則,Unicode之前可能沒有中文版本的Windows! – RichieHindle 2010-10-07 08:33:35

+0

還應該注意的是,Microsoft可以輕鬆地將UTF-8添加爲支持的多字節字符集,並使整個問題消失,但他們拒絕這麼做*。 – 2010-10-07 16:40:08

0

非Unicode應用程序是一種主要使用一個多字節編碼,其中該字符串由字符* reperesented,不爲wchar_t *:

char* myString; 

通過改變所使用的編碼,則改變字符設置可用於應用程序。

而且大多數應用程序都包含指令和數據。

+1

@Amigable Clark Kant:不,對於ANSI API和使用'char',「多字節」是正確的。例如,請參閱MultiByteToWideChar API,其中MultiByte表示非Unicode,WideChar表示Unicode。 – RichieHindle 2010-10-07 08:36:00

+1

答案和評論應該說明這是Microsoft創建的不正確的術語。 Unicode的主要編碼是UTF-8,一種多字節編碼,並且存在寬字符編碼不是Unicode的系統。實際上,有人可能會認爲它不是Windows上的Unicode,因爲Windows的wchar_t太小而不能存儲任意的Unicode代碼點了。 – 2010-10-07 16:42:24

+0

@Alexander Rafferty:對於數據段,ANSI C使用的內部編碼是什麼?不是由C定義的,還是我們可以改變? – Alfred 2010-10-07 19:33:23

0

RichieHindle正確地解釋了大多數API的一種* W(Unicode)和* A(ANSI)變體。但在此之後,他有點不對。

重要的是要知道* A變體(如MessageBoxA)只是* W版本的包裝(如MessageBoxW)。他們將輸入的字符串轉換爲Unicode;他們把輸出的字符串轉換回來。

在Windows SDK中,對於所有此類A/W對,存在#ifdef UNICODE塊,因此MessageBox()是擴展爲MessageBoxA()MessageBoxW()的宏。由於所有宏都使用相同的條件,因此許多程序都使用100%* A函數或100%* W函數。那麼「非Unicode」應用程序就是而非定義的UNICODE,因此只能使用* A變體。

但是,沒有理由不能混合搭配* A和* W功能。混合* A和* W函數的程序是否被認爲是「Unicode」,「非Unicode」還是別的?其實,答案也很複雜。當涉及到Clock,Language和Region設置時,應用程序在進行* W調用時被認爲是Unicode應用程序,在進行* A調用時被認爲是非Unicode應用程序 - 該設置控制* A包裝程序轉換爲* W電話。因此,回到RichieHindle的例子中,如果你調用一個值爲(char)0xE4的*函數,包裝將轉發到* W功能可以使用L'ä'L'ה',具體取決於此設置。如果您直接用值(WCHAR)0x00E4調用* W函數,則不會發生翻譯。