A Simple Example of Using CORBA

For the purposes of this example I am assuming that both our client and our server are written in C++; furthermore, I will show just one of the many possible ways of implementing the server connection. For more information on C++ mappings (and mappings for other languages) refer to the OMG documents. I will also assume that both for the client and the server the interface to the ORB in this case is static, that is it is based on an IDL specification, DII and DSK are not used.

A simple example illustrating interfacing objects with CORBA can be constructed as follows. First, the programmer needs to write an OMG IDL specification of the object and the services it is supposed to perform. IDL is very similar to C++, with the concept of class roughly corresponding to the concept of an interface. An example specification may look like this:


  interface example_object{
    void operation_on_object(in long a, inout boolean b);
  }
  

This specification defines one object, on which a client can invoke one operation returning no results, but taking two arguments. In addition to the type, the parameters are described by in/out/inout attributes which signal whether the value will be passed from client to server, the other way around or both ways.


slide: Interface

This IDL specification is then passed through some IDL compiler, which generates client stubs and server skeletons in the languages in which client and server are written. These are then included in the client's program, and the server's program respectively. Additionally, the specification can be used to generate an entry in the interface and implementation repositories.

The client and server ``binding'' code needs to correspond to OMG language mapping specifications. According to the OMG document interfaces can be implemented in C++ through inheritance. In this case the above interface specification will map to the following hierarchy of classes:


Client-side

  class example_object: public virtual CORBA::Object{
    static example_object_Ref _bind(...);
    virtual void operation_on_object
  	(CORBA::Long a, CORBA::Boolean& b);
  }
  

The example_object class is used on the client's side. The function operation_on_object in this class represents a stub; its implementation will marshal parameters of the request, initiate sending the request to the server (through calling some ORB-specific routines which the compiler knows about) and wait for the answer. The _bind function will bind to a specific object of the example_object type given some of its characteristics (eg. its name, address, etc).


slide: Implementation


Server-side interface

  class example_object_sk: public virtual example_object{
    virtual void operation_on_object
  	(CORBA::Long a, CORBA::Boolean& b) = 0;
    static void call_operation_on_object( /* a stream */);
  };
  

On the object implementation side, the up-call from the Object Adaptor will be made through the skeleton function call_operation_on_object. Its implementation contains interface to the net on the server's side. After unmarshaling parameters, this function is going to execute a call to operation_on_object, which implements the service. Note that in this class operation_on_object is a pure virtual function and thus has to be implemented in a class derived from example_object_sk.


slide: Server-side


Server-side implementation

  class example_object_impl: public example_object_sk{
    void operation_on_object
  	(CORBA::Long a, CORBA::Boolean& b);
  };
  

The last class contains the actual implementation of the object and has to be written by the programmer.


slide: Server implementation


Simple scenario

In the simplest scenario, the main program of the server implementation contains an instantiation of the implemented object and a call to the Basic Object Adapter notifying it that the implementation is ready:

CORBA::BOA::impl_is_ready();

Then, a client can obtain an object reference to the server by calling the _bind method generated for the interface on the client side, and thus obtain a handle on the object in its own address space. Then it can invoke requests on the server as if it resided in its address space:

  example_object* x = 
  	example_object::_bind("my_example_object", leopard@cs.indiana.edu);
  x->operation_on_object(4,0);

slide: Simple scenario