Interface and Object Names
Operations on Object References
Widening and Narrowing Object References
Interface and Object Names
When you define an object's interface in an IDL specification, you must give it an interface name. For example, the library object introduced in Chapter 2 was given the name "library" in the IDL specification.
interface library {The interface name is the least specific name by which an object can be identified when a client application invokes the
void add_book();
};
_bind
method. An object name may also be used to further qualify an object. For information on obtaining interface and object names from an object reference, see page 3-14.
Interface Names
You define an object's interface name when you define the object in IDL. The interface name will be registered with the VisiBroker osagent, when the BOA::object_is_ready
method is called by the server that implements the object. The interface name is also the name that client applications will use to bind to an object. Object Names
In addition to the required interface name, you may specify an optional object name when instantiating an object. The VisiBroker IDL compiler generates a NULL
object name as a default parameter. The use of an object name is required if your client application plans to bind to more than one instance of an object at a time. Object names must be assigned at the time an object is registered with the Object Activation Daemon, described in Chapter 4.
Using Qualified Object Names with Servers
Consider the library example from Chapter 2 and imagine that you need to have two library objects available; one for a library at Stanford and one for the Harvard library. You may even want to implement two separate object servers, possibly on different hosts. Each server would instantiate a library object, but each would use the Library
object's constructor that accepts an object name. shows the use of the default constructor. shows the library server changes that you would need to make to create separate library objects for Stanford and Harvard.
The following example shows the default use of an object's constructor:
#include <lib_srv.h>The following example shows specifying an object name when instantiating an object's implementation:int main(int argc, char **argv)
{ // Initialize ORB and Basic Object Adaptor (BOA)
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_var boa = orb->BOA_init(argc, argv);
// Instantiate the Library classLibrary library_server();
orb->obj_is_ready(&library_server);...
};
#include <lib_srv.h>int main(int argc, char **argv)
{ // Initialize ORB and Basic Object Adaptor (BOA)
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_var boa = orb->BOA_init(argc, argv);
// Instantiate Harvard Library classLibrary library_server("Harvard");
...
// Or
// Instantiate the Stanford Library classLibrary library_server("Stanford");
...
orb->obj_is_ready(&library_server);};
NULL
parameter for the object name, by default.Expanding the library example to represent two different libraries will require that you modify the client application's
_bind
invocation to specify a particular library object. shows the original client code used to bind to a default object. shows how you would modify the client application to specify an object name with the _bind
call.
The following example shows tThe use of the
_bind
method without an object name:
...The following example shows the modified// Declare the library object
library *library_object;
try {// Locate object and return a pointer to it
library_object = library::_bind();
} // Check for errors
catch(const CORBA::Exception& excep) { cout << "Error binding to library object" << endl;
return(0);
} ...
_bind
method, using an object name:
...// Declare the library object
library *library_object;
try {
// Locate object and return a pointer to it
library_object = library::_bind("Harvard");
}
// Check for errors
catch(const CORBA::Exception& excep) {
cout << "Error binding to library object" << endl;
return(0);
}
...
_bind
method.Note: Your client application will never call the class' constructor, it will always obtain an object reference using the static
_bind
method.
The following figure shows Client and Server processes on different hosts:
The following figure shows Client and Server processes on the same host.
_bind
method. shows the _bind
method generated for the library interface by the IDL compiler. The default value for all of the parameters is NULL
.class libraryThe interface name specified in the interface specification becomes the name of the class. The use of the{
static library_ptr _bind(
const char *object_name = NULL,
const char *host_name = NULL,
const CORBA::BindOptions* opt = NULL);
...
};
object_name
parameter is discussed on page 3-2.
Host Name
In addition to the object name, your client application can specify a particular host it wishes to use for the object implementation. This can be useful if your application knows that a particular object implementation is located on a particular host. If you do not specify a host name, the ORB will locate a host that meets all of the other bind parameters. BindOptions
Figure 3-1 shows the BindOptions
structure, used for the third parameter to the _bind
method, which enables you to control various aspects of the connection between the client application and the object implementation. If the third parameter is NULL
, the default bind options will be used. Each of the structure's members will be discussed in turn.
struct BindOptions {CORBA::Boolean defer_bind;
CORBA::Boolean enable_rebind;
CORBA::Long max_bind_tries;
CORBA::ULong send_timeout;
CORBA::ULong receive_timeout;
CORBA::ULong connection_timeout;
};
Figure 3-1 TheBindOptions
structure.
defer_bind
to 1
, the _bind
method creates a proxy object (if necessary) and returns an object reference to your client application. A connection will not be established with the object implementation until your client application actually invokes a method on the object. If you set defer_bind to 0
, then the connection will be established when _bind
is invoked.The default behavior is to establish the connection at the time the
_bind
method is invoked.
enable_rebind
to 1
. If you wish to prevent this re-binding process, set enable_rebind
to 0.
The default
_bind
behavior is to attempt to re-bind to the server if an error occurs. Maximum Bind Attempts
Object implementations may be registered with the Object Activation Daemon, described in Chapter 4, so that an object server process is automatically launched when your client binds to the object. You can set max_bind_tries
to specify the number of attempts the oad should make to launch the server process.
The default
oad
behavior is to make no more than five attempts to launch a server process. Send Time-outs
You set send_timeout
to specify the number of seconds your client application will wait for a request to be delivered to an object server. If the time-out period expires before the message is delivered to the object server, a CORBA::NO_RESPONSE
exception is raised. send_timeout
is set to 0, which indicates that your client application wishes to block indefinitely. Receive Time-outs
You set receive_timeout
to specify the number of seconds your client application will wait for a response to be received from an object server. If the time-out period expires before the message is received from the object server, a CORBA::NO_RESPONSE
exception is raised.receive_timeout
is set to 0, which indicates that your client application wishes to block indefinitely. Connection Time-outs
You set the connection_timeout
option to specify the number of seconds your client application will wait for a connection to be established with an object server. If the time-out period expires before a connection is established, a CORBA::NO_IMPLEMENT
exception is raised.connection_timeout
is set to 0 to indicate that your client application wishes to use the default connection time-out. Scope of BindOptions
VisiBroker allows you to specify three distinct levels of BindOptions. You can specify the options for each invocation of the _bind method, for a particular object reference or for all invocations of _bind by your client application. Process-Level BindOptions
VisiBroker provides a global BindOptions structure that contains default values for the _bind method. These defaults are used if you do not explicitly specify a BindOptions
parameter when you invoke the _bind method. The following example shows the static methods you can use to query and set these defaults.
class Object {static const BindOptions *_default_bind_options();
static void _default_bind_options(const BindOptions&);
...
};
BindOptions
parameter when you invoke the _bind
method.These new options will remain in effect for the life of the object reference returned by _bind
, regardless of any changes to the process-level bind options.
_bind
method. shows a method you can use on the object reference returned by _bind
. This method allows you to change send and receive time-out values for any valid object reference. If you change the connection time-out and a re-bind occurs, the new connection time-out value will be apply. The bind options you set remain in effect for this object reference for as long as the reference is valid.
The following example shows the method for setting object-level bind options:
class Object {...
void _bind_options(const CORBA::BindOptions& opt);
...
};
_bind
method represents an ORB object. Your client application can use the object reference to invoke methods on the object that have been defined in the object's IDL interface specification. In addition, there are methods that all ORB objects inherit from the class CORBA::Object
that you can use to manipulate the object.
1
if the object reference passed is nil. It returns 0
if the object reference is not nil.The following example shows the method for checking for a nil object reference:
class CORBA {...
static Boolean _nil(Object_ptr obj);
...
CORBA::Object
method shown. It returns a NULL
value that is cast to an Object_ptr
.
class Object {...
static Object_ptr _nil();
...
};
_duplicate
method to copy an object reference so that the copy can be stored in a data structure or passed as a parameter. When this method is invoked, the reference count for the object reference is incremented by one and the same object reference is returned to the caller.The IDL compiler generates a
_duplicate
method for each object interface you specify. The _duplicate
method shown accepts and returns a generic Object_ptr
.
class Object {...
static Object_ptr _duplicate(Object_ptr obj);
...
};
};
CORBA::Object
class method _release
.
class CORBA {You may also use theclass Object {
...
void _release();
...
};
};
CORBA
class method _release
, which is provided for compatibility with the CORBA specification.
class CORBA {...
static void release();
...
};
_bind
, the reference count is set to one. Releasing an object reference will decrement the reference count by one. Once the reference count reaches 0, VisiBroker automatically deletes the object reference. Figure 3-17 shows the method for retrieving the reference count.
class Object {...
ULong _ref_count() const;
...
};
_clone
method for each object interface that you specify. Unlike the _duplicate method, _clone will create an exact copy of the object's entire state and establish a new, separate connection to the object implementation. The object reference returned and the original object reference will represent two distinct connections to the object implementation. Figure 3-18 shows the _clone
method generated for the library interface introduced in Chapter 2.
class library: public virtual CORBA::ObjectPlatforms that support multi-threaded client applications may increase their performance by cloning an object reference for each by each thread that is created to access a particular object. See Chapter 8 for information on multi-threaded applications.{
public:
...
library_ptr _clone();
...
};
Converting a Reference to a String
Object references are opaque and can vary from one ORB to another, so VisiBroker provides an ORB class with methods that allow you to convert an object reference to a string as well as convert a string back into an object reference. The CORBA specification refers to this process as "stringification." Figure 3-19 shows these conversion methods.
Note: Only object references representing persistent objects can be converted to a string. Any attempt to convert a transient object reference to a string will fail. Use the
_is_persistent
method to ensure that an object reference represents a persistent object before calling the object_to_string
method.
class ORB {public:
// Convert an object reference to a string
char *object_to_string(Object_ptr obj);
// Convert a char * to an object reference
Object_ptr string_to_object(const char *);
...
};
Object
class that you can use to obtain the interface and object names as well as the repository id associated with an object reference. The interface repository is discussed in Chapter 9 of this guide.
class Object {...
const char *_interface_name() const;
const char *_object_name() const;
const char *_repository_id() const;
...
};
_is_a
method. You must first obtain the repository id of the type you wish to check using the _repository_id
method. This method returns 1
if the object is either an instance of the type represented by repository_id
or if it is a sub-type. 0
is returned if the object is not of the type specified.
class Object {shows the...
Boolean _is_a(const char *repository_id);
...
};
_is_equivalent
method which you can use to check if two object references are equivalent. This method returns 1
if the references are equivalent. This method returns 0 if the references are not identical.
The following example shows the method for comparing object references.
class Object {You can use the...
Boolean _is_equivalent(Object_ptr other_object);
...
};
_hash
method shown in Figure 3-23 to obtain a hash value for an object reference. While this value is not guaranteed to be unique, it will remain consistent through the lifetime of the object reference.
class Object {...
ULong _hash(ULong maximum);
...
};
1
if the object is bound and 0
if the object is not bound.
The following example shows the method for querying the state of the bind for an object reference.
class Object {shows two methods your client application can use after a successfulpublic:
...
Boolean _is_bound() const;
...
};
_bind
invocation to determine the location of the object implementation.
The following example shows methods for determining the location of an object implementation:
class Object {Note: If the referred object is in the same process,virtual Boolean _is_local() const;
Boolean _is_remote() const;
...
};
_is_local
returns TRUE.
class Object {...
const CORBA::BindOptions _bind_options() const;
...
};
library
pointer to an Object
pointer. The pointer lib
can be cast as an Object
pointer because the library
class inherits from the Object
class.
library *lib;The process of converting an object reference's type from a general super-type to a more specific sub-type is called narrowing. VisiBroker maintains a typegraph for each object interface so that narrowing can be accomplished by the object's
Object *obj;
lib = library::_bind();
obj = (Object *)lib;
_narrow
method. If the _narrow
method determines it is not possible to narrow an object to the type you request, it will return NULL
.
library *lib;The
library *libtwo;
Object *obj;
lib = library::_bind();
obj = (Object *)lib;
libtwo = library::_narrow(obj);
_narrow
method constructs a new C++ object and returns a pointer to that object. When you no longer need the object, you must release the object reference returned by _narrow
as well as the object reference you passed as an argument.