我正在努力学习COM。 我想我大致了解了COM的体系结构,
维基百科说:
对于编写良好的组件,COM允许在不了解其内部实现的情况下重用对象,因为它迫使组件实现者提供与实现分离的定义良好的接口。
此dll的客户端也不公开于实现, 只有界面,意思,他可以使用什么功能和他们的签名。
如果有人能向我解释一下COM背后的动机,我会很高兴的 它解决了什么问题。
它解决了什么问题。
当然这可能比你要求的要多,但这一直是我想写一篇博客文章的主题。
组件对象模式COM有一些优点。它还因为多年的边缘文档、实现的复杂性和开发人员的挫败感而饱受诟病。
它的核心是鼓励用户进行设计 interfaces
参考计数。当引用计数在当时被引入C/C++开发人员时,它类似于古罗马人了解数字0。
鼓励 loose coupling
它是 factory pattern
它可以用作本地和远程的面向对象抽象 过程调用(也称为“进程外COM”和“DCOM”)
执行和语言透明度。COM对象的调用代码和该对象的实现不需要用相同的语言编写。
它的功能:
对于本机C++开发,它是实例化在DLL中实现的具体C++类的一种非常有效的方法,但它返回纯抽象方法的抽象基类。它使您(开发者)能够在代码中从我的DLL中消费我的C++类,而不必包含一堆杂乱的实现特定的头文件。我可以给你一个简单的头文件,它不显示我的类和COM GUID的任何成员变量。然后,您只需使用类id和接口id调用CoCreateInstance。我还可以完全重新编写DLL,以及完全不同的类的具体实现——但只要我公开相同的接口,它就不会破坏您的使用。
插件模型。假设您的应用程序是照片渲染器,您希望支持第三方代码,以便能够与您的应用程序集成,在工具栏上添加一个按钮,并具有执行某些图像处理的代码。通过标准化接口,例如:
class ImageProcessor : public IUnknown { public: void ApplyEffect(BitmapData* pBitmap) = 0; };
在进程(本地过程调用)之间进行跨进程通信(在C++中)的一种明智方法。
GUID+注册表是一个设计错误(好了,我说了,来吧,兄弟。
进程外COM调用本来应该是一种异步调用模式,但COM默认使其同步。
将COM对象注册添加到应用程序设置是一件繁琐的事情。
微软的IDL文件格式是非标准的,MIDL工具使用起来并不有趣,文档也很简洁。
大量的开销,以获得从一个DLL导出的基本C++对象。在某些情况下,更容易坚持基于和IUnkown的实现,但只需从DLL中导出自己的工厂函数,而不是通过CoCreateInstance加载它。ATL模板类使这更容易。
进程外的线程模型。我站在篱笆上。他们选择了一个比“公寓”更糟糕的比喻,将线程模型引入COM。大多数书在解释STA和MTA之间的差异方面做得很糟糕。但是,一旦你了解了这些差异并阅读了足够多的雷蒙德·陈的博客文章,你就能真正欣赏它,并知道如何利用它进行设计。我只花了20年的时间就明白了这一点。
Out-of-proc COM调用pump窗口消息,并在应用程序中引入意外错误。这就是为什么进程内COM对象和进程外COM对象之间的位置透明性在某种程度上是一个神话的原因之一。