C++ 简而言之,什么是 COM(组件对象模型)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/455687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is COM (Component Object Model) in a nutshell?
提问by Carl Seleborg
It seems COM objects are general use objects which are governed by the OS. The objects follow a strict interface and allow you to query the objects to determine information. Is this what COM objects are?
似乎 COM 对象是由操作系统管理的通用对象。对象遵循严格的接口,并允许您查询对象以确定信息。这就是 COM 对象吗?
回答by Carl Seleborg
COMis a mechanism that allows the re-use of objects (or rather components), independently of the languages used by the programmer who implemented the component and the programmer who uses it, and independently of whether the component was implemented in the client's program or elsewhere on the machine (or network).
COM是一种允许重用对象(或者更确切地说是组件)的机制,独立于实现组件的程序员和使用它的程序员所使用的语言,也独立于组件是在客户端程序中实现的还是在客户端的程序中实现的。机器(或网络)上的其他地方。
Broadly speaking, each COM component provides an implementation of one or more interfaces. Those interfaces are defined in a language-neutral manner using the Interface Definition Language (IDL). As an example, one of the fundamental interfaces in COM, IUnknown, is defined like this:
从广义上讲,每个 COM 组件都提供一个或多个接口的实现。这些接口是使用接口定义语言 (IDL)以与语言无关的方式定义的。例如,COM 中的基本接口之一IUnknown定义如下:
interface IUnknown
{
virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) = 0;
virtual ULONG AddRef(void) = 0;
virtual ULONG Release(void) = 0;
};
This little interface is fundamental in COM, because each COM component mustimplement it. It defines two important aspects of the COM machinery:
这个小接口是 COM 的基础,因为每个 COM 组件都必须实现它。它定义了 COM 机制的两个重要方面:
QueryInterface
allows calling code to get an implementation for a known interface. In COM, interfaces are referenced by GUIDs (also known as Interface Identifiers, IID). If an object implements several interfaces, that's how client code gets a reference to each of those interfaces. It acts as a sort of casting operator, if you will.AddRef()
andRelease()
implement the memory management mechanism for COM objects. As their name suggests, the most common model is the reference counting mechanism, where an instance is destroyed after the last client has released its reference to it.
QueryInterface
允许调用代码来获取已知接口的实现。在 COM 中,接口由 GUID(也称为接口标识符,IID)引用。如果一个对象实现了多个接口,那么客户端代码就是这样获取对每个接口的引用的。如果您愿意,它充当一种强制转换运算符。AddRef()
并Release()
实现 COM 对象的内存管理机制。顾名思义,最常见的模型是引用计数机制,即在最后一个客户端释放对实例的引用后销毁实例。
All COM components are registered with the system upon installation. If a programmer wants to use a certain component, he needs to:
所有 COM 组件在安装时都会向系统注册。如果程序员想要使用某个组件,他需要:
- Make sure the component is installed at a reachable location. Most of the time it is on the system of the running application, but COM+ also allows components to exist on remote computers.
- Know the GUID of the given component. With this GUID, the client can then ask the system to instantiate the component (in C, the function to do this is called
CoCreateInstance()
). You can look in the registry underHKEY_CLASSES_ROOT\CLSID
: each GUID in there is (most probably) an identifier for a COM component or interface, and the entries below that key tell the system how it should be instanciated.
- 确保组件安装在可访问的位置。大多数情况下,它位于正在运行的应用程序的系统上,但 COM+ 也允许组件存在于远程计算机上。
- 知道给定组件的 GUID。有了这个 GUID,客户端就可以要求系统实例化组件(在 C 中,执行此操作的函数称为
CoCreateInstance()
)。您可以在以下注册表中查看HKEY_CLASSES_ROOT\CLSID
:其中的每个 GUID(很可能)都有一个 COM 组件或接口的标识符,该键下面的条目告诉系统它应该如何实例化。
The COM machinery is extremely complex. For example, implementing or using COM components in C requires a horrendous amount of work, but higher-level languages like Visual Basic have done a lot to ease the implementation and use of COM components. The benefits are however very real. It makes it possible to write an application in, say, Visual Basic, but to still implement the performance-critical algorithms in C or C++ as COM objects, which can be used directly from the VB code. The system takes care of marshallingmethod-call arguments, passing them through threads, processes and network connections as needed so that the client code has the impression of using a normal object.
COM 机制极其复杂。例如,在 C 中实现或使用 COM 组件需要大量的工作,但是像 Visual Basic 这样的高级语言已经做了很多工作来简化 COM 组件的实现和使用。然而,好处是非常真实的。它使得在 Visual Basic 中编写应用程序成为可能,但仍然可以将 C 或 C++ 中的性能关键算法实现为 COM 对象,可以直接从 VB 代码中使用。系统负责编组方法调用参数,根据需要通过线程、进程和网络连接传递它们,以便客户端代码具有使用普通对象的印象。
Many fundamental parts of Windows are based on COM. Windows Explorer (the file manager), for instance, is basically an empty shell. It defines a bunch of COM Interfaces for navigating and displaying tree hierarchies, and all the code that actually displays "My Computer", the drives, the folders and the files is as a set of COM components that implement those interfaces.
Windows 的许多基本部分都基于 COM。例如,Windows 资源管理器(文件管理器)基本上是一个空壳。它定义了一堆用于导航和显示树层次结构的 COM 接口,所有实际显示“我的电脑”、驱动器、文件夹和文件的代码都是作为一组实现这些接口的 COM 组件。
With the advent of .NET, COM is slowly becoming obsolete.
随着 .NET 的出现,COM 正慢慢变得过时。
回答by McDowell
COM is a mechanism that was developed to allow people to distribute binaries that could be reused even if the caller was using another vendor's C++ compiler or (ultimately) a different language altogether.
COM 是一种机制,旨在允许人们分发可以重用的二进制文件,即使调用者正在使用其他供应商的 C++ 编译器或(最终)完全不同的语言。
If you want a good introduction to COM, read Essential COMby Don Box.