为什么WinRT是非托管的?

166

Windows 8引入了WinRT,类似于.NET但是不受管理。

为什么它是不受管理的?这是性能问题吗?这是否意味着垃圾回收不适用于较低级别的API?


56
这是一个“糟糕的决定”,和关闭它一样糟糕。你现在坚持要求参考资料和来源,而之前关闭问题已经截断了这个过程。现在你删除了程序员提供的优秀来源。 - Hans Passant
9
我投票认为这个问题不属于实际编程问题,只是出于好奇。没有程序员会因为这个问题而改变他们的代码。 - Raymond Chen
17
根据这种推理,“地球是如何形成的?”这样的问题在科学界会非常糟糕,因为它会吸引很多宗教性的猜测。但是对于这个问题有正确的答案,仅仅因为它引起了很多错误的答案并不意味着它是一个不好的问题。不过,为什么不把这个问题移到P.SE上呢? - Rei Miyasaka
22
@casperOne 对于许多开发者来说,这是一个合理的“白板”问题——我们想要了解做出决策的技术原因,以便在其他地方应用相同的推理。这是因为垃圾回收器难以分析吗?还是因为它提供了更易于访问的低级硬件抽象?如果没有技术原因,那么这只是不幸——但这与问题本身的质量完全无关。 - Rei Miyasaka
7
我同意@HansPassant的观点,这个问题需要重新开放并被视为有效。对于WinRT基础知识而言,“为什么是非托管的?”是一个非常好的问题。 - Rob Perkins
显示剩余7条评论
2个回答

195

WinRT是一个基于C语言的Winapi的替代品,必须在许多运行时环境中使用的API。20年前,C API相对容易进行互操作。但现在已经发生了改变,自上世纪90年代后半叶,COM成为通用粘合剂。Windows上常见的任何语言运行时都支持COM。

垃圾收集器是语言运行时实现的细节。例如,.NET的收集器与Javascript的收集器非常不同。在任何一种语言中创建的本地对象都必须遵守收集器的严格规则。这反过来意味着它们必须创建针对每种语言运行时具体的WinRT版本。即使像微软这样的大公司也无法承担为每个语言绑定创建和支持特定的WinRT版本的成本。而且,这也并不必要,因为这些语言已经支持COM。

目前,WinRT最好的绑定语言是C++,因为COM与显式内存管理更有效率。通过新的C++编译器扩展的充足帮助,可以将其自动化,类似于旧版的C++/CLI _com_ptr_t,并使用类似于C++/CLI语法的方式避免使用它。与托管语言的绑定相对简单,因为CLR已经具有出色的COM互操作支持。 WinRT还采用了.NET的元数据格式。截至今天,据我所知,在托管编译器方面还没有进行任何工作。

编辑:著名的Microsoft程序员和博客作者Larry Osterman在一个现已删除的答案中留下了一个很好的评论。以下是他的引言:

WinRT是非托管的,因为操作系统是非托管的。通过设计WinRT的方式,使其能够以许多不同的语言表达,而不仅仅是C ++,C#和JS。例如,我可以轻松看到一组Perl模块,这些模块实现适用于桌面的WinRT API。如果我们使用.NET实现,那将会非常困难。


14
我不了解编译器,但我非常确定WinRT .NET投影在CLR上做了很多工作。他们可能重复使用了COM互操作代码,但也存在差异(例如IInspectable可以让你查询对象的实际类类型或所有支持接口的列表,而使用winmd文件可以将WinRT元数据投射到Reflection中)。而且,winmd文件也不能直接用作Interop程序集,CLR必须进行特殊处理。 - Pavel Minaev
5
不确定,你正在忽略大象。IInspectable是IDispatch的替代品,它停留在1997年。你在微软工作,请随意分享一些秘密 :) - Hans Passant
13
为支持语言预测,三种语言都进行了相关工作。 - Larry Osterman
14
我认为目前“WinRT的最佳绑定”实际上是C#。CLR绑定甚至比相当快的COM互操作更加优化,而开发预览版中的.NET语言已经实现了对普遍异步函数的出色支持,使用“await”即可。在一些演示中,C#代码做的比C++样例多得多,并且更容易使用。也许以后C++会获得一个异步帮助扩展,但在这个版本中,C++异步看起来很糟糕。而使用垃圾回收的CLR不太可能泄漏长期内存,这是C++实现中循环问题的解决方案。C# FTW! - Govert
13
第三个投影是所有CLR语言(主要是C#和VB)的CLR。WinJS不是一个投影,而是一组支持库。投影直接内置于Chakra JS引擎中。 - Larry Osterman
显示剩余7条评论

25

WinRT是未托管的,因为它旨在取代Win32——Windows最低级别的可供开发人员访问的API。未托管的API仍然是开发人员可用的最具潜力的性能API,而且理由是它始终可以在其上面封装托管的API,这正是“投影”所做的。

这也意味着C++开发人员可以使用WinRT而不需要进行C++/CLI所引入的复杂操作(请参见https://www.stroustrup.com/bs_faq.html#CppCLI)。但这也意味着如果您想要使用WinRT,则仍然需要学习COM。

真正的问题是“为什么需要COM?为什么Microsoft必须发明它?”因为仅带有C++的所有增加的设施之外,COM是无法满足真正的面向对象编程工作的,而且Stroustrup声称C++给您“可移植性”的说法在实际工作中非常虚伪。请参见https://webmechs.com/webpress/2011/11/09/c-versus-objective-c-as-api-substrate/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接