IDL allows the passing of any C language basic or constructed data type as an RPC parameter, mainly through the use of attributes. However, the C++ language makes it much easier and convenient for the programmer to define new types using class definitions. A C++ application can contain a wealth of class definitions modeled after real world objects, usually in the form of class libraries. The implementation details of a class library definition are hidden from the programmer in favor of a public interface or set of operations to manipulate the class instance. In addition, software vendors are in the business of providing class libraries containing all sorts of class definitions that are ready to use by the application programmer.
As applications move towards the client/server model, and as distributed object technology becomes the vehicle for such a model, RPC must be able to pass C++ objects as parameters efficiently and intrinsically.
When an application is distributed, a number of issues arise that must be dealt with. These issues include the ability of the network to pass large amounts of data, the problem of passing pointers as RPC arguments, and the differences in the representation of a piece of data in the computer's memory that results from different machine architectures. These problems are addressed by DCE implementations adhering to the network data representation (NDR) for data types and the effective use of attributes in the interface definition. However, other problems that are specific to the C++ language include the following:
Data Hiding
One advantage of a class definition is that it allows the application designer to model a programming language construct after some real world object and to interact with the
construct in a high level fashion. The details of how the construct is built and manipulated should be handled by the designer of the class. The application programmer should be insulated from the
class internals and only needs to be aware of the public interface to the object. However, this programming model exposes a fundamental problem when extended to DCE RPC. In passing a parameter to a
remote procedure, the DCE runtime library must be able to marshal the RPC parameters over the network on behalf of the caller of the remote operation and unmarshal those parameters and reconstruct
the data type on the server side of the application. If users are able to create new and exotic data types, how can the DCE runtime know how to marshal them? It is unreasonable to expect that DCE
could be extensible enough to track and know how to marshal new data types as they are created. It is also unreasonable to expect class designers to supply their own support for marshaling objects.
This is especially true for data types that are provided as class libraries by outside vendors having no connection at all with DCE.
Inheritance
Inheritance and polymorphism are techniques available with C++ whereby a generic class type is used by an application but the actual object is created from a more specific
class type. A classic example of this is a generic class called Shape and a number of specific classes such as Circle, Square and Cylinder that all derive from the Shape class. Shape might have
operations such as draw( ) and rotate( ) which cause the object to be drawn onto the screen and rotated. The application can have an array of Shape objects and cause each one in turn to be displayed
and manipulated. However, the array could be a mix of Circle, Square and Cylinder objects. Each object will know how to draw and rotate itself. For some objects, a function such as rotate(
) may have no meaning. The polymorphic behavior of the Shape class will forward the draw( ) operation to the correct specific drawing operation implemented by the object. The rotate( )
operation behaves similarly for classes that support rotation. And if the object does not support rotation, the Shape class will supply its own rotate implementation which may actually do nothing.
The problem of passing a Shape object is that the DCE runtime may not know what type of shape the object really is. A Shape could have some self-identifying information, but this will often not be the case. Furthermore, if there were some shape identifier, it would need to track new class types as they are introduced into the application. This type of design is not very extensible and contrary to the object oriented methodology.
Lots of data
Another problem with passing a C++ object over the network is fundamental to any RPC argument. As the amount of data needed to be passed over the wire and recreated in the
server process increases, the performance of the RPC call will obviously decrease. The decision as to what kinds of operations are remote and what types of data they require is a basic design issue.
For example, consider a stack type. If the stack is small then it may be advantageous to pass the entire stack over the wire, recreate it on the server side, allow the server to update it, and then
pass it back to the client side so that it reflects any updates the server made to it. The IDL language supports such a paradigm by using an array network type along with other parameters to
indicate the array size. However, this paradigm quickly breaks down as the stack size increases. A better way for the server to access a large stack would be to pass a stack reference to the server
and allow the server to access the stack by making RPC calls to it.
Two programming methodologies are presented to illustrate how C++ objects can be passed as DCE RPC parameters: data representation and delegation. It is a design choice as to which solution better applies to a specific application problem. By using these methodologies, class libraries can be easily integrated into an application. Both solutions are intended to be handled primarily at the interface definition level so that the application itself can be designed in a normal and natural way while minimizing the issue of distributing the application.
More: