Wrappers are created in order to expose a COM interface on a managed class. The COM interface that is exposed from the wrapper is really just a proxy for the actual interface that the object implements. The interfaces generated by the wrapper are always generated dynamically. As interfaces are requested, the wrapper uses the class metadata to determine if the class implements the requested interface. If it does, the wrapper creates a new vtable for the interface and populates the vtable with pointers to stub functions that delegate the calls to the real methods on the object. These tear-off interfaces are only created if, and when, they are requested. This reduces the object overhead considerably for objects that implement many interfaces as the vtable for the interfaces are only allocated if the interface is used.
At any given time, a CCW may be proxying several different interfaces on the same managed object. The CCW handles the details of generating the vtable and stubs as necessary.
All interfaces explicitly implemented by a NGWS class can be exposed through the CCW as a vtable-based COM interface. For backward compatibility with classic COM, the actual layout of the vtable for the COM interface can be controlled through the class metadata although most COM interfaces would typically have the same layout as the managed interface.
As mentioned, the function pointers in the vtable exposed by the CCW don’t actually point to the managed implementation of the method. Instead they point to stubs that marshal the call to the correct managed method. The stubs are responsible for the marshaling the call from the unmanaged code to managed code.