5.11 COM (Common Object Model)
The ffi/com and ffi/unsafe/com libraries support COM interaction in two layers. The safe upper layer provides functions for creating COM objects and dynamically constructing method calls based on COM automatiion (i.e., reflective information provided by the object). The unsafe lower layer provides a syntactic form and functions for working more directly with COM objects and interfaces.
A COM object instantiates a particular COM class. A COM class can be specified in either of two ways:
A CLSID (class id), which is represented as a GUID. A GUID (globally unique identifier) is a 16-byte structure. GUIDs are typically written in string forms such as "{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}". The string->guid and guid->string convert between string and GUID forms. The string->clsid function is the same as string->guid, but its use suggests that the resulting GUID is to be used as a CLSID.
A ProgID is a human-readable name, such as "MzCom.MzObj.5.2.0.7", which includes a version number. The version number can be omitted in a ProgID, in which case the most recent available version is used. The operating system provides a mapping between ProgIDs and CLSIDs that is available via progid->clsid and clsid->progid.
A COM object can be instantiated either on the local machine or on a remote machine. The latter relies on the operating system’s DCOM (distributed COM) support.
Each COM object supports some number of COM interfaces. A COM interface has a programmatic name, such as IDispatch, that corresponds to a C-layer protocol. Each interface also has an IID (interface id) that is represented as a GUID such as "{00020400-0000-0000-C000-000000000046}". Direct calls to COM methods require extracting a suitable interface pointer from an object using QueryInterface and the desired IID; the result is effectively cast it to a pointer to a dispatch-table pointer, where the dispatch table has a statically known size and foreign-function content. The define-com-interface form simplifies description and use of interface pointers. The COM automation layer uses a fixed number of reflection interfaces internally, notably IDispatch, to call methods by name and with safe argument marshaling.