OSF DCE Application Development Guide--Introduction and Style Guide
OSF DCE Application Development Guide—Introduction and Style Guide
One effect of this is that pointers only reference the marshalled data itself; that is, data of
the size determined by the stub. For example, passing an idl_char * parameter causes
the stub to marshall a single idl_char, since that is the size of the object pointed to by an
idl_char *. Typically, a local procedure call passes a char * type in order to pass the
address of an array of characters, not a single char; but a remote routine that tries to
move such a pointer beyond the transmitted char will very likely find itself pointing to
invalid storage and certainly not to the intended string.
A similar case is illustrated in the sample code: a client passes an array and an [in,out,
ptr] pointer to an array element. If the server sets the pointer to point to some element of
the passed array, then it will point to memory holding a copy of that element when the
call returns to the client. It will not point to any part of the passed-in array itself, and any
attempt to increment or decrement the pointer on the client side will leave it pointing to
an invalid location.
This is one example of the fact that you cannot assume that the results of pointer
arithmetic will be the same for a local and remote procedure call. To give another
example, suppose a call passes two parameters: a data structure and a pointer to the type
of the data structure, set to NULL. If the server application then sets the pointer to point
to the data structure, the client stub will allocate new storage for the returned data
structure and set the returned pointer to point to it. As a result, the returned pointer will
not point to the original structure, but to a copy of it in stub maintained memory.
This may seem like an IDL limitation, but in fact, the real issue is that the client and
server address spaces are different, and some operations in one address space cannot be
reflected in the other. Specifically, the server application cannot meaningfully interpret
an address in the client address space, and vice versa. So, as in the last example, the
server cannot set a pointer to point to a structure in the client address space; it can only
ask the client stub to mirror any changes made at the server.
6.3.3.1 Memory Allocation Routines
The stubs will do their best to allocate any new memory required for marshalled
pointed-to nodes so that the marshalling is transparent to the application. On the server
side, stub allocated memory exists for the scope of the manager routine call. The stub
frees such memory once the nodes have been marshalled. On the client side, however,
the stubs obviously cannot free the memory they have marshalled since they are
returning the data to the client application. Therefore, in order to avoid memory leaks,
when a client makes an RPC that results in the client stub allocating memory, the client
application needs to call rpc_sm_client_free( ) to free the pointed-to memory.
When a server manager routine needs to allocate new memory for a pointed-to node, it
can do so either statically or by making a call to a memory allocation routine. In the
latter case, however, the manager cannot deallocate the memory it has allocated, since
the pointer must be valid when the call returns (so that the stubs can marshall the data.)
Only the stub can free such memory. In order to permit this, server managers need to call
rpc_sm_allocate() to allocate memory for parameters. The stubs free all memory
allocated by rpc_sm_allocate() once they have marshalled the required data, thus
avoiding memory leaks.
6− 10 Tandem Computers Incorporated 124246










