NonStop Software

Object References

Previous Topic | Next Topic | Contents | Index
Getting Started Guide | Administration Guide | Reference Guide

Subtopics

Obtaining Object References
Operations on Object References
Widening and Narrowing Object References

An object reference is an object name that reliably denotes a particular object. An object reference identifies the same object each time the reference is used in a request (subject to certain pragmatic limits of space and time). An object may be denoted by multiple, distinct object references.

A client uses an object reference to invoke methods on a CORBA object. There can be more than one object reference to the same CORBA object. However, an object reference always refers to only one CORBA object.

A CORBA server implements the object and produces the object reference. Once created, object references can be used in various ways. Object reference can be stored in the Naming Service for later use, they can be stringified and stored in a database for later use and they can be passed as parameters to other methods.

NonStop DOM produces and interprets interoperable object references (IORs) as defined by the CORBA specification. NonStop DOM interoperable object references can be interpreted by other ORB implementations and NonStop DOM can interpret IORs produced by other ORBs.

Obtaining Object References

To invoke a method on a CORBA object, you need a reference for the object. Two fundamental ways to obtain an object reference are to:

You can create a string from an object reference; the result is called a stringified object reference. You can also do the reverse: create an object reference from a stringified reference. A stringified object reference is a textual form that can be stored in a file.

For the receiving an object reference from a method invocation, there are a few commonly used techniques:

Working With Stringified Object References

Because an object reference is opaque and may differ from one ORB to another, the object reference itself is not a convenient value for storing references to objects in persistent storage or communicating references by means other than invocation. Two problems must be solved: allowing an object reference to be turned into a value that a client can store in some other medium, and ensuring that the value can subsequently be turned into the appropriate object reference.

The following ORB interface functions are provided to help store and retrieve object references:

A NonStop DOM program, often a server, uses object_to_string( ) as follows:

char* refStr = orb->object_to_string(CORBAObject);

Here the <CORBAObject> variable holding an object reference. The result is a stringified object reference that can, for example, be written to file. The calling program must use the CORBA::string_free to free the string memory after it is no longer needed.

A NonStop DOM program, often a client, uses string_to_object( ) as follows:

CORBA::Object_var CORBAObject = 
  CORBA::string_to_object(refStr);

Here the <refStr> variable holds a stringified object reference. The result is a CORBA object reference.

Working With Returned Object References

This topic provides two subtopics:

Object References Produced by Methods

An object reference can be obtained as a result from a method invocation. The method signature in the IDL specification specifies an out, inout, or return value that is an object. The type of the object can be an interface name or simply Object.

Once an object reference is obtained it can be used to invoke methods on the object.

Object References Produced by the Naming Service

The NonStop DOM Naming Service provides a mechanism to obtain an object reference. Given a name specification, the Naming Service resolve( ) method retrieves a stored object reference. The Naming Service stores object references of any type. Therefore, a client program usually must narrow the object reference before it can be used. See Widening and Narrowing Object References for details on narrowing.

Operations on Object References

This section discusses the following types of operations:

Duplicating an Object Reference

Your application can use the _duplicate( ) method to copy an object reference. This method typically is used when the holder of an object reference wants to provide an object reference to a requester while retaining the capability to use it. For example, if an object's method produces an object reference return value, it should use _duplicate( ) if you want to use the object reference later.

CORBA::Object_ptr Account2 = CORBA::Object::_duplicate(<Account>);

Given a valid object reference, _duplicate( ) returns a reference to the same object. If the given object reference is nil, the _duplicate( ) method returns a nil object reference. The object returned by this call should be freed using CORBA::release( ) or should be assigned to CORBA::Object_var for automatic destruction.


Note: The object implementation is not involved in creating the duplicate, and that the implementation cannot distinguish whether the original or a duplicate was used in a particular request.


Obtaining nil Object References

You can obtain a nil object reference using the _nil( ) method.

A_ptr aPtr = A::_nil( );

The method returns a NULL value of type Object_ptr.

Checking for a nil Object Reference

To test whether a given object reference is nil, use the static method CORBA::is_nil( ). This method returns TRUE if the given object reference is nil and FALSE otherwise. The object implementation is not involved in the nil test.

if (CORBA::is_nil(aPtr))
    return;

Releasing an Object Reference

When an object reference is no longer needed by a program, its storage may be reclaimed by use of the release operation. Note that the object implementation is not involved, and that neither the object itself nor any other references to it are affected by the release operation. See the following example.

CORBA::release(Account);

Checking for Equivalent Object References

To test whether two object references represent the same object, use the _is_equivalent( ) method. This method returns TRUE if the given object reference represents the same object as the object on which the method is invoked.

CORBA::Object_ptr account2 = CORBA::Object::_duplicate(account1);
CORBA::Boolean b = account1->_is_equivalent(account2);

In this example the value returned by _is_equivalent( ) is TRUE because _duplicate( ) creates a copy of an object reference.

Determining Whether an Object Exists

The object denoted by an object may have ceased to exist. The object might have been explicitly deleted or it might be a transient object whose server has restarted. To test whether the object still exists, use the _non_existent( ) method. It returns TRUE (rather than raising CORBA::OBJECT_NOT_EXIST) if the ORB knows authoritatively that the object does not exist; otherwise, it returns FALSE.

if (aPtr->_non_existent())
    return;

Checking the Type of an Object Reference

To determine whether an object reference is an instance of a particular class, use the _is_a( ) method. This method is used to determine if an object is an instance of the Repository type that you specify in the logical_type_id parameter. It facilitates maintaining type-safety for object references over the scope of an ORB. It returns TRUE if the object is an instance of the specified type or if the object is an ancestor of the most derived type of that object.

CORBA::Boolean ab = account1->_is_a("Account");

Widening and Narrowing Object References

Consider the following outline of IDL interface definitions:

interface Account {
// . . . . . 
};

interface Savings: Account {
// . . . .
};

interface Checking: Account {
// . . . .
};

Here both the Savings and Checking interfaces inherit from the Account interface. The IDL compiler produces corresponding C++ classes named Account, Savings, and Checking. The inheritance relationship is maintained. So a Savings object is also an Account object. Similarly a Checking object is also an Account object. A given Account object may or may not be a Savings object. We will use these classes in the following sections.

Widening Object References

As is normal in object-oriented systems, if you have a reference to a Savings object, you can assign it to a reference of type Account. Moving from a derived interface to a base interface is termed widening in CORBA (C++ refers to this as upcast).

For example given the following objects, you can make assignments as shown:

Savings_ptr pSavings = [a valid savings object];
Checking_ptr pChecking = [a valid checking object];
Account_ptr pAccount;
CORBA::Object_ptr pObject;

pAccount = pSavings;
pObject = pChecking;

Narrowing Object References

The term narrowing is used in CORBA when moving from a base interface to a derived interface (C++ refers to this as downcast). If you have a base interface reference, you can assign it to a reference to a derived interface, but only if the base reference actually references an instance of the derived interface. There is no way to statically determine whether this condition holds, so there must be a runtime test to determine the safety of the assignment.

Here are some examples showing successful and unsuccessful narrowing:

pSavings = Savings::_narrow(pAccount); 
if (!CORBA::_is_nil(pSavings))
{  /* pAccount did reference a Savings object */ }
else
{ /* the narrow failed */ }

Assuming you have made the assignments shown previously, _narrow( ) will be successful because <pAccount> does hold a Savings object.

pSavings = Savings::_narrow(pObject);
if (!CORBA::_is_nil(pSavings))
{ /* pObject did reference a Savings */ }
else { /* the narrow failed */ )

In this case, _narrow( ) produces nil because <pObject> was originally assigned a Checking object reference.

A successful call to _narrow( ) returns a new object reference to the given object. When you no longer need the object, you must release the object reference returned by the _narrow( ) method.

The static function _narrow( ) returns a nil object reference if the parameter passed to it is not a reference to an object of the correct interface, or a derived interface. The _narrow( ) method can also raise an exception, so your code should include an exception handler.


Previous Topic | Next Topic | Contents | Top
Getting Started Guide | Administration Guide | Reference Guide
Bibliography | Glossary | Index
© Tandem, a division of Compaq. All rights reserved. Legal notices.