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 {
void add_book();
};
The interface name is the least specific name by which an object can be identified when a client application invokes the _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 The BindOptions 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 {
class Object {
...
void _release();
...
};
};
You may also use the 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 {
...
Boolean _is_a(const char *repository_id);
...
};
shows the _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 {
...
Boolean _is_equivalent(Object_ptr other_object);
...
};
You can use the _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 {
public:
...
Boolean _is_bound() const;
...
};
shows two methods your client application can use after a successful _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 {
virtual Boolean _is_local() const;
Boolean _is_remote() const;
...
};
Note: If the referred object is in the same process, _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.