CoMarshalInterface

HRESULT CoMarshalInterface(pstm, riid, pUnk, dwDestContext, pvDestContext, mshlflags)

Marshal the interface riid on the object on which pUnk is an IUnknown* into the given stream in such a way as it can be reconstituted in the destination using CoUnmarshalInterface().17. This the root level function by which an interface pointer can be marshaled into a stream. It carries out the test for custom marshaling, using it if present, and carries out standard marshaling if not. This function is normally only called by code in interface proxies or interface stubs that wish to marshal an interface pointer parameter, though it will sometimes also be called by objects which support custom marshaling.

riid indicates the interface on the object which is to be marshaled. It is specifically not the case that pUnk need actually be of interface riid; this function will QueryInterface from pUnk to determine the actual interface pointer to be marshaled.

dwDestContext is a bit field which identifies the execution context relative to the current context in which the unmarshaling will be done. Different marshaling might be done, for example, depending on whether the unmarshal happens on the same workstation vs. on a different workstation on the network; an object could choose to do custom marshaling in one case but not the other. The legal values for dwDestContext are taken from the enumeration MSHCTX, which presently contains the following values.


typedef enum tagMSHCTX {
   MSHCTX_NOSHAREDMEM            = 1,
   MSHCTX_DIFFERENTMACHINE         = 2,
   MSHCTX_SAMEPROCESS            = 4,
   } MSHCTX;

These flags have the following meanings.

Value

Description

MSHCTX_NOSHAREDMEM

The unmarshaling context does not have shared memory access with the marshaling context.

MSHCTX_DIFFERENTMACHINE

If this flag is set, then it cannot be assumed that this marshaling is being carried out to the same computer as that on which the marshaling is being done. The unmarshaling context is (very probably) on a computer with a different set of installed applications / components than the marshaling context (for example, is on a different computer). This is significant in that the marshaling cannot in this case assume that it knows whether a certain piece of application code is installed remotely.

MSHCTX_SAMEPROCESS

The interface is being marshaled to another apartment within the same process in which it is being unmarshaled.


In the future, more MSHCTX flags may be defined; recall that this is a bit field.

pvDestContext is a parameter that optionally supplies additional information about the destination of the marshaling. If non-NULL, then it is a pointer to a structure of the following form.


typedef struct MSHCTXDATA {
   ULONG            cbStruct;
   IRpcChannelBuffer*      pChannel;
   } MSHCTXDATA;

The members in this structure have the following meanings:

Value

Description

cbStruct

The size of the MSHCTXDATA structure in bytes.

pChannel

The channel object involved in the marshaling process.


pvDestContext may legally be NULL, in which case such data is not provided.

mslflags indicates the purpose for which the marshal is taking place, as was discussed in an earlier part of this document. Values for this parameter are taken from the enumeration MSHLFLAGS, and have the following interpretation.

Value

Description

MSHLFLAGS_NORMAL

The marshaling is occurring because of the normal case of passing an interface from one process to another. The marshaled-data-packet that results from the call will be transported to the other process, where it will be unmarshaled (see CoUnmarshalInterface).

With this flag, the marshaled data packet will be unmarshaled either one or zero times. CoReleaseMarshalData is always (eventually) called to free the data packet.

MSHLFLAGS_TABLESTRONG

The marshaling is occurring because the data-packet is to be stored in a globally-accessible table from which it is to be unmarshaled zero, one, or more times. Further, the presence of the data-packet in the table is to count as a reference on the marshaled interface.

When removed from the table, it is the responsibility of the table implementor to call CoReleaseMarshalData on the data-packet.

MSHLFLAGS_TABLEWEAK

The marshaling is occurring because the data-packet is to be stored in a globally-accessible table from which it is to be unmarshaled zero, one, or more times. However, the presence of the data-packet in the table is not to count as a reference on the marshaled interface.

Destruction of the data-packet is as in the MSHLFLAGS_TABLESTRONG case.


A consequence of this design is that the marshaled data packet will want to store the value of mshlflags in the marshaled data so as to be able to do the right thing at unmarshal time.

Argument

Type

Description

pstm

IStream *

The stream onto which the object should be marshaled. The stream passed to this function must be dynamically grow-able.

riid

REFIID

The interface that we want to marshal.

pUnk

IUnknown *

The object on which we want to marshal the interface riid.

dwDestContext

DWORD

The destination context in which the unmarshaling will occur.

pvDestContext

void*

As described above.

mshlflags

DWORD

The reason that the marshaling is taking place.

return value

HRESULT

S_OK, STG_E_MEDIUMFULL, E_NOINTERFACE, E_FAIL