PreviousNext

Pointers

RPC pointers differ from local pointers in one key respect: there is no shared address space between client and server. This means that the stubs need to marshall the pointed-to data itself. To do so, the stubs must be able to dereference any pointer passed as a parameter. This means that a pointer, even if it does not point at useful data, must be initialized either to NULL or to a valid address before it is passed as a parameter. This behavior may be counter-intuitive for programmers used to local procedure calls, where pointers may be freely passed whether they have been initialized or not, and is a common source of programming grief for remote procedure calls.

To be able to marshall pointer referents, the stubs need to know, either at compile time or at runtime, how much data to transmit; that is, they need to know the size of the pointed to object. This can require a good deal of work on the part of the stubs in the case of varying or conformant arrays and objects like linked lists.

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.

More:

Memory Allocation Routines

Pointer Types

Pointer Examples