The IDL Compiler
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. Figure 10-1 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.
The following figure shows 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. Figure 10-2 shows an IDL specification for an object named example
. The example
object has only one method, op1
.
// IDL specification for the example objectinterface example
{
long op1(in char x, out short y);
};
example
class in C++ that the client will use. Files generated by the IDL compiler always have either a ".cc" or ".hh" suffix to make them easy to distinguish from file you create yourself.Caution: You should not modify the contents of the files generated by the IDL compiler.
The following example shows the
example
class generated in ex_client.hh.
class example : public virtual CORBA::Object{
private:
// Methods used internally by VisiBroker to store type information
...
public:
// More methods used internally by VisiBroker 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);
};
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.
Since 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 VisiBroker for C++ Reference Guide.
The _ptr Definition
The IDL compiler always provides a pointer type definition. Figure 10-4shows the type definition for the example class.
typedef example *example_ptr;
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
.
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:
...
};
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 following example shows 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);
};
op1
method defined in the IDL specification in Figure 10-2 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 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 example shows the template class generated by the IDL compiler 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;
};
_tie_example
template class you must first create your own Example
class. The following example 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 VisiBroker.
class ExampleGiven the _tie_example template generated by the IDL compiler and the Example class you defined, the following example shows the server's main routine.{
public:
Example();
CORBA::Long op1(CORBA::Char x, CORBA::Short& y);
};
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();
return(1);
};
The following example shows the class definition generated for the object implementation.
// IDLThe following example shows the resulting class definition generated by the IDL compiler for the client application.interface test
{
attribute long count;
readonly attribute string name;
};
class test : public virtual CORBA::ObjectThe following example shows the class generated for the server.{
...
// Methods for read-write attribute
virtual CORBA::Long count();
virtual void count(CORBA::Long val);
// Method for read-only attribute.
virtual char * name();
...
};
class _sk_test : public test{
virtual CORBA::Long count() = 0;
virtual void count(CORBA::Long val) = 0;
virtual char * name() = 0;
};
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. VisiBroker 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.
// IDLThe following example shows the code generated for the client application.interface oneway_example
{
oneway void set_value(in long val);
};
class oneway_example : public virtual CORBA::ObjectThe following example shows the base class generated for the implementation.{
virtual void set_value(CORBA::Long val);
...
};
class _sk_oneway_example : public oneway_example{
virtual void set_value(CORBA::Long val) = 0;
};
typedef example *example_ptr;
typedef example_ptr exampleRef;
// IDLThe following example shows the C++ code generated from the preceding example.interface parent
{
void operation1();
}
interface child : parent
{
...
long operation2(in short s);
};
...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);
...
};