微軟實現新版本操作系統向下兼容困難嗎?

眾所周知,微軟的新版操作系統對其舊版本系統軟體具有較好的兼容性,即使Windows系列的構架不斷在修改。第三方開發的Windows兼容工具如Wine的表現卻往往不如意。微軟自己本身實現向下兼容困難嗎?是什麼原因能讓它實現地比Wine更好?


既然題主提到了 Wine,作為一個菜鳥級別的 Wine 開發者(但是我對 Windows 的技術不是很懂)來說下我的看法:

首先困難是肯定的。

先說 Windows 部分:

1. 如果簡單從應用對 Win32 API 的調用來看,首先 Windows 必須保證 API 介面不變,但是不同版本的實現始終還是有差異的,假設以下情況:

XP 中的 riched20.dll 中的函數 FunctionA() 剛好有個 bug( Windows 的代碼也是人寫的,bug 是必須得),但是恰恰是這個使得某個應用 ApplicationA 中的一個對 FunctionA 調用的比較奇怪的用法可以工作!假如 MSDN 沒有對 FunctionA 這種奇怪的調用有說明,結果大量的第三方程序這樣用,ApplicationB、ApplicationC……ApplicationZ 都是,在 XP 正常工作。

過個一年半載,Windows 的開發者終於發現了這個 bug,所以隨手給修了,然後打算隨新版本的 Windows 發行,Vista。結果這一修,把原來那些用了奇怪的調用方法的一籮筐應用都給弄得 crash 掉了!卧槽,這可不行,怎麼辦呢,最粗暴的辦法就是把兩個版本都帶上,就是 WinSXS 的一個作用:舊應用調用舊 DLL,新應用調用新 DLL,保持兼容,即一個介面多個實現;

2. Win32 API 中保留了很多 reserve 參數。其實是為未來開發著想,以後 Windows 肯定會實現一些 Win32 API 的 feature,但是到時又要保證舊的應用調用這個 API 時正常,所以先佔個位,以後再實現時用,保持兼容;

3. 類似 2 的還有 FunctionEx 這樣的解決辦法。

以上其實就是 Windows 經常被黑的 DLL hell 吧,可以看出其實像 Windows 這樣大一個工程,為了這麼大一個市場,每次開發新版本時兢兢戰戰,保持向前兼容,MS 其實很努力了…

然後說下 Wine:

1. @vczh (好奇,是 VC 中文版的意思嗎 =.=)說得沒錯!因為 Wine 太窮了…其實也不是太窮,就是人手太少了(諸多原因,避免跑題太遠最後再說下)

2. Wine 目前對一些應用支持不好的主要原因,還不是因為 Windows 不同版本的實現差異。

要理解這個問題,得先明白 Wine 是什麼。官方描述為:

Wine (originally an acronym for "Wine Is Not an Emulator") is a compatibility layer capable of running Windows applications on several POSIX-compliant operating systems, such as Linux, Mac OSX, BSD. Instead of simulating internal Windows logic like a virtual machine or emulator, Wine translates Windows API calls into POSIX calls on-the-fly, eliminating the performance and memory penalties of other methods and allowing you to cleanly integrate Windows applications into your desktop.

說得很明白,Wine 就是開源的 Win32 API 實現,把 POSIX API、POSIX 上的 library api 用封裝、轉發的方式來實現這套開源的 Win32 API。

Wine 最主要的困難在於只用而且只能用微軟公開的文檔和黑盒測試的辦法,用 C 實現一套開源的 POSIX 之上的 Win32 API。(MS 公開的用於教育的代碼不能看、泄漏的代碼不能看、不能反彙編:CleanRoomGuidelines)

3. 這就好比別人寫了一個 FunctionB,還給了你一個對這個 API 調用方法的文檔,讓你在不看 FunctionB 代碼的情況下,實現一個兼容介面,一兩個好辦,但是 Windows 應該有上百個 DLL,至少八萬多個 API ,然後這些不同的 DLL、API 之間有些還有複雜的耦合。

從這裡我們可以看出:WineHQ - Win API Stats 那些綠色的,就是 Wine 實現得比較全面的 DLL,而紅色的還有很多,就是還沒有實現的,然後綠色中已經實現的部分還有一些是有 bug 的,Wine 的任務就是填平這些差異。

4. 我們也可以看到為什麼有這麼多還沒實現的 API,Wine 還可以跑 Office、跑 foobar2000、跑 QQ、跑阿里旺旺、跑 steam…嗯,至少成千上萬個應用:WineHQ - Wine Application Database

主要因為有幾個原因:一、假設我們跑 ApplicationC 時,它調用了 riched20.dll(怎麼又是它!=.=)中的一個 Wine 還沒實現的函數,我們可以用 native 的 riched20.dll 覆蓋掉這個 dll,然後就可以解決這個問題了(Wine 稱 MS Windows 實現的 DLL 為 native,Wine 實現的為 builtin);二、Wine 有一個 work for real world application 的原則,即是:Windows 那麼多 API,但是不是每個都有人用,每個都經常被用到,所以不會去盲目亂實現 API,而只是當有真實的程序調用到這個 API 時,不能正常工作,才去實現;三、即使被調用到的 API,有一些也只需要寫一個 stub,就是成功騙過應用,正常工作:Stubs - The Official Wine Wiki;

5. Wine 核心開發者不超過 100 人,Wine 始於 1993 年,最初只有單位數開發者、業餘開發;1999 年,CodeWeavers 成立,僱傭的幾乎所有的 Wine 核心開發者全職進行 Wine 開發(注意是 Wine 開發,CodeWeavers 的產品「商業版 Wine」——CrossOver 的核心功能都是 CodeWeavers 的僱傭的 Wine 開發者直接在 Wine 社區提交到 Wine);這期間 20 余載,100 人以內的開發者,實現了至少 3300 多個應用的良好支持:WineHQ - Browse Applications (Gold 是支持異常良好的,一般 Bronze 都是 ok 的)如果我們換個角度用 100 人 * 20 年開發 3300 多個應用給 Linux(嗯,一個桌面市場佔有率不到百分之二的操作系統) 其中還包括 Office、PhotoShop、AutoCAD 這樣的大型項目,不可想像吧~

6. 所以 Windows 和 Wine 都不容易吶,但是……Windows 也不能這樣坑開發者吶:實際上,根據經驗 MSDN 的文檔不可全信,坑隨處可見,所以 Wine 開發者只會相信測試,不會全信 MSDN 的文檔。

以上,如有錯漏還請大家不吝指出,多謝 ;)

以下福利,亂七八糟寫了這麼多,不給看到這裡的各位發福利那就太過分了 XD

----

1. 為什麼說 Wine 窮(人手不夠)?

a. Wine 開發入門門檻相對其他開源項目稍高,其綜合難度不亞於 kernel(Wine 社區有經驗的開發者都是 kernel、xorg、git…這些項目的貢獻者,因為 Wine 的一些 feature 的實現需要後者這些的支持)。Wine 本來就是要實現 Win32 API,其中 Windows 的各種功能都包含,所以說綜合難度和操作系統相當也合理;

b. 因為難度稍高,然後有興趣的開發者一般都是 *nix 用戶,然後他們發現還要寫 Win32 API 的代碼,2333

c. 偏見問題,有些人由於對於 Wine 架構、目標的不了解,對 Wine 有一定的偏見,甚至認為 Wine 是 Linux 下的搗亂者。他們認為如果有 Wine,開發者就不會去實現原生的版本。但是他們殊不知,資本會給用戶不足百分之二的操作系統開發這麼多原生應用?(你也許會說什麼什麼應用不是原生嗎,但是想下如果用戶一直百分之二,資本還會堅持嗎,爛尾又不是沒見過)而 Wine 恰恰是可能使 Linux 原生應用生態趨於良好的項目,假如通過 Wine 這種成本相對低的方法在 Linux 滿足了更多用戶的需求,Linux 用戶就更多,更多資本願意投入 Linux 原生,原生應用多了,Linux 用戶更多,如此良性循環,直到有一天我們不再需要 Wine!嗯,Wine 是自己的掘墓者。

d. 其實 Wine 在資金上不算窮,當然也不像土豪公司。首先 CodeWeavers 僱傭了 Wine 開發者進行全職開發,整個社區的核心開發者都不會因為生計而放棄 Wine 開發,這種模式在眾多開源項目中也是罕見的成功;其次 Wine 長期是 Google Summer of Code 的受益社區,土豪公司 Google 提供資金,由 Wine 社區主導培養學生成為新 Wine 開發者,這也是其他很多開源項目還沒申請得到、享受到的。

2. Wine 之 winelib

Wine 其實帶了很好玩的東西~因為 Wine 主體是一套開源的 Win32 API 實現,所以我如果把這套實現和編譯器搞一起了,那麼我們就可以在 *nix 下編譯 Win32 API 的代碼了!這個東西就是 winelib:Winelib - The Official Wine Wiki

理論上,只要是 Wine 支持良好的用 Win32 API 寫的程序,都可以把代碼用 Winelib 編譯,然後…還可以和 POSIX 混著寫…

3. Windows 不同 版本之間的差異——bug、以及 MSDN 的坑

http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/riched20/tests/richole.c#l446

ITextSelection_GetText 其實就是 ITextSelection::GetText,按照 MSDN 的說明,如果傳入的參數是 NULL,那麼就會返回 E_INVALIDARG。可是通過測試我們可以發現,在 64bit 的實現中,Windows 沒處理好這個問題…沒攔截 NULL 後 return E_INVALIDARG…於是在 64bit 的 Windows 中,你如果給 ITextSelection::GetText 傳一個 NULL,程序就會 crash 掉。

4. Wine 的 Testbot

Wine 只能通過文檔和測試來實現,Wine 是 TDD,所以需要把測試在所有 Windows 版本上跑一次,於是就有了 Testbot:Wine Test Bot

開發者只需要把 patch 提交,Testbot 就會自動在所有不同版本的 Windows 上跑測試,以此保證 Wine 的兼容性和防止退化。

5. ReactOS 的 Win32 API 兼容層來自 Wine,並且 ReactOS 的開發者大部分也給 Wine 貢獻代碼。

以上,謝謝

1:1408012150

2:1408012225:+ ReactOS


1:當然困難,windows8其實就是windows nt+2000+xp+vista+7+8。看看那兼容模式,有多少有名的程序不肯出補丁,結果要windows在高版本專門把他們依賴了的bug留給他們,當發現是這些傻逼程序的時候就給他一個帶bug的dll。

2:主要原因是因為Wine窮,招不到人。你看人家ReactOS能跑Office,證明這技術問題根本就不是什麼解決不了的事情對吧。


針對問題回答一下:

1. 微軟自己本身實現向下兼容困難嗎?

2. 是什麼原因能讓它實現地比Wine更好?

1. 困難得很,95時代的程序到現在都能跑,針對妖怪的程序要專門做hack,讓他們不會掛掉

2. 因為微軟人多錢多要文檔有文檔要源碼有源碼,有足夠多的人力物力處理這類問題

談到某些其他os,ABI和API都會變來變去,人家設計的時候就沒怎麼考慮兼容這檔子事情。


哎。。。我觀點是這特么真的是神跡啊


推薦閱讀:

阿里巴巴沒有能力開發出媲美linux的操作系統嗎?有的話為什麼不開發?
高頻交易中是否需要實時操作系統?
中國是否應當強制推廣自主知識產權的操作系統,並強制各大IT公司推廣相應的軟體?
你是如何愛上 Mac OS X 的?

TAG:微軟Microsoft | MicrosoftWindows | 操作系統 |