選單

說說有點意思的STRRET結構體

如果你曾經摺騰過外殼名稱空間(shell namespace),則我想你一定碰到過古怪的STRRET結構體。

這個結構體是

IShellFolder::GetDisplayNameOf用來返回一些列外殼專案名稱的。

如果你閱讀文件就可以知道,一個STRRET結構有時候是一個ANSI字串的緩衝區,有時候它又是一個指向UNICODE字串的指標,有時候(這個時候是最奇怪的情況)它會是一個指向一個pidl的偏移量。

這都什麼亂七八糟的?下面我們來具體看看。

STRRET結構是從Windows 95年代引入的。這個年代的計算機系統的效能還是比較慢的,記憶體也不是很大。(要知道,Windows 95的最小硬體需求是4MB的記憶體和一塊25MHz的386DX處理器)。在這樣的系統上,透過在棧(Stack)上分配記憶體(一條簡單的sub指令),遠比在堆(Heap)上分配記憶體(這可能需要數千條機器指令)要快得多,所以STRRET結構就被設計出來,用來應對在一些無需堆記憶體分配的場景需求。

STRRET_OFFSET標誌進一步將這種效能最佳化推向極端。通常,你將名稱保留在pidl中,並將其複製到 STRRET結構中需要花費200個時鐘週期。為了避免這種浪費的記憶體複製,STRRET_OFFSET允許你只返回一個偏移量到pidl中,然後呼叫者可以直接從中複製出來。

也就是說,透過這種技法,我們省掉了一個字串複製操作。

當然,隨著時間的推移,計算機變得更快,記憶體變得更大,這些微最佳化已經變成了煩惱。在字串複製操作上節省200個時鐘週期幾乎沒什麼意義。在1GHz處理器上,單個軟頁面錯誤(soft page fault)就會花費超過一百萬個週期,而一個硬頁面錯誤會讓你損失數千萬個時鐘週期。

在這段時間裡,你都可以複製大量的字串了。

更重要的是,Windows 95中常見的場景已經不那麼常見了,因此原本為最佳化量身定製的場景幾乎不再出現。 這是一種已經失去效用的最佳化。

幸運的是,你不必再考慮STRRET結構。有幾個輔助函式可以將STRRET結構轉換為更易於操作的東西。所以,不需要再在這個結構體上花功夫了。

總結

STRRET結構的怪異之處現在已被簡單易用的API封裝起來了,開發者也舒坦了。

我也覺得真是謝天謝地了。

最後

Raymond Chen的《The Old New Thing》是我非常喜歡的部落格之一,裡面有很多關於Windows的小知識,對於廣大Windows平臺開發者來說,確實十分有幫助。

本文來自:《The kooky STRRET structure》

最近我寫了個東西

正如你們所知道的,拓撲梅爾智慧辦公平臺(Topomel Box)是一款綠色軟體,主要面向經常使用電腦的朋友。它提供了各種提升辦公效率的小功能,同時操作上儘可能地簡單方便。

我想:你值得擁有。

說說有點意思的STRRET結構體