[Previous] [Contents] [Next] [Orbix Home Page] [IONA Technologies]


1.3 Introduction to IDL C++ Classes

In this section, we present an overview of the mechanisms that a C++ programmer must appreciate in order to construct distributed applications. Subsequent chapters elaborate further on the concepts presented here.

Components of an Orbix program are called objects; and interfaces to remote objects are specified using IDL. An IDL interface consists of operation and attribute (property) specifications.

The Orbix IDL compiler can be used to produce a C++ class corresponding to each IDL interface; that is, the IDL compiler translates from IDL to C++ declarations. This step is required before the interface can be implemented or used by C++ code. In Orbix terminology, such C++ classes are called IDL C++ classes. An IDL C++ class lists the functions that clients of the interface can use.

The implementer of each IDL interface must write a C++ class. The definition of each member function gives the code to be run when the corresponding operation or attribute is called by a client.

Once an interface is implemented, any number of objects can be created. Each such object adheres to the corresponding IDL interface. These objects, although normal C++ objects, are special because they can be used from any node in the distributed system.

Each operation in an IDL interface is mapped into a C++ member function, of the same name, in the IDL C++ class. Since IDL interfaces can also have attributes, an attribute is mapped into a pair of C++ member functions: one to read (get) the value and the other to write (set) the value. IDL attributes which are "readonly" map to just a single function, which returns the value.


Figure 1.1: The overall programming environment for clients

An overall diagram of the client's programming environment for an IDL interface Account is shown in Figure 1.1.

IDL allows one interface to inherit from another, thereby creating an inheritance hierarchy. For example, interface CheckingAccount could inherit from interface Account, thereby inheriting all of Account's operations and attributes. The IDL C++ class CheckingAccount is generated as a derived class of the IDL C++ class Account.

An overview of the mapping between an interface specified in IDL and the corresponding (automatically produced) IDL C++ class is outlined in Chapter 3, "Summary of IDL to C++ Mapping". The full specification is given in Chapter 1, "IDL to C++ Mapping" of the Orbix Reference Guide.

1.3.1 Client Side

An object reference in Orbix can denote an object which is local (in the same memory address space) or which is remote (in a different address space–either in a different node or in the same node). To ensure close integration with C++, Orbix object references are just normal C++ pointers. When the required object is remote, an object reference will refer to a proxy object for the remote object. A proxy is a local representative, or surrogate, for a remote object.

A client can bind to an Orbix object by specifying its unique identifier. The bind call returns an object reference that the client object can subsequently use to invoke functions on the (possibly) remote object, using normal C++ function invocation syntax. Whether the object is local or remote is transparent to the programmer–the same C++ syntax is used in both cases.

If the real target object is in fact remote, then the object reference for it automatically denotes a proxy object which implements the support necessary to send requests to the remote object: all requests made by the client will be forwarded automatically by the proxy to the remote object, as shown in Figure 1.2. Proxy objects are thus used to support the clients of a remote object, and the programmer of a client need not be aware of the existence of the proxy. It is possible to determine whether an object reference refers to a proxy or directly to the real target object (in the same address space), but this facility need not be used in most applications.

Proxy objects are C++ objects; they run code generated by the Orbix IDL compiler.1


Figure 1.2: An operation call on a proxy

1.3.2 Implementing an Interface

Each IDL interface must be implemented by a C++ class. This implementation class must implement each of the functions that correspond to IDL operations and attributes. Instances of such a class are Orbix objects–they are accessible from any node in the distributed system.

Clients are not concerned with the implementation class. They are only aware of the IDL interface, or in C++ terms, the IDL C++ class; this has the same name as the IDL interface and is generated by the IDL compiler.2

The IDL compiler can be instructed to produce a first version of the implementation class. It will then output a header file containing the class declaration, with the declaration of each of the functions that correspond to IDL operations and attributes; and it will output a file containing the definition of each of these functions, but each with a null body. The implementer of the class can then add other members (constructors, destructor, variables and public and private functions), and code each of the functions.

In fact, for a given IDL interface, it is possible to have more than one implementation class. This allows for the different implementations that may sometimes be required on different machine types, or simply to allow for different space/time trade-offs.

1.3.3 Servers and the Implementation Repository

The objects in a distributed system are contained in server processes, and to a lesser extent in client processes. Each server has a name, unique within its host machine. The same server name can occur in different hosts. A server can consist of one or more processes, as will become clear later.

The name of an object (its unique object reference) contains:

For example, the object identifier for an Account object would include the name of the server which manages the account, a marker name, and the name of the server's host.

The objects which are managed by a server need not be of the same implementation class, or even of the same IDL C++ class. Thus a server can support many different IDL interfaces–that is, it can be the server of objects which collectively support many different IDL interfaces.

Not all of the objects in a server need be visible to clients in the system. Some of the objects in a server can have IDL interfaces but nevertheless may exist only for direct use by the server itself. A server can also contain C++ objects that do not have a IDL interface; such objects cannot be directly invoked by remote clients.

Orbix provides an Implementation Repository, which manages the servers in the system. The Implementation Repository maintains a mapping from a server's name to the file name of the executable code which implements that server. The programmer of a server must therefore register its code with the Implementation Repository. As a result, this code image will be automatically launched (if it is not already launched) by Orbix when a function invocation is made to any object whose object identifier names that particular server. If required, any number of different servers can use the same executable code.

Orbix provides a number of different mechanisms, or modes, for launching servers, giving the programmer control over how servers are implemented as processes by the underlying operating system. In the default mode, shared mode, there will be at most one process for any given server. A process will be started by Orbix to run a server's code if an operation call is made on one of the objects managed by that server. That process can remain running indefinitely, or (in the default case) it can time out so that servers which are not currently in use do not waste system resources.

In another mode, unshared mode, a server can be coded and registered so that there will be one process per active object–that is, each active object runs in its own process. Although this mode is not frequently used, it has some advantages. One advantage is that the objects cannot interfere with each other's memory. Another is that operation invocations on the set of objects in a server can run in parallel because they are handled by different processes (which can be registered to run the same or different executable code). However, it should be remembered that it may be better to run multiple light-weight threads in a single server process, using the Multi-Thread version of Orbix.

In a third mode, per-method-call mode, Orbix will start a separate process for each operation call. When registering the server, a different, or the same, executable file can be specified for each operation.

On UNIX and Windows NT, Orbix provides the putit command for registering servers; this is explained in Chapter 6, "Registration and Activation of Servers", and, in more detail, in Chapter 2, "The Orbix Utilities", of the Orbix Reference Guide. By default, putit registers a server in the shared activation mode. The putit command also supports a number of variations on the modes outlined in this chapter, and these variations are explained in Chapter 2, "The Orbix Utilities", of the Orbix Reference Guide.

Although every server must be registered in the Implementation Repository, individual objects do not normally need to be registered. Individual objects are registered in unshared mode. To be more exact, only those objects for which Orbix should launch a process (if an appropriate process is not already running) should be registered in the unshared mode.

In the default shared mode, a server process can be started manually (or by some mechanism external to Orbix, for example by a debugger) prior to any invocations on its objects. Subsequent invocations will be passed to the process. This is very useful during the debugging of a server, since its output can be seen on the chosen window. Also, some server processes carry out extensive initialisation after being powered up, so it may be sensible to launch such servers before any clients are started.



1 Since IDL interfaces define only operations and not state, direct access to the state of remote objects is not possible or necessary: thus, an IDL C++ class only contains public member functions, and no public member data.



2 Programmers do not normally create instances of an IDL C++ class.



[Previous] [Contents] [Next] [Orbix Home Page] [IONA Technologies]