When you define a pipe in an IDL file, the MIDL compiler generates a pipe control structure whose members are pointers to push, pull, and alloc procedures and a state variable that coordinates these procedures. The state variable is local to each side — that is, the client and server each maintain their own pipe state, by which their application code and stub code communicate.
The client application initializes the fields in the pipe control structure, maintains its state variable, and manages the data transfer with its own push, pull, and alloc functions, as described in the next topic. The client stub code calls these application functions in loops during data transfer. For an input pipe the client stub marshals the transfer data and transmits it to the server stub. For an output pipe, the client stub unmarshals the data into a buffer and passes a pointer to that buffer back to the client application.
The server stub code initializes the fields of the pipe control structure to a state variable and push, and pull routines. The server stub maintains the state and manages its private storage for the transfer data. The server application calls the pull and push routines in loops during the remote procedure call as it receives and unmarshals data from the client stub, or marshals and transmits data to the client stub.
In the following example, we define a pipe type LONG_PIPE, whose element size is defined as long. We also declare function prototypes for the remote procedure calls InPipe and OutPipe, to send and receive data, respectively.
//file: pipedemo.idl
typedef pipe long LONG_PIPE;
void InPipe( [in] LONG_PIPE pipe_data );
void OutPipe( [out] LONG_PIPE *pipe_data );
//end pipedemo.idl
//file: pipedemo.h (fragment)
typedef struct pipe_LONG_PIPE
{
void (__RPC_FAR * pull) (
char __RPC_FAR * state,
long __RPC_FAR * buf,
unsigned long esize,
unsigned long __RPC_FAR * ecount );
void (__RPC_FAR * push) (
char __RPC_FAR * state,
long __RPC_FAR * buf,
unsigned long ecount );
void (__RPC_FAR * alloc) (
char __RPC_FAR * state,
unsigned long bsize,
long __RPC_FAR * __RPC_FAR * buf,
unsigned long __RPC_FAR * bcount );
char __RPC_FAR * state;
} LONG_PIPE;
void InPipe(
/* [in] */ LONG_PIPE pipe_data);
void OutPipe(
/* [out] */ LONG_PIPE __RPC_FAR *pipe_data);
//end pipedemo.h