IMarshal  555..25

The IMarshal interface enables an 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.

When to Implement

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:

    The objects you are writing keep their state in shared memory. In this case, both the original process and the client process uses proxies that refer to the shared memory. This type of custom marshaling is possible only if the client process is on the same machine as the original process. OLE-provided implementations of IStorageFS1VT1 and IStream8MD3QE are examples of this type of custom marshaling.

    The objects you are writing are immutable, that is, their state does not change after creation. Instead of forwarding method calls to the original objects, you simply create copies of those objects in the client process. This technique avoids the cost of switching from one process to another. Some monikers are examples of immutable objects; if you are implementing your own moniker class, you should evaluate the costs and benefits of implementing IMarshal on your moniker objects.

    Objects that themselves are proxy objects can use custom marshaling to avoid creating proxies to proxies. Instead, the existing proxy can refer new proxies back to the original object. This capability is important for the sake of both efficiency and robustness.

    Your server application wants to manage how calls are made across the network without affecting the interface exposed to clients. For example, if an end user were making changes to a database record, the server might want to cache the changes until the user has committed them all, at which time the entire transaction would be forwarded in a single packet. Using a custom proxy would enable the caching and batching of changes in this way.

 

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.

When to Use

COM calls this interface as part of system-provided marshaling support. COM s calls are wrapped in calls to CoMarshalInterfaceKHF9NR and CoUnmarshalInterface1LJ9LBY. 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.

Methods in VTable Order

IUnknown1NEM0LU Methods

Description

QueryInterface2Y54585

Returns pointers to supported interfaces.

AddRef1SHW0SS

Increments reference count.

ReleaseDUW01A

Decrements reference count.

 

IMarshal Methods

Description

GetUnmarshalClass12PRR_H

Returns CLSID of unmarshaling code.

GetMarshalSizeMaxWZ.VK0

Returns size of buffer needed during marshaling.

MarshalInterfaceCJVN_.

Marshals an interface pointer.

UnmarshalInterface15AQS.P

Unmarshals an interface pointer.

ReleaseMarshalDataCQ0NPV

Destroys a marshaled data packet.

DisconnectObject1VIIBC

Severs all connections.

 

See Also

IStdMarshalInfo