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.
Related topics