IMarshal interface
IMarshal interface is the mechanism by which an object is custom-marshaled. IMarshal is defined as follows:
interface IMarshal : IUnknown {
HRESULT GetUnmarshalClass(iid, pvInterface, dwDestContext, pvDestContext, mshlflags, pclsid);
HRESULT GetMarshalSizeMax(iid, pvInterface, dwDestContext, pvDestContext, mshlflags, pcb);
HRESULT MarshalInterface(pstm, iid, pvInterface, dwDestContext, pvDestContext, mshlflags);
HRESULT UnmarshalInterface(pstm, iid, ppvInterface);
HRESULT DisconnectObject(dwReserved);
HRESULT ReleaseMarshalData(pstm);
};
The process of custom marshaling an interface pointer involves two steps, with an optional third:
- The code doing the marshaling calls IMarshal::GetUnmarshalClass(). This returns the class ID that will be used to create an uninitialized proxy object in the unmarshaling context.
- (Optional) The marshaler calls IMarshal::GetMarshalSizeMax() to learn an upper bound on the amount of memory that will be required by the object to do the marshaling.
- The marshaler calls IMarshal::MarshalInterface() to carry out the marshaling.
The class IDand the bits that were marshaled into the stream are then conveyed by appropriate means to the destination, where they are unmarshaled. Unmarshaling involves the following essential steps:
- Load the class object that corresponds to the class that the server said to use in GetUnmarshalClass().
IClassFactory * pcf;
CoGetClassObject(clsid, CLSCTX_INPROCSERVER, IID_IClassFactory, &pcf);
- Instantiate the class, asking for IMarshal interface:
IMarshal * proxy;
pcf->CreateInstance(NULL, IID_IMarshal, &proxy);
- Initialize the proxy with IMarshal::UnmarshalInterface() using a copy of the bits that were originally produced by IMarshal::MarshalInterface() and asking for the interface that was originally marshaled.
IOriginal * pobj;
proxy->UnmarshalInterface(pstm, IID_Original, &pboj);
proxy->Release();
pcf->Release();
The object proxy is now ready for use.