The IMarshal interface enables a COM object to define and manage the marshaling of its interface pointers. The alternative is to use COM's default implementation, the preferred choice in all but a few special cases (see "When to Implement").
"Marshaling" is the process of packaging data into packets for transmission to a different process or machine. "Unmarshaling" is the process of recovering that data at the receiving end. In any given call, method arguments are marshaled and unmarshaled in one direction, while return values are marshaled and unmarshaled in the other.
Although marshaling applies to all data types, interface pointers require special handling. The fundamental problem is how client code running in one address space can correctly dereference a pointer to an interface on an object residing in a different address space. COM's solution is for a client application to communicate with the original object through a surrogate object, or proxy, which lives in the client's process. The proxy holds a reference to an interface on the original object and hands the client a pointer to an interface on itself. When the client calls an interface method on the original object, its call is actually going to the proxy. Therefore, from the client's point of view, all calls are in-process.
On receiving a call, the proxy marshals the method arguments and, through some means of interprocess communication, such as RPC, passes them along to code in the server process, which unmarshals the arguments and passes them to the original object. This same code marshals return values for transmission back to the proxy, which unmarshals the values and passes them to the client application.
IMarshal provides methods for creating, initializing, and managing a proxy in a client process; it does not dictate how the proxy should communicate with the original object. COM's default implementation of IMarshal uses RPC. When you implement this interface yourself, you are free to choose any method of interprocess communication you deem to be appropriate for your application — shared memory, named pipe, window handle, RPC — in short, whatever works.
Implement IMarshal only when you believe that you can realize significant optimizations to COM's default implementation. In practice, this will rarely be the case. However, there are occasions where implementing IMarshal may be preferred:
When you choose to implement IMarshal, you must do so for both your original object and the proxy you create for it. When implementing the interface on either object or proxy, you simply return E_NOTIMPL for the methods that are not implemented.
COM uses your implementation of IMarshal in the following manner: When it's necessary to create a remote interface pointer to your object (that is, when a pointer to your object is passed as an argument in a remote function call), COM queries your object for the IMarshal interface. If your object implements it, COM uses your IMarshal implementation to create the proxy object. If your object does not implement IMarshal, COM uses its default implementation.
How you choose to structure the proxy is entirely up to you. You can write the proxy to use whatever mechanisms you deem appropriate for communicating with the original object. You can also create the proxy as either a stand-alone object or as part of a larger aggregation such as a handler. However you choose to structure the proxy, it must implement IMarshal to work at all. You must also generate a CLSID for the proxy to be returned by your implementation of IMarshal::GetUnmarshalClass on the original object.
COM calls this interface as part of system-provided marshaling support. COM's calls are wrapped in calls to CoMarshalInterface and CoUnmarshalInterface. Your code typically will not need to call this interface. Special circumstances where you might choose to do so are discussed in the "Notes to Callers" section for each method.
IUnknown Methods | Description |
---|---|
QueryInterface | Returns pointers to supported interfaces. |
AddRef | Increments reference count. |
Release | Decrements reference count. |
IMarshal Methods | Description |
---|---|
GetUnmarshalClass | Returns CLSID of unmarshaling code. |
GetMarshalSizeMax | Returns size of buffer needed during marshaling. |
MarshalInterface | Marshals an interface pointer. |
UnmarshalInterface | Unmarshals an interface pointer. |
ReleaseMarshalData | Destroys a marshaled data packet. |
DisconnectObject | Severs all connections. |
Windows NT: Use version 3.1 or later.
Windows: Use Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in objidl.h.