To use an instance of the MyObject_impl servant class to incarnate a CORBA object, you must create a MyObject_impl servant, create a CORBA object, and register the servant as the incarnation of the CORBA object. Note that merely creating a C++ servant does not imply the creation of a CORBA object; each of the two entities has its own separate, distinct lifetime.
To keep things simple, the following example shows the easiest way to simultaneously create both a C++ servant and a new CORBA object incarnated by that servant:
// First create a servant instance.
MyObject_impl servant(42);
// Next, create a new CORBA object and use our new servant
// to incarnate it.
MyObject_var object = servant._this();
The first line of code creates the servant instance and sets its value to 42. At this point, all we have is a C++ object—no connections between the servant and any CORBA objects have yet been made. The simple appearance of the second line of code is misleading. This invocation of the _this function of servant implicitly performs all the following steps:
Creates a CORBA object under the Root POA
Registers servant with the Root POA as the implementation for the new object
Creates an object reference for the new object
Returns the new object reference
The _this function is supplied by the skeleton class. The following code again shows the generated POA_MyObject class, but this time we have included the _this member function that is generated by the IDL compiler:
class POA_MyObject : public virtual PortableServer::ServantBase{
public:
virtual CORBA::Long get_value()
throw(CORBA::SystemException) = 0;
MyObject_ptr _this();
// ...
};
For any skeleton class POA_A representing IDL interface A, the return value of the POA_A::_this function is A_ptr, the C++ object reference type for interface A.
Accordingly, in the preceding example, the return type of _this is MyObject_ptr.
Because the caller of _this is responsible for ensuring that CORBA::release is eventually invoked on the returned object reference, we have assigned the return value to a MyObject_var in our example on page 355.
Under these circumstances, the CORBA object created by _this is a transient object. A transient CORBA object is bounded by the lifetime of the POA in which it is created. However, _this can provide this form of creation and registration service only if the servant's POA was created with the appropriate policies. The standard set of policies supported by the Root POA were explicitly designed to allow _this to be used in this manner.
A completely operational server main, and it works as follows.
Step 1.
We initialize an ORB via the standard CORBA::ORB_init call.
Step 2.
We use the ORB reference returned by ORB_init to invoke resolve_initial_references, which allows you to obtain object
references to a small number of well-known interfaces. We use
it to get a reference to the Root POA for the ORB, which we in
turn use to get a reference to the POAManager for the Root POA.
Activating the POAManager allows the Root POA to start processing
requests as soon as the ORB starts listening for them.
Step 3.
We create a servant of type MyObject_impl.
Step 4.
We invoke the _this function of the servant to create a new transient CORBA object and incarnate it with the servant. Then we store the returned object reference into a IT-SC book: Advanced CORBA® Programming with C++
320 MyObject_var so that it will automatically be released when the MyObject_var
goes out of scope.
Step 5.
To make the object reference for our new CORBA object available to potential clients, we convert it to a string by passing it to the ORB's object_to_string function. We assign the string returned by this function to a String_var to ensure its cleanup, and we then write it to the application's standard output.
Step 6.
We invoke the ORB::run operation to make the ORB start listening for requests.
The conversion of the object reference to a string (detailed in Section 7.10) al lows clients to obtain the object reference in order to be able to invoke requests on the object. Of course, production applications would never advertise their object references in this manner, instead relying on object reference discovery services such as Naming (see Chapter 18) or Trading (see Chapter 19). However, the string conversion approach suffices for our simple example. A production application would also set up try and catch blocks to handle errors, but we have elided these to keep the example as simple as possible.
阅读(2058) | 评论(0) | 转发(0) |