在本文的其余部分中,我将使用 Linux 作为开源软件的示例。在我提到“Linux”的地方,它主要是一种简短/简单的方式来指代一般的开源软件,而不是特定于 Linux 的任何东西。
COM 与 .NET
COM 实际上并不局限于 C 和 C++,.NET 实际上也没有取代 COM。然而,在某些情况下,.NET 确实提供了 COM 的替代方案。 COM 的一种常见用途是提供控件(ActiveX 控件)。 .NET 提供/支持自己的控件协议,允许某人用一种 .NET 语言编写控件,并使用任何其他 .NET 语言的该控件 - 或多或少与 COM 在 .NET 之外提供的东西相同。世界。
同样,.NET 提供 Windows Communication Foundation (WCF)。 WCF 实现了 SOAP(简单对象访问协议)——一开始它可能很简单,但后来发展到最不简单的程度。无论如何,WCF 提供了许多与 COM 相同的功能。尽管 WCF 本身特定于 .NET,但它实现了 SOAP,并且使用 WCF 构建的 SOAP 服务器可以与不使用 WCF 实现的服务器进行通信(反之亦然)。既然您提到了开销,那么可能值得一提的是,WCF/SOAP 往往会比 COM 增加更多的开销(我在任何地方都看到过几乎等于大约两倍的开销,具体取决于具体情况)。
要求差异
对于Linux,前两点往往相关性相对较低。大多数软件都是开源的,并且许多用户无论如何都习惯于从源代码构建。对于此类用户来说,二进制兼容性/重用影响很小或根本没有影响(事实上,相当多的用户可能会拒绝所有不以源代码形式分发的软件)。尽管二进制文件通常是分布式的(例如,使用 apt-get、yum 等),但它们基本上只是缓存为特定系统构建的二进制文件。也就是说,在 Windows 上,您可能有一个二进制文件可用于从 Windows XP 到 Windows 10 的任何操作系统,但如果您在 Ubuntu 18.02 上使用 apt-get,那么您正在安装专门为 Ubuntu 18.02 构建的二进制文件,而不是尝试与 Ubuntu 10(或其他)的所有内容兼容。
当组件丢失时能够加载和运行(功能减少)也是最常见的闭源问题。闭源软件通常有多个版本,具有不同的功能以支持不同的价格。对于供应商来说,能够构建主应用程序的一个版本,并根据提供/省略的其他组件提供不同级别的功能是很方便的。
但这主要是为了支持不同的价格水平。当软件免费时,只有一种价格和一种版本:很棒的版本 http://www.codinghorror.com/blog/2009/07/oh-you-wanted-awesome-edition.html.
语言之间对库功能的访问往往更多地基于源代码而不是二进制接口,例如使用SWIG http://www.swig.org/允许使用 Python 和 Ruby 等语言的 C 或 C++ 源代码。同样,COM 基本上解决了主要由于缺乏源代码而引起的问题;当使用开源软件时,问题根本就不会出现。
在其他进程中进行编码的低开销 RPC 似乎主要源于闭源软件。当/如果您希望 Microsoft Excel 能够使用 Adobe Photoshop 等内部“东西”时,您可以使用 COM 让它们进行通信。这增加了运行时开销and额外的复杂性,但是当其中一段代码由 Microsoft 所有,另一段由 Adobe 所有时,这几乎就是您所面临的困境。
源代码级共享
然而,在开源软件中,如果项目 A 具有某些在项目 B 中有用的功能,那么您可能看到(至多)项目 A 的一个分支,将该功能转换为一个库,然后将其链接到两个项目项目 A 的其余部分并进入项目 B,很可能还有项目 C、D 和 E——所有这些都不会增加 COM、跨过程 RPC 等的开销。
现在,请不要误会我的意思:我并不是想充当开源软件的代言人,也不是说闭源很糟糕,而开源总是非常优越。我什么am据说COM主要是在二进制级别定义的,但是对于开源软件,人们倾向于更多地处理源代码。
当然,SWIG 只是支持源代码级别跨语言开发的多种工具之一。虽然 SWIG 被广泛使用,但 COM 在一个相当关键的方面与它不同:使用 COM,您可以用单一的中性语言定义一个接口,然后生成一组适合该接口的语言绑定(代理和存根)。这与 SWIG 相当不同,在 SWIG 中,您直接从一种源语言匹配到一种目标语言(例如,绑定以使用 Python 中的 C 库)。
二进制通信
在某些情况下,至少拥有一些与 COM 提供的功能类似的功能仍然很有用。这些导致了开源系统在很大程度上类似于 COM。例如,许多开源桌面环境使用/实现 D-bus。 COM 主要是一种 RPC 类型的东西,而 D-bus 主要是一种在组件之间发送消息的商定方式。
然而,D-bus 确实指定了它称为对象的东西。它的对象可以有方法,您可以向其发送信号。尽管 D-bus 本身主要根据消息传递协议来定义这一点,但编写代理对象使得调用远程对象上的方法看起来非常像调用本地对象上的方法是相当简单的。最大的区别是 COM 有一个“编译器”,它可以采用协议规范,并自动为您生成这些代理(以及远端的相应存根以接收消息,并根据消息调用适当的函数)已收到)。这不是 D-bus 本身的一部分,但人们已经编写了工具来获取(例如)接口规范并根据该规范自动生成代理/存根。
因此,尽管两者并不完全相同,但 D-bus 具有足够的相似性,可以(并且经常)用于许多与 COM 相同的事物。
类似于 DCOM 的系统
COM还允许您使用DCOM(分布式COM)构建分布式系统。也就是说,您在一台计算机上调用一个方法,但(至少可能)在另一台计算机上执行该调用的方法的系统。这会增加更多的开销,但由于(正如上面针对 D-bus 所指出的)RPC 基本上是与连接到末端的代理/存根进行通信,因此以分布式方式执行相同的操作非常容易。然而,开销的差异往往会导致系统需要如何设计才能正常工作方面存在差异,因此对于分布式系统使用与本地系统完全相同的系统的实际优势往往相当小。
因此,开源世界提供了用于执行分布式 RPC 的工具,但通常不会努力使它们看起来与非分布式系统相同。 CORBA 众所周知,但通常被视为庞大且复杂,因此(至少根据我的经验)当前的使用相当少。阿帕奇节俭 http://thrift.apache.org/提供一些相同的通用类型的功能,但以一种更简单、更轻量的方式。特别是,当 CORBA 试图为分布式计算提供一整套工具(包括从身份验证到分布式计时的所有工具)时,Thrift 更紧密地遵循 Unix 哲学,试图准确满足一个需求:从接口定义(用中性语言编写)。如果你want使用 Thrift 做那些类似 CORBA 的事情,您毫无疑问可以,但是在构建调用者和被调用者相互信任的内部基础设施的更典型的情况下,您可以避免大量开销并继续处理手头的业务。同样地,谷歌远程过程调用 https://grpc.io/提供与 Thrift 大致相同类型的功能。
OS X 特定
可可提供分布式对象 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DistrObjects/Concepts/AboutDistributedObjects.html与 COM 非常相似。不过,这是基于 Objective-C 的,我相信它现在已被弃用。
苹果还提供XPC https://developer.apple.com/documentation/xpc。与 RPC 相比,XPC 更多的是关于进程间通信,因此我认为它更直接地与 D-bus 相比较,而不是与 COM 相比较。但是,很像 D-bus,它具有许多与 COM 相同的基本功能,但形式不同,更强调通信,而不是让事情看起来像本地函数调用(无论如何,许多人现在更喜欢消息传递而不是 RPC) )。
Summary
开源软件的设计中有足够多的不同因素,因此对提供与 Microsoft COM 在 Windows 上提供的功能相同的组合的需求较少。 COM 在很大程度上是一个试图满足所有需求的单一工具。在开源世界中,人们不太愿意提供单一的、包罗万象的解决方案,而更倾向于提供一套工具,每个工具都能很好地完成一件事,然后可以将它们组合成一个满足特定需求的解决方案。
由于更加商业化,Apple OS X 可能(至少可以说)比大多数更纯粹的开源世界更接近 COM。