说说有点意思的STRRET结构体

说说有点意思的STRRET结构体

作者:BlogUpdater |  时间:2021-09-20 |  浏览:113 |  评论已关闭 条评论

如果你曾经折腾过外壳命名空间(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)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。

相关推荐

评论已关闭。