Programming CORBA with Orbacus on Linux
Get references to server objects
Converting a stringified reference
The method
CORBA::Object_ptr CORBA::ORB::string_to_object(str)
of the ORB converts a stringified reference back to an object. The method may return a nil
reference if the stringified reference was correct, but did not point to a server
object, or raise some exceptions: TRANSIENT, if the server could not be reached,
BAD_PARAM if the stringified reference was syntactically wrong, or another
system exception.
A typical usage is the following:
try {
CORBA::Object_var obj = orb->string_to_object(strIOR);
if (CORBA::is_nil(obj){
<handle this error>
}
// do something with the object, typically it is narrowed down
X_var x = X::_narrow(obj);
if (CORBA::is_nil(x){
<handle this error>
}
<do something with the resulting object>
} catch (const CORBA::TRANSIENT& e){
// the server is not reachable
} catch (const CORBA::BAD_PARAM& e){
// the strIOR reference was wrong
} catch (const CORBA::SystemException& e){
// something was wrong
}
After succesfully getting the initial reference for object "ObjectName", the reference
is typically narrowed down to some type like PortableServer::POA or a user-defined type as
X. These narrowed references are subsequently used.
The stringified references can be transferred from server to the client by storing them in
ordinary files, sending via email or using other methods. The simplest method is to store them
in files, which is shown in the next section.
Stringified references in files
It is possible to store stringified references in a file system, to which both client and
server have access. The server stores the reference in a well-known file, the client retrieves
it via the special resolving method relfile::
CORBA::Object_ptr CORBA::ORB::string_to_object("relfile:/<filename>")
An example for retrieving a server reference via a file-based IOR is given
here.
Initial references
The method
resolve_initial_references()
may return a nil reference if the name specified was valid, but did not point to a
valid reference. If the name specification itself was syntactically wrong, a
CORBA::ORB::InvalidName exception is thrown. A CORBA::SystemException may be
thrown if the service could not be contacted. You use this method typically
as follows:
try {
CORBA::Object_var obj = orb->resolve_initial_references("ObjectName")
if (CORBA::is_nil(obj)){
<handle this error>
}
// do something with the object, typically it is narrowed down
X_var x = X::_narrow(obj);
<do something with the resulting object>
} catch (const CORBA::ORB::InvalidName& e){
// the "ObjectName" specification was wrong
} catch (const CORBA::SystemException& e){
// something else was wrong
}
After succesfully getting the initial reference for object "ObjectName", the reference
is typically narrowed down to some type like PortableServer::POA or a user-defined type as
X. These narrowed references are subsequently used.
References for certain services as 'RootPOA' are available automatically; for others, you
will have to specify how to resolve the symbolic reference. AS example, when using the COsEvent
service, refrences to the default event channel and the (proprietary) channel factory have
to be explicitly specified, e.g. as follows:
char strRef[100], strRef1[100];
char* strHost = "adrasteia";
char* strPort = "3860";
sprintf(strRef, "EventService=corbaloc:iiop:%s:%s/DefaultEventChannel",
strHost, strPort);
sprintf(strRef1, "EventChannelFactory=corbaloc:iiop:%s:%s/DefaultEventChannelFactory",
strHost, strPort);
char* orb_options[] = { "-ORBInitRef", strRef, "-ORBInitRef", strRef1 };
int optc = sizeof(orb_options)/sizeof(char *);
try {
m_oORB = CORBA::ORB_init(optc, orb_options);
} catch (const CORBA::SystemException& e){
cerr << "error initializing ORB: " << e << endl;
}
The example code assumes that the event service was started at host 'adrasteia' on port 3860. This
can be done with
adrasteia$ eventserv -OAport 3860
You specify in your program how to find this service. The options are hard-coded in the example
code, but can also be specified as command-line arguments, if you initialize your ORB with
argc and argv.
Locating server objects with CORBALOC
The method string_to_object allows a special syntax to resolve references,
which are not stringified, but registered by the server with CORBALOC. To
use CORBALOC, you do not use a filename, but a string of the structure
corbaloc::iiop:<hostname>:<port>/<server object name>
Host and port are data of the host on which the server object is available, the name
of the server object is given by the server running the object.
The typical use of CORBALOC resolving is as follows:
X_var server;
try {
CORBA::String_var strIOR = CORBA::string_dup("corbaloc:iiop:");
strIOR += strHost;
strIOR += ":";
strIOR += strPort;
strIOR += "/Serverobjectname";
CORBA::Object_var oServer = orb->string_to_object(strIOR);
if (CORBA::is_nil(oServer)){
// handle error
}
server = X::_narrow(oServer);
if (CORBA::is_nil(server)){
// handle error
}
} catch (const CORBA::TRANSIENT& e) {
// handle error: server not reachable
} catch (const CORBA::BAD_PARAM& e) {
// handle error: wrong CORBALOC syntax
} catch (const CORBA::SystemException& e) {
// handle error: anything else
}
An example using CORBALOC can be found here.
Checking for existence
The method
_non_existent()
allows you to check if the reference on which it is invoked points to an existing object
or not. The result is definitive true, if the reference dangles. A result of false indicate
either that the server object does not exist or cannot be contacted to check the existence!
For that, the method may throw system exceptions. A typical usage is the following:
X_ptr xp = <get reference from somewhere>
try {
if (xp->non_existent()){
// definitive answer, release resources
CORBA::release(xp);
} else {
// try to use reference
xp->f();
}
} catch (const CORBA::TRANSIENT&) {
} catch (const CORBA::SystemException&) {
}
back to CORBA page
|