Netscape Internet Service Broker for C++ Programmer's Guide

[Contents] [Previous] [Next]

Chapter 9
The IDL Compiler

This chapter discusses the ISB for C++ IDL compiler and includes the following major sections:

The IDL Compiler

Code Generated for Clients

Code Generated for Servers

Interface Attributes

Oneway methods

Mapping Object References

Interface Inheritance

The IDL Compiler

You use the Interface Definition Language, IDL, to define the object interfaces that client applications may use. The IDL compiler uses your interface definition to generate C++ code. The following figure shows how the compiler generates code for the client application and for the object implementation, or server. The file names used for discussion in this chapter apply to systems that support long file names.

Figure 9.1    C++ files generated by the IDL compiler.

The Interface Definition

Your interface definition defines the name of the object as well as all of the methods the object offers. Each method specifies the parameters that will be passed to the method, their type and whether they are for input or output. The following code listing shows an IDL specification for an object named example. The example object has only one method, op1.

The example IDL specification.

// IDL specification for the example object
interface example
{
long op1(in char x, out short y);
};

Code Generated for Clients

Figure 9.1 shows how the IDL compiler generates two client files; ex_client.hh and ex_client.cc. These two files provide an example class in C++ that the client will use. By default, files generated by the IDL compiler have either a ".cc" or ".hh" suffix to make them easy to distinguish from file you create yourself.

Caution Do not modify files generated by the IDL compiler.
The example class generated in ex_client.hh.

class example : public virtual CORBA::Object
{
private:
   // Methods used internally by ISB for C++ to store type information
    ...
public:
   // More methods used internally by ISB for C++ to create object
   // references and manage type information
protected:
   example(const char *obj_name = NULL) : CORBA::Object(obj_name, 1);
   example(NCistream& strm) :CORBA::Object(strm);
   virtual ~example();
public:
static example_ptr _bind(const char *object_name = NULL,
                           const char *host_name = NULL,
                            const CORBA::BindOptions* opt = NULL);
static example_ptr _duplicate(example_ptr obj);
                    static example_ptr _nil();
                    static example_ptr _narrow(CORBA::Object *obj)
                    virtual CORBA::Long op1(CORBA::Char x, CORBA::Short& y);
};

Methods Generated

The code listing above shows the op1 method generated by the IDL complier, along with several other methods. The op1 method is called a stub because when your client application invokes it, it actually packages the interface request and arguments into a message, sends the message to the object implementation, waits for a response, decodes the response, and reflects the results to your application.

Because the example class is derived from the CORBA::Object class, several inherited methods are available for your use. The CORBA::Object class methods are described in the Netscape Internet Service Broker for C++ Reference Guide.

The _ptr Definition

The IDL compiler always provides a pointer type definition. The following code listing shows the type definition for the example class.

The _ptr type definition.

typedef example *example_ptr;

The _var Class

The IDL compiler also generates a class named example_var, which you can use instead of the example class. The example_var class will automatically manage the memory associated with the object reference.When the an example_var object is deleted, the object associated with example_ptr is released. When an example_var object is assigned, the old object reference pointed to by example_ptr is released after the assignment takes place. A casting operator is also provided to allow you to assign an example_var to a type example_ptr.

The example_var class.

class example_var
{
  public:
    example_var();
    example_var(example_ptr ptr);
    example_var(const example_var& var);
    ~example_var();
    example_var& operator=(example_ptr p);
    example operator=(const example_ptr p);
    example_ptr operator->();
    ...
  protected:
    example_ptr          _ptr;
  private:
    ...
};

Table 9.1 The _var class method descriptions.
method Description
example_var()

Constructor that initializes the _ptr to NULL.

example_var(example_ptr ptr)

Constructor that creates an object with the _ptr initialized to the argument passed. When the object is destroyed, the object to which _ptr points will destroyed.

example_var(const example_var& var)

Constructor that makes a copy of the object passed as a parameter var and points _ptr to the newly copied object. When this object is destroyed, the object to which _ptr points will be destroyed.

~example()

Destructor that frees any memory associated with _ptr before destroying this object.

operator=(example_ptr p)

Assignment operator that frees any memory associated with _ptr before performing the assignment.

operator=(const example_ptr p)

Assignment that frees any memory associated with _ptr before making a complete copy of the specified object and assigning _ptr to point to the newly created object.

operator->()

Returns the _ptr stored in this class. This operator should not be called until this class has been properly initialized.

Code Generated for Servers

The IDL compiler generates two server files: ex_server.hh and ex_server.cc. These two files provide an _sk_example class in C++ that the server will use to derive an implementation class. The _sk_example class is derived from the client's example class.

Caution You should not modify the contents of the files generated by the IDL compiler.
The _sk_example class generated in ex_server.hh.

class _sk_example : public example
{
protected:
_sk_example(const char *object_name = (const char *)NULL);
virtual ~_sk_example();
public:
static const CORBA::TypeInfo _skel_info;
virtual CORBA::Long op1(CORBA::Char x, CORBA::Short& y) = 0;
static void _op1(void *obj), CORBA::MarshalStream &strm,
                                        CORBA::Principal_ptr principal,
                                        const char *oper);
};

Generated Methods

Notice that the op1 method defined in the IDL specification presented previously is generated, along with an _op1 method. The op1 method is a pure virtual method and must be implemented by the class you derive from _sk_example.

The _op1 method is called a skeleton and is invoked by the BOA when a client request is received. This method will marshal all the parameters from the request, invoke the op1 method and then marshal the return parameters or exceptions into a response message. The ORB will then send the response to the client application. Skeleton methods should not be explicitly invoked by the server or object implementation.

The constructor and destructor are both protected. The constructor accepts an object name so that multiple objects can be instantiated by a server.

The Class Template

In addition to the _sk_example class, the IDL compiler generates a class template named _tie_example. This template can be used if you wish to avoid the overhead associated with deriving a class from _sk_example. Templates can also be useful for providing a wrapper class for existing applications that cannot be modified to inherit from a new class. The following code listing shows the template class generated by the IDL compiler for the example class.

A template class generated for the example class.

template <class T>
class _tie_example : public example
{
  public:
    _tie_example(T& t, const char *obj_name=(char *)NULL);
    ~_tie_example();
    CORBA::Long op1(CORBA::Char x, CORBA::Short& y);
  private:
    T& _ref;
};

Using the Template

To use the _tie_example template class you must first create your own Example class. The following code listing shows what your Example class might look like. Notice that, unlike most object implementation classes, this Example class does not inherit from the client's example class or any class supplied by ISB for C++.

A class to be used with the _tie_example template.

class Example
{
  public:
    Example();
    CORBA::Long op1(CORBA::Char x, CORBA::Short& y);
};
Given the _tie_example template generated by the IDL compiler and the Example class you defined, the following code example shows the server's main routine.

Using the _tie_example template class.

void main(int argc, char * const *argv)
{
// Initialize ORB and BOA
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_ptr boa = orb->BOA_init(argc, argv);

// Instantiate the Example class
Example myExample;

// Instantiate the template, passing a reference to the example
// object instantiated above and an ORB object instance name.
_tie_example<Example> tieExample(myExample, "test");
boa->impl_is_ready();
};

Interface Attributes

In addition to operations, an interface specification can also define attributes as part of the interface. By default, all attributes are read-write and the IDL compiler will generate two methods; one to set the attribute's value and one to get the attribute's value. You can also specify read-only attributes. These techniques are shown in the following code examples.

IDL specification with two attributes; one read-write and one read-only.

// IDL
interface test
{
attribute long count;
readonly attribute string name;
};
The class generated for the client application.

class test : public virtual CORBA::Object
{
...
// Methods for read-write attribute
virtual CORBA::Long count();
virtual void count(CORBA::Long val);

// Method for read-only attribute.
virtual char * name();
...
};
The class generated for the server.

class _sk_test : public test
{
  virtual CORBA::Long count() = 0;
  virtual void count(CORBA::Long val) = 0;
  virtual char * name() = 0;
};

Oneway methods

The IDL allows you to specify operations that have no return value, called oneway methods. These operations may only have input parameters. When a oneway method is invoked, a request is sent to the server but there is no confirmation from the object implementation that the request was actually received. ISB for C++ uses TCP/IP for connecting clients to servers. This provides guaranteed delivery of all datagrams so the client can be sure the request will be delivered to the server--as long as the server remains available. Still, the client has no way of knowing if the request was actually processed by the object implementation itself.

NOTE: Oneway operations cannot throw exceptions.
Defining a oneway operation.

// IDL
interface oneway_example
{
oneway void set_value(in long val);
};
Code generated for the client application.

class oneway_example : public virtual CORBA::Object
{
virtual void set_value(CORBA::Long val);
...
};
Base class generated for the implementation.

class _sk_oneway_example : public oneway_example
{
virtual void set_value(CORBA::Long val) = 0;
};

Mapping Object References

In addition to generating C++ classes from your interface specification, the IDL compiler will also create object references for your classes. The following code listing shows the object references generated by the IDL compiler.

Object references generated by the IDL compiler.

typedef example *example_ptr;
typedef example_ptr exampleRef;

Interface Inheritance

IDL allows you to specify an interface that inherits from another interface. The C++ classes generated by the IDL compiler will reflect the inheritance relationship. All methods, data type definitions, constants and enumerations declared by the parent interface will be visible to the derived interface.

An example of inheritance in an interface specification.

// IDL
interface parent
{
void operation1();
}

interface child : parent
{
...
long operation2(in short s);
};
The C++ code generated from the previous specification.

...
class parent : public virtual CORBA::Object
{
...
void operation1(CORBA::Environment& _env);
...
};
class child : public virtual parent
{
...
CORBA::Long operation2(CORBA::Short s, CORBA::Environment& _env);
...
};


[Contents] [Previous] [Next]

Last Updated: 02/03/98 15:34:01


Copyright © 1997 Netscape Communications Corporation

Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use