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.
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:
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).
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.
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.
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);