Recall that there are two good reasons for us to concentrate on
standard marshalling:
- Because it is easy. The object implementor need do nothing but
design the interfaces to be remoted in IDL.
- The implementation of standard marshalling is tightly coupled
to the notion of maintaining object identity across context.
We saw that CoMarshalInterface() and CoUnmarshalInterface() are
used to export an interface pointers from one context and import
into another. If an object doesn't implement the IMarshal interface,
the COM run-time¡¯s "standard marshaller" will be used to export and
import interface references to the object. All references to
marshalling and unmarshalling in this section assume the use of the
COM runtime¡¯s "standard marshaller".
Standard marshalling will perform the following tasks.
- Create a STDOBJREF for transmission.
- Create a stub in the object's context to receive incoming ORPC
request packets from the proxy.
- Create a proxy in the caller's context that feels exactly like
the real object but sends/receives ORPC request/response packets
in lieu of performing actual operations.
- The proxy and stub communicate via a system provided channel
that abstracts the exact underlying communication mechanism.
This channel is sensitive to the exact difference in context
that exists between the proxy and stub.
Marshalling an interface: STDOBJREF, interface stubs and the stub
manager
Under standard marshalling, CoMarshalInterface creates two things
for each marshalled interface on an object:
- A standard OBJREF, STDOBJREF, which is the marshalled data for
the interface, enough to unmarshall into a proxy.
- An interface stub. A stub for a given
interface holds on to a direct in-context reference to that
interface on the real object. It listens on the system-supplied
communications channel that connects the proxy and stub. The
interface stub intercepts ORPC requests from the proxy and
translates them into method invocations on the real object. For
the first interface reference that is marshalled for an object
identity, the standard marshaller will also set up a stub
manager, that looks after all the interface stubs.
Here is a diagram outlining the relationship between the stub
manager, the interface stubs and the real object. All are in the
object's context.

The STDOBJREF
Here is a diagram of the OBJREF that standard marshalling builds
- the STDOBJREF.

The important things to notice are
- A flag that indicates whether we are using
standard, custom or handler marshalling. This dictates the
layout of most of the rest of the OBJREF. Because we are
discussing standard marshalling then the format will be as
above.
- The interface IID, which is used to identify
the type of interface that has been marshalled. For standard
marshalling this is used as the registry key to work out which
proxy to load in the caller's context and which stub to load in
the object's context. This assumes both have been registered
correctly.
- The OXID, which is a machine-wide unique object
exporter ID on the exporting machine. It is used to identify
where the STDOBJREF was exported from, i.e. where the object
lives. OXIDs provide two things.
- OXIDs provide a container or scope for grouping together
objects. In theory an OXID defines a context-based
sub-division of a process that represents the unique location
that calls to an object can be dispatched (executed). In
reality it defines an apartment under the current
implementation of COM.
- OXIDs enable lazy resolution (at or before the first
method call) of the communications protocol used to bind to an
object's exporter and make calls on the object. This is done
via a service on the exporting machine called the OXID
Resolver, discussed later. The OXID is generated the first
time an interface is exported from an apartment. It is
registered in a table held by the OXID Resolver on the
exporting machine, along with the protocol information needed
to bind to the object exporter locally.
- The OID, which is a context-wide unique object
instance ID. This is used in the caller's context for
maintaining remote object identity.
- The IPID, which is a context-wide unique
interface stub identifier. Once the OXID has been used to
establish a connection with an object's exporter (apartment) in
the object's server on a particular machine, the IPID will get
us back to a particular interface stub on a particular object in
a particular context in the object's context.
- The host address determines the exporting
machine that must be used to resolve the OXID into the
communications protocol-specific address used to communicate
with the object, in the case where the OBREF is imported on a
foreign machine.
The standard marshaller uses the interface IID as a key to search
the registry for the stub class to load. Here is a diagram showing
the registry key for an interface IFoo. This is the registry of the
exporting machine.

The CLSID of the stub is shown by the ProxyStubClsid32 key
thus.

The registry entry for the stub's CLSID looks like this.

The standard marshaller uses this CLSID to load a code for the
stub class. Notice that the stub class is just a regular COM class
and that it is marked as threading model "Both", which simply means
that the stub (and proxy) code can be loaded directly into any
threading environment (more on the ThreadingModel attribute
later).
Unmarshalling an interface: proxies and the proxy manager
COM ensures that an interface proxy exists for each marshalled
interface reference that is unmarshalled. The interface proxy is
connected to the stub via a system-supplied channel. The interface
proxy is held by the caller that unmarshalls it as a direct
in-context reference. From the caller¡¯s perspective, the proxy looks
and feels just like the real interface implementation on the real
object. In reality, the proxy dehydrates the method calls into ORPC
requests that are sent to the connected interface stub. The proxy
then waits for the ORPC response, which it rehydrates in order to
return the results of the method to the caller. For the first
interface reference that is unmarshalled on a given object identity
(in a given context), the standard marshaller will set up a
proxy manager that looks after all the proxies. The proxy
manager represents the remote object's identity in the caller's
context.
Here is a diagram outlining the relationship between the caller,
the proxy manager and the aggregated interface proxies. All are in
the caller's context.

When unmarshalling, the standard marshaller uses the interface ID
in the OBJREF as a key to search the registry for the proxy class to
load.
Here is the whole picture.

Click here
to see an animation which shows the sequence of events that occurs
when an interface reference is passed as a parameter to a method of
an interface which is already remoted.
Next we look at how to
generate proxies and stubs for standard marshalling.

|