Developing Component Software with CORBA > 5 The Bank Client > 5.4 Defining the interfaces


5.4.3 Initializing the ORB and obtaining the first object reference

A client can only communicate with a CORBA object if it possesses a reference to that object. This raises the question of how the client obtains its initial object reference. The fact that some IDL operation may return an object reference is of no help here: without a reference to specify as its target, there is no way to invoke this operation.

In more detail, before a client can enter the CORBA environment, it must first:

CORBA provides a standard set of operations, specified in pseudo IDL (PIDL), to initialize applications and obtain the appropriate object references.

Operations providing access to the ORB reside in the CORBA module. (Like an IDL interface declaration, a (P)IDL module declaration defines a new namespace for the body of declarations it encloses. What it does not do is define a new type of CORBA object.) Operations providing access to an Object Adapter, Interface Repository, Naming Service, and other Object Services reside in the ORB interface defined within the CORBA module.

To provide some flavor of PIDL, here is a fragment of the PIDL specification of CORBA that we rely on in our implementation of the bank client.

module CORBA { 
  interface Object { 
    boolean is_a (in string logical_type_id); 
  interface ORB { 
    string object_to_string (in Object obj); 
    Object string_to_object (in string str); 
  typedef string ORBid; 
  typedef sequence <string> arg_list;
  ORB ORB_init (inout arg_list argv, in ORBid orb_identifier);

The Object interface is implicitly inherited by all IDL interfaces, much as every Common Lisp class inherits from the class standard-object .

The is_a operation provides a test for inheritance (the logical_type_id is a string representation of an interface identifier). The operation returns true if the object is an instance of that interface, including if that interface is an ancestor of the most derived interface of that object.

The ORB operations object_to_string and string_to_object provide an invertible mapping from object references to their representations as strings.

Notice that the CORBA operation ORB_init is defined outside the scope of any interface, providing a means of bootstrapping into the CORBA world. Calling ORB_init initializes the ORB, returning an ORB pseudo-object that can be used as the target for further ORB operations.

Like most other language bindings, the Common Lisp binding adopts the pseudo-objects approach in which these CORBA and ORB operations are accessed by applying the binding's normal IDL mapping rules to the PIDL specification.

In this tutorial, we use a very simple technique to obtain the initial object reference. The client assumes that the server has published a reference to its implementation of the bank object, encoded as a string, in a shared file. After starting up, the client reads the file, decodes the string as an object reference, and then uses this reference as the target of further operations.

Here is the remaining Common Lisp code that completes the implementation of the client:

(defun bank-client ()
  (let ((orb (op:orb_init nil "LispWorks ORB")))
    (let ((bank-ref (op:narrow 'BankingDemo:bank
                               (file-to-object orb))))
      (capi:display (make-instance 'bank-interface 
                                   :bank-ref bank-ref
                                   :title "Corba Bank")))))

The defparameter *bank-ior-file* is the name of the shared file used to pass the reference of the bank object from the server to the client.

The method file-as-string reads a file's contents.

The top-level let statement first initializes The LispWorks ORB by calling the Common Lisp generic function op:ORB_init corresponding to the PIDL ORB_init operation. The first argument to this call is an empty list. Passing an empty sequence instructs the op:ORB_init function to ignore this argument and use the application's command line arguments (if any) instead. The value of the second argument, "LispWorks ORB" , merely identifies the ORB to use.

Invoking op:string_to_object on this ORB, passing the string read from the shared file, reconstitutes the string as an unspecific object reference of class CORBA:Object . Calling the op:narrow method on this object reference narrows (that is, coerces) it to a more specific object reference of class
BankingDemo:bank . (The op:narrow method employs an implicit call to the object's is_a operation to check that the desired coercion is safe.)

Finally, the resulting object reference bank-ref , of class BankingDemo:bank , is used to make and start a new bank interface, displaying the initial GUI to the user. The implementation of the client is now complete.


Developing Component Software with CORBA - 22 Dec 2009