为什么COM接口契约是不可变的?

时间:2015-03-15 01:38:08

标签: c++ com

我已经google了很多,发现很奇怪,没有人愿意解释为什么COM接口是不可变的。我想你无法从COM接口中删除任何方法的原因是因为依赖于该接口的客户端会遇到错误,这是不好的。但是为什么在接口上添加新功能会改变其中的任何一个?这与底层的vtable有关吗?

2 个答案:

答案 0 :(得分:5)

COM有一个非常强大的DLL Hell问题。几个基本原因:

  • 参与编写服务器和客户端代码的程序员很少相互了解,不能一起工作并拥有自己的发布计划。
  • 默认情况下,在整个计算机范围内注册服务器会影响依赖于服务器的每个客户端程序。带有reg-free清单的隔离COM是一种解决方法。
  • 早期绑定的COM(使用v表)非常有效,但对v-table更改非常不容忍。当客户端代码只调用完全错误的函数或传递错误的参数时,很难诊断不匹配。通过IDispatch进行的后期绑定调用是一种解决方法,但速度很慢。
  • COM程序员非常强烈要求作弊,更改界面{guids}会导致非常脾气暴躁的客户端程序员和尴尬的支持调用。使接口向后兼容相对容易,使其向前兼容永远不会起作用。只更改界面guid是真正安全的。
  • 部署COM服务器通常是客户的职责,他们通常不了解服务器以排除故障并纠正问题。

这些是其他通用的版本控制问题,许多运行时实现都会受到各种痛苦的影响。 COM的一个特定优势是你可以做些什么。改变{guids}并消除许多肮脏的东西。

答案 1 :(得分:3)

如果添加方法,则在使用旧版本的组件时,使用该方法的较新客户端将失败。

除非您专门添加代码来实现它,重建组件,然后在使用该组件的所有计算机上重新安装组件,否则组件的旧版本将无法使用新方法。

如果较新版本的客户端尝试在没有该方法的旧版本组件上调用新方法,则会发生未定义的行为(可能是崩溃,但也可能是静默数据损坏)。新客户端将尝试通过vtable中的指针条目调用方法,该指针条目在构建旧客户端时不存在,因此旧客户端在此位置将具有一些不相关的值。

当然,如果您同时控制客户端和组件并将它们部署在一起,这对您来说不会是一个问题,但COM是针对更广泛的用例而设计的。