> For the complete documentation index, see [llms.txt](https://7-stars-servers.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://7-stars-servers.gitbook.io/docs/windows-internals/component-object-model-com.md).

# Component Object Model (COM)

**COM** (Component Object Model) is a **Microsoft-developed framework** that allows **software components** to **communicate** with each other, **regardless of the programming language** used to write them.

It's a **binary-interface standard**, meaning it defines how components interact at the **binary level**, not source code level. This makes it language-independent and extensible.

**Interfaces:**

An **interface** in COM is like a **contract** — a list of method names (without implementation) that a component promises to provide.

* Think of it like a remote control: you know the buttons (methods), but not how the TV (component) actually works inside.
* Interfaces are written using **IDL** (Interface Definition Language), which allows COM to generate code for different programming languages.
* All COM interfaces must **inherit from `IUnknown`**, the base interface in COM, to support polymorphism and memory management.

**IUnknown Interface**

`IUnknown` is the **foundation** of all COM interfaces. It defines three crucial methods:

1. **`QueryInterface(REFIID riid, void** ppvObject)`**
   * Used to **ask** an object if it supports another interface.
   * Example: "Hey, do you also support printing or saving?"
   * If yes, it gives you a pointer to that interface.
2. **`AddRef()`**
   * Tells the object: “Someone is using you.”
   * Increases the **reference count**.
3. **`Release()`**
   * Tells the object: “I’m done with you.”
   * Decreases the reference count.
   * When it reaches 0, the object **destroys itself**.

**Vtable**

A **vtable** is a **lookup table of function pointers**.

In C++ (and in COM), when a class declares **virtual functions**, the compiler builds a table (the vtable) that stores **addresses of the actual functions** that should be called when those virtual methods are invoked.

Each **object** of the class stores a hidden pointer to its **class's vtable**.

***

**What Is the Virtual Function Dispatcher?**

The **dispatcher** is just how the program decides **which function to call** at runtime.

* When you call `obj->Speak()` on a pointer to a base class,
* The program does **not directly call** `IAnimal::Speak()`.
* Instead, it uses the **vtable pointer** stored in the object to **look up** the actual function address, and **jumps to it**.

This is what allows **dynamic dispatch** or **polymorphism**.

**What Is Cross-Process Marshalling?**

**Cross-process marshalling** is the specific case of marshalling where data (or interface calls) must move between:

* Two **separate processes** (i.e., they have **separate memory spaces**),
* Possibly even between **different user sessions** or across the **network** (in DCOM).

You **cannot directly share pointers** or references between processes, because each process has its own virtual memory space. So, COM (or other RPC systems) uses **marshalling** to:

* Serialize the data,
* Transmit it through some channel (like named pipes),
* Deserialize it on the other side.

**In the Context of COM**

COM interfaces (like `IMyObject`) are **pointer-based**. But:

* You cannot directly pass a pointer to a COM object from **Process A** to **Process B**.
* Instead, COM creates a **proxy** object in the client process, and a **stub** in the server process.
* When you call a method on the proxy, it **marshals the call** across process boundaries to the stub, which then calls the real object.

This is called the **COM Proxy-Stub model**.

**Use Case:**

**In Process A:**

* Process A has a **COM proxy** object.
* This proxy **looks like** the real object — it has the **same interface** (i.e., same method names and signatures).
* But when you call a method, the proxy doesn’t do the real work — instead, it:
  * **Packages the method call and arguments** (marshalling),
  * Sends that package to Process B.

**In Process B:**

* Process B has a **COM stub** (like a receiver).
* The stub **unpacks the message**, then calls the **real method** on the actual object in B.
* After the real method executes, the result is **marshalled back** to A.

So yes, **the COM proxy in Process A exposes all the methods** declared in the interface — but:

> These are not the real methods. They're just **placeholders** that forward the call to the actual object in Process B.

* **In Process B**:\
  There is **one real COM object** — the one that implements the logic and methods.
* **In Process A**:\
  There is **a proxy object** — not a real COM object in the full sense, but a special object created by the COM runtime to **act as a stand-in** for the real object.
* In Process A, you call `CoCreateInstance(CLSID_X)` — this tells COM:

  > "I want an object of class X."
* If that object is registered as **out-of-process**, COM will:
  * Start the EXE (Process B),
  * Ask it to create the actual COM object.
* COM now creates:
  * A **proxy** in **Process A** (called a **proxy stub**),
  * A **stub** in **Process B** (called a **stub manager**).
* These are **automatically generated** from the COM interface definition.
* They’re connected via an internal communication mechanism:
  * Named pipes
  * RPC (Remote Procedure Calls)
  * Shared memory (for in-process)
  * DCOM transport (for remote)

When Process A calls `object->DoSomething()`:

* A → Proxy → marshals data → sends to B
* B → Stub → calls real `DoSomething()` method
* B → Gets result → marshals it back → A

You never have to write this plumbing — COM handles it.
