Marshaling Rules for user_marshal and wire_marshal

The OSF-DCE specification for marshaling embedded pointer types requires that you observe the following restrictions when implementing the <type>_UserSize, <type>_UserMarshal, and <type>_UserUnMarshal functions. (The rules and examples given here are for marshaling. However, your sizing and unmarshaling routines must follow the same restrictions):

  • If the wire-type is a flat type with no pointers, your marshaling routine for the corresponding userm-type should simply marshal the data according to the layout of the wire-type. For example:

    typedef [wire_marshal (long)] void * HANDLE_HANDLE;
    

    Note that the wire type, long, is a flat type. Your HANDLE_HANDLE_UserMarshal function marshals a long whenever a HANDLE_HANDLE object is passed to it.

  • If the wire-type is a pointer to another type, your marshaling routine for the corresponding userm-type should marshal the data according to the layout for the type that the wire-type points to. The NDR engine takes care of the pointer. For example:

    typedef struct HDATA
    {
        long size;
        [size_is(size)] long * pData;
    } HDATA;
    
    typedef HDATA * WIRE_TYPE;
    typedef [wire_marshal(WIRE_TYPE)] void * HANDLE_DATA;
    

    Note that the wire type, WIRE_TYPE, is a pointer type. Your HANDLE_DATA_UserMarshal function marshals the data related to the handle, using the HDATA layout, rather than the HDATA * layout.

  • A wire-type must be either a flat data type or a pointer type. If your transmissible type must be something else (a structure with pointers, for example), use a pointer to your desired type as the wire-type.

The effect of these restrictions is that the types defined with the [wire_marshal] or [user_marshal] attributes can be freely embedded in other types.

wire_marshal

user_marshal

The type_UserSize Function

The type_UserMarshal Function

Thetype_UserUnMarshalFunction

Thetype_UserFreeFunction