Sophie

Sophie

distrib > Mandriva > 2010.1 > x86_64 > by-pkgid > a5b20f7ff89b16488de4451524d040ed > files > 21

omniorb-doc-4.1.4-3mdv2010.1.x86_64.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>

<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<META name="GENERATOR" content="hevea 1.10">
<LINK rel="stylesheet" type="text/css" href="omniORB.css">
<TITLE>Type Any and TypeCode</TITLE>
</HEAD>
<BODY >
<A HREF="omniORB010.html"><IMG SRC="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC="contents_motif.gif" ALT="Up"></A>
<A HREF="omniORB012.html"><IMG SRC="next_motif.gif" ALT="Next"></A>
<HR>
<H1 CLASS="chapter"><A NAME="htoc118">Chapter&#XA0;11</A>&#XA0;&#XA0;Type Any and TypeCode</H1><P>
<A NAME="chap:any"></A></P><P>The CORBA specification provides for a type that can hold the value of
any OMG IDL type. This type is known as type Any. The OMG also
specifies a pseudo-object, TypeCode, that can encode a description of
any type specifiable in OMG IDL.</P><P>In this chapter, an example demonstrating the use of type Any is
presented. This is followed by sections describing the behaviour of
type Any and TypeCode in omniORB. For further information on type
Any, refer to the C++ Mapping specification., and for more information
on TypeCode, refer to the Interface Repository chapter in the CORBA
core section of the CORBA specification.</P><H2 CLASS="section"><A NAME="toc51"></A><A NAME="htoc119">11.1</A>&#XA0;&#XA0;Example using type Any</H2><P>Before going through this example, you should make sure that you have
read and understood the examples in chapter&#XA0;<A HREF="omniORB002.html#chap:basic">2</A>. The
source code for this example is included in the omniORB distribution,
in the directory <TT>src/examples/anyExample</TT>. A listing of the
source code is provided at the end of this chapter.</P><H3 CLASS="subsection"><A NAME="htoc120">11.1.1</A>&#XA0;&#XA0;Type Any in IDL</H3><P>
Type Any allows one to delay the decision on the type used in an
operation until run-time. To use type any in IDL, use the keyword
<TT>any</TT>, as in the following example:</P><DIV CLASS="lstlisting"><I>// IDL</I>
<B>interface</B> anyExample {
  <B>any</B> testOp(<B>in</B> <B>any</B> mesg);
};</DIV><P>The operation <TT>testOp()()</TT> in this example can now take any
value expressible in OMG IDL as an argument, and can also return any
type expressible in OMG IDL.</P><P>Type Any is mapped into C++ as the type <TT>CORBA::Any</TT>. When passed
as an argument or as a result of an operation, the following rules
apply:</P><TABLE CELLSPACING=6 CELLPADDING=0><TR><TD ALIGN=left NOWRAP><B>In </B></TD><TD ALIGN=left NOWRAP><B>InOut </B></TD><TD ALIGN=left NOWRAP><B>Out </B></TD><TD ALIGN=left NOWRAP><B>Return </B></TD></TR>
<TR><TD CLASS="hbar" COLSPAN=4></TD></TR>
<TR><TD ALIGN=left NOWRAP><TT>const CORBA::Any&amp; </TT></TD><TD ALIGN=left NOWRAP><TT>CORBA::Any&amp; </TT></TD><TD ALIGN=left NOWRAP><TT>CORBA::Any*&amp; </TT></TD><TD ALIGN=left NOWRAP><TT>CORBA::Any* </TT></TD></TR>
</TABLE><P>So, the above IDL would map to the following C++:</P><DIV CLASS="lstlisting"><I>// C++</I>

<B>class</B> anyExample_i : <B>public</B> <B>virtual</B> POA_anyExample {
<B>public</B>:
  anyExample_i() { }
  <B>virtual</B> ~anyExample_i() { }
  <B>virtual</B> CORBA::Any* testOp(<B>const</B> CORBA::Any&amp; a);
};</DIV><H3 CLASS="subsection"><A NAME="htoc121">11.1.2</A>&#XA0;&#XA0;Inserting and Extracting Basic Types from an Any</H3><P>The question now arises as to how values are inserted into and removed
from an Any. This is achieved using two overloaded operators:
<TT>&lt;&lt;=</TT> and <TT>&gt;&gt;=</TT>.</P><P>To insert a value into an Any, the <TT>&lt;&lt;=</TT> operator is used, as
in this example:</P><DIV CLASS="lstlisting"><I>// C++</I>
CORBA::Any an_any;
CORBA::Long l = 100;
an_any &lt;&lt;= l;</DIV><P>Note that the overloaded <TT>&lt;&lt;=</TT> operator has a return
type of <TT>void</TT>.</P><P>To extract a value, the <TT>&gt;&gt;=</TT> operator is used, as in this
example (where the Any contains a long):</P><DIV CLASS="lstlisting"><I>// C++</I>
CORBA::Long l;
an_any &gt;&gt;= l;

cout &lt;&lt; "This is a long: " &lt;&lt; l &lt;&lt; endl;</DIV><P>The overloaded <TT>&gt;&gt;=</TT> operator returns a <TT>CORBA::Boolean</TT>.
If an attempt is made to extract a value from an Any when it contains
a different type of value (e.g. an attempt to extract a long from an
Any containing a double), the overloaded <TT>&gt;&gt;=</TT> operator will
return False; otherwise it will return True. Thus, a common tactic to
extract values from an Any is as follows:</P><DIV CLASS="lstlisting"><I>// C++</I>
CORBA::Long l;
CORBA::Double d;
<B>const</B> <B>char</B>* str;

<B>if</B> (an_any &gt;&gt;= l) {
  cout &lt;&lt; "Long: " &lt;&lt; l &lt;&lt; endl;
}
<B>else</B> <B>if</B> (an_any &gt;&gt;= d) {
  cout &lt;&lt; "Double: " &lt;&lt; d &lt;&lt; endl;
}
<B>else</B> <B>if</B> (an_any &gt;&gt;= str) {
  cout &lt;&lt; "String: " &lt;&lt; str &lt;&lt; endl;
  <I>// The storage of the extracted string is still owned by the any.</I>
}
<B>else</B> {
  cout &lt;&lt; "Unknown value." &lt;&lt; endl;
}</DIV><H3 CLASS="subsection"><A NAME="htoc122">11.1.3</A>&#XA0;&#XA0;Inserting and Extracting Constructed Types from an Any</H3><P>It is also possible to insert and extract constructed types and object
references from an Any. omniidl will generate insertion and extraction
operators for the constructed type. Note that it is necessary to
specify the <TT>-WBa</TT> command-line flag when running omniidl in
order to generate these operators. The following example illustrates
the use of constructed types with type Any:</P><DIV CLASS="lstlisting"><I>// IDL</I>
<B>struct</B> testStruct {
  <B>long</B> l;
  <B>short</B> s;
};

<B>interface</B> anyExample {
  <B>any</B> testOp(<B>in</B> <B>any</B> mesg);
};</DIV><P>Upon compiling the above IDL with <TT>omniidl -bcxx -Wba</TT>, the
following overloaded operators are generated:</P><OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
<CODE>void operator&lt;&lt;=(CORBA::Any&amp;, const testStruct&amp;)</CODE>
</LI><LI CLASS="li-enumerate"><CODE>void operator&lt;&lt;=(CORBA::Any&amp;, testStruct*)</CODE>
</LI><LI CLASS="li-enumerate"><CODE>CORBA::Boolean operator&gt;&gt;=(const CORBA::Any&amp;,</CODE><BR>
 <CODE>const testStruct*&amp;)</CODE>
</LI></OL><P>Operators of this form are generated for all constructed types, and
for interfaces.</P><P>The first operator, <EM>(1)</EM>, copies the constructed type, and
inserts it into the Any. The second operator, <EM>(2)</EM>, inserts the
constructed type into the Any, and then manages it. Note that if the
second operator is used, the Any consumes the constructed type, and
the caller should not use the pointer to access the data after
insertion. The following is an example of how to insert a value into
an Any using operator <EM>(1)</EM>:</P><DIV CLASS="lstlisting"><I>// C++</I>
CORBA::Any an_any;

testStruct t;
t.l = 456;
t.s = 8;

an_any &lt;&lt;= t;</DIV><P>The third operator, <EM>(3)</EM>, is used to extract the constructed
type from the Any, and can be used as follows:</P><DIV CLASS="lstlisting"><B>const</B> testStruct* tp;

<B>if</B> (an_any &gt;&gt;= tp) {
    cout &lt;&lt; "testStruct: l: " &lt;&lt; tp-&gt;l &lt;&lt; endl;
    cout &lt;&lt; "            s: " &lt;&lt; tp-&gt;s &lt;&lt; endl;
}
<B>else</B> {
    cout &lt;&lt; "Unknown value contained in Any." &lt;&lt; endl;
}</DIV><P>As with basic types, if an attempt is made to extract a type from an
Any that does not contain a value of that type, the extraction
operator returns False. If the Any does contain that type, the
extraction operator returns True. If the extraction is successful, the
caller&#X2019;s pointer will point to memory managed by the Any. The caller
must not delete or otherwise change this storage, and should not use
this storage after the contents of the Any are replaced (either by
insertion or assignment), or after the Any has been destroyed. In
particular, management of the pointer should not be assigned to a
<TT>_var</TT> type.</P><P>If the extraction fails, the caller&#X2019;s pointer will be set to point to
null.</P><P>Note that there are special rules for inserting and extracting arrays
(using the <TT>_forany</TT> types), and for inserting and extracting
bounded strings, booleans, chars, and octets. Please refer to the C++
Mapping specification for further information.</P><H2 CLASS="section"><A NAME="toc52"></A><A NAME="htoc123">11.2</A>&#XA0;&#XA0;Type Any in omniORB</H2><P>
<A NAME="anyOmniORB"></A></P><P>This section contains some notes on the use and behaviour of type Any
in omniORB.</P><H3 CLASS="subsection"><A NAME="htoc124">11.2.1</A>&#XA0;&#XA0;Generating Insertion and Extraction Operators.</H3><P>
To generate type Any insertion and extraction operators for
constructed types and interfaces, the <TT>-Wba</TT> command line flag
should be specified when running omniidl.</P><H3 CLASS="subsection"><A NAME="htoc125">11.2.2</A>&#XA0;&#XA0;TypeCode comparison when extracting from an Any.</H3><P>
When an attempt is made to extract a type from an Any, the TypeCode of
the type is checked for <EM>equivalence</EM> with the TypeCode of the
type stored by the Any. The <TT>equivalent()</TT> test in the TypeCode
interface is used for this purpose.</P><P>Examples:</P><DIV CLASS="lstlisting"><I>// IDL 1</I>
<B>typedef</B> <B>double</B> Double1;

<B>struct</B> Test1 {
  Double1 a;
};</DIV><DIV CLASS="lstlisting"><I>// IDL 2</I>
<B>typedef</B> <B>double</B> Double2;

<B>struct</B> Test1 {
  Double2 a;
};</DIV><P>If an attempt is made to extract the type <TT>Test1</TT> defined in IDL
1 from an Any containing the <TT>Test1</TT> defined in IDL 2, this will
succeed (and vice-versa), as the two types differ only by an alias.</P><H3 CLASS="subsection"><A NAME="htoc126">11.2.3</A>&#XA0;&#XA0;Top-level aliases.</H3><P>
When a type is inserted into an Any, the Any stores both the value of
the type and the TypeCode for that type. However, in some cases, a
top-level alias can be lost due to the details of the C++ mapping. For
example, consider these IDL definitions:</P><DIV CLASS="lstlisting"><I>// IDL 3</I>
<B>typedef</B> <B>sequence</B>&lt;<B>double</B>&gt; seqDouble1;
<B>typedef</B> <B>sequence</B>&lt;<B>double</B>&gt; seqDouble2;
<B>typedef</B> seqDouble2       seqDouble3;</DIV><P>omniidl generates distinct types for <TT>seqDouble1</TT> and
<TT>seqDouble2</TT>, and therefore each has its own set of C++ operators
for Any insertion and extraction. That means inserting a
<TT>seqDouble1</TT> into an Any sets the Any&#X2019;s TypeCode to include the
alias &#X2018;seqDouble1&#X2019;, and inserting a <TT>seqDouble2</TT> sets the
TypeCode to the alias &#X2018;seqDouble2&#X2019;.</P><P>However, in the C++ mapping, <TT>seqDouble3</TT> is required to be just
a C++ typedef to <TT>seqDouble2</TT>, so the C++ compiler uses the Any
insertion operator for <TT>seqDouble2</TT>. Therefore, inserting a
<TT>seqDouble3</TT> sets the Any&#X2019;s TypeCode to the <TT>seqDouble2</TT>
alias. If this is not desirable, you can use the member function
&#X2018;<TT>void type(TypeCode_ptr)</TT>&#X2019; of the Any interface to explicitly
set the TypeCode to the correct one.</P><H3 CLASS="subsection"><A NAME="htoc127">11.2.4</A>&#XA0;&#XA0;Removing aliases from TypeCodes.</H3><P>
Some ORBs (such as old versions of Orbix) will not accept TypeCodes
containing <TT>tk_alias</TT> TypeCodes. When using type Any while
interoperating with these ORBs, it is necessary to remove
<TT>tk_alias</TT> TypeCodes from throughout the TypeCode representing a
constructed type.</P><P>To remove all <TT>tk_alias</TT> TypeCodes from TypeCodes transmitted in
Anys, supply the <TT>-ORBtcAliasExpand 1</TT> command-line flag when
running an omniORB executable. There will be some (small) performance
penalty when transmitting Any values.</P><P>Note that the <TT>_tc_</TT> TypeCodes generated for all constructed
types will contain the complete TypeCode for the type (including any
<TT>tk_alias</TT> TypeCodes), regardless of whether the
<TT>-ORBtcAliasExpand</TT> flag is set to 1 or not. It is only when
Anys are transmitted that the aliases are stripped.</P><H3 CLASS="subsection"><A NAME="htoc128">11.2.5</A>&#XA0;&#XA0;Recursive TypeCodes.</H3><P>
omniORB supports recursive TypeCodes. This means that types such as
the following can be inserted or extracted from an Any:</P><DIV CLASS="lstlisting"><I>// IDL 4</I>
<B>struct</B> Test4 {
  <B>sequence</B>&lt;Test4&gt; a;
};</DIV><H3 CLASS="subsection"><A NAME="htoc129">11.2.6</A>&#XA0;&#XA0;Threads and type Any.</H3><P>
Inserting and extracting simultaneously from the same Any (in 2
different threads) results in undefined behaviour.</P><P>In versions of omniORB before 4.0, extracting simultaneously from the
same Any (in 2 or more different threads) also led to undefined
behaviour. That is no longer the case&#X2014;Any extraction is now thread
safe.</P><H2 CLASS="section"><A NAME="toc53"></A><A NAME="htoc130">11.3</A>&#XA0;&#XA0;TypeCode in omniORB</H2><P>This section contains some notes on the use and behaviour of TypeCode
in omniORB</P><H3 CLASS="subsection"><A NAME="htoc131">11.3.1</A>&#XA0;&#XA0;TypeCodes in IDL.</H3><P>When using TypeCodes in IDL, note that they are defined in the CORBA
scope. Therefore, <TT>CORBA::TypeCode</TT> should be used. Example:</P><DIV CLASS="lstlisting"><I>// IDL 5</I>
<B>struct</B> Test5 {
  <B>long</B> length;
  CORBA::TypeCode desc;
};</DIV><H3 CLASS="subsection"><A NAME="htoc132">11.3.2</A>&#XA0;&#XA0;orb.idl</H3><P>The CORBA specification says that IDL using <TT>CORBA::TypeCode</TT>
must include the file <TT>orb.idl</TT>. That is not required in omniORB,
but a suitable <TT>orb.idl</TT> is available.</P><H3 CLASS="subsection"><A NAME="htoc133">11.3.3</A>&#XA0;&#XA0;Generating TypeCodes for constructed types.</H3><P>To generate a TypeCode for constructed types, specify the
<TT>-Wba</TT> command-line flag when running omniidl. This will
generate a <TT>_tc_</TT> TypeCode describing the type, at the same
scope as the type. Example:</P><DIV CLASS="lstlisting"><I>// IDL 6</I>
<B>struct</B> Test6 {
  <B>double</B> a;
  <B>sequence</B>&lt;<B>long</B>&gt; b;
};</DIV><P>A TypeCode, <TT>_tc_Test6</TT>, will be generated to describe the
struct <TT>Test6</TT>. The operations defined in the TypeCode interface
can be used to query the TypeCode about the type it represents.</P><H2 CLASS="section"><A NAME="toc54"></A><A NAME="htoc134">11.4</A>&#XA0;&#XA0;Source Listing</H2><H3 CLASS="subsection"><A NAME="htoc135">11.4.1</A>&#XA0;&#XA0;anyExample_impl.cc</H3><DIV CLASS="lstlisting"><I>// anyExample_impl.cc - This is the source code of the example used in</I>
<I>//                      Chapter 9 "Type Any and TypeCode" of the omniORB</I>
<I>//                      users guide.</I>
<I>//</I>
<I>//                      This is the object implementation.</I>
<I>//</I>
<I>// Usage: anyExample_impl</I>
<I>//</I>
<I>//        On startup, the object reference is printed to cout as a</I>
<I>//        stringified IOR. This string should be used as the argument to </I>
<I>//        anyExample_clt.</I>
<I>//</I>

<B>#include</B> &lt;anyExample.hh&gt;

<B>#ifdef</B> HAVE_STD
<B>#  include</B> &lt;iostream&gt;
   <B>using</B> <B>namespace</B> std;
<B>#else</B>
<B>#  include</B> &lt;iostream.h&gt;
<B>#endif</B>

<B>class</B> anyExample_i : <B>public</B> POA_anyExample {
<B>public</B>:
  <B>inline</B> anyExample_i() {}
  <B>virtual</B> ~anyExample_i() {}
  <B>virtual</B> CORBA::Any* testOp(<B>const</B> CORBA::Any&amp; a);
};


CORBA::Any* anyExample_i::testOp(<B>const</B> CORBA::Any&amp; a)
{
  cout &lt;&lt; "Any received, containing: " &lt;&lt; endl;

<B>#ifndef</B> NO_FLOAT
  CORBA::Double d;
<B>#endif</B>

  CORBA::Long l;
  <B>const</B> <B>char</B>* str;

  testStruct* tp;


  <B>if</B> (a &gt;&gt;= l) {
    cout &lt;&lt; "Long: " &lt;&lt; l &lt;&lt; endl;
  }
<B>#ifndef</B> NO_FLOAT
  <I>// XXX - should we provide stream ops for _CORBA_Double_ and</I>
  <I>// _CORBA_Float_on VMS??</I>
  <B>else</B> <B>if</B> (a &gt;&gt;= d) {
    cout &lt;&lt; "Double: " &lt;&lt; (<B>double</B>)d &lt;&lt; endl;
  }
<B>#endif</B>
  <B>else</B> <B>if</B> (a &gt;&gt;= str) {
    cout &lt;&lt; "String: " &lt;&lt; str &lt;&lt; endl;
  }
  <B>else</B> <B>if</B> (a &gt;&gt;= tp) {
    cout &lt;&lt; "testStruct: l: " &lt;&lt; tp-&gt;l &lt;&lt; endl;
    cout &lt;&lt; "            s: " &lt;&lt; tp-&gt;s &lt;&lt; endl;
  }
  <B>else</B> {
    cout &lt;&lt; "Unknown value." &lt;&lt; endl;
  }

  CORBA::Any* ap = <B>new</B> CORBA::Any;

  *ap &lt;&lt;= (CORBA::ULong) 314;

  cout &lt;&lt; "Returning Any containing: ULong: 314\n" &lt;&lt; endl;
  <B>return</B> ap;
}

<I>//////////////////////////////////////////////////////////////////////</I>

<B>int</B> main(<B>int</B> argc, <B>char</B>** argv)
{
  <B>try</B> {
    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

    CORBA::Object_var obj = orb-&gt;resolve_initial_references("RootPOA");
    PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);

    anyExample_i* myobj = <B>new</B> anyExample_i();

    PortableServer::ObjectId_var myobjid = poa-&gt;activate_object(myobj);

    obj = myobj-&gt;_this();
    CORBA::String_var sior(orb-&gt;object_to_string(obj));
    cout &lt;&lt; (<B>char</B>*)sior &lt;&lt; endl;

    myobj-&gt;_remove_ref();

    PortableServer::POAManager_var pman = poa-&gt;the_POAManager();
    pman-&gt;activate();

    orb-&gt;run();
    orb-&gt;destroy();
  }
  <B>catch</B>(CORBA::SystemException&amp; ex) {
    cerr &lt;&lt; "Caught CORBA::" &lt;&lt; ex._name() &lt;&lt; endl;
  }
  <B>catch</B>(CORBA::Exception&amp; ex) {
    cerr &lt;&lt; "Caught CORBA::Exception: " &lt;&lt; ex._name() &lt;&lt; endl;
  }
  <B>catch</B>(omniORB::fatalException&amp; fe) {
    cerr &lt;&lt; "Caught omniORB::fatalException:" &lt;&lt; endl;
    cerr &lt;&lt; "  file: " &lt;&lt; fe.file() &lt;&lt; endl;
    cerr &lt;&lt; "  line: " &lt;&lt; fe.line() &lt;&lt; endl;
    cerr &lt;&lt; "  mesg: " &lt;&lt; fe.errmsg() &lt;&lt; endl;
  }
  <B>return</B> 0;
}</DIV><H3 CLASS="subsection"><A NAME="htoc136">11.4.2</A>&#XA0;&#XA0;anyExample_clt.cc</H3><DIV CLASS="lstlisting"><I>// anyExample_clt.cc -  This is the source code of the example used in </I>
<I>//                      Chapter 9 "Type Any and TypeCode" of the omniORB</I>
<I>//                      users guide.</I>
<I>//</I>
<I>//                      This is the client.</I>
<I>//</I>
<I>// Usage: anyExample_clt &lt;object reference&gt;</I>
<I>//</I>

<B>#include</B> &lt;anyExample.hh&gt;

<B>#ifdef</B> HAVE_STD
<B>#  include</B> &lt;iostream&gt;
   <B>using</B> <B>namespace</B> std;
<B>#else</B>
<B>#  include</B> &lt;iostream.h&gt;
<B>#endif</B>


<B>static</B> <B>void</B> invokeOp(anyExample_ptr&amp; tobj, <B>const</B> CORBA::Any&amp; a)
{
  CORBA::Any_var bp;

  cout &lt;&lt; "Invoking operation." &lt;&lt; endl;
  bp = tobj-&gt;testOp(a);

  cout &lt;&lt; "Operation completed. Returned Any: ";
  CORBA::ULong ul;

  <B>if</B> (bp &gt;&gt;= ul) {
    cout &lt;&lt; "ULong: " &lt;&lt; ul &lt;&lt; "\n" &lt;&lt; endl;
  }
  <B>else</B> {
    cout &lt;&lt; "Unknown value." &lt;&lt; "\n" &lt;&lt; endl;
  }
}


<B>static</B> <B>void</B> hello(anyExample_ptr tobj)
{
  CORBA::Any a;

  <I>// Sending Long</I>
  CORBA::Long l = 100;
  a &lt;&lt;= l;
  cout &lt;&lt; "Sending Any containing Long: " &lt;&lt; l &lt;&lt; endl;
  invokeOp(tobj,a);

  <I>// Sending Double</I>
<B>#ifndef</B> NO_FLOAT
  CORBA::Double d = 1.2345;
  a &lt;&lt;= d;
  cout &lt;&lt; "Sending Any containing Double: " &lt;&lt; d &lt;&lt; endl;
  invokeOp(tobj,a);
<B>#endif</B>

  <I>// Sending String</I>
  <B>const</B> <B>char</B>* str = "Hello";
  a &lt;&lt;= str;
  cout &lt;&lt; "Sending Any containing String: " &lt;&lt; str &lt;&lt; endl;
  invokeOp(tobj,a);

  <I>// Sending testStruct  [Struct defined in IDL]</I>
  testStruct t;
  t.l = 456;
  t.s = 8;
  a &lt;&lt;= t;
  cout &lt;&lt; "Sending Any containing testStruct: l: " &lt;&lt; t.l &lt;&lt; endl;
  cout &lt;&lt; "                                   s: " &lt;&lt; t.s &lt;&lt; endl;
  invokeOp(tobj,a);
}

<I>//////////////////////////////////////////////////////////////////////</I>

<B>int</B> main(<B>int</B> argc, <B>char</B>** argv)
{
  <B>try</B> {
    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

    <B>if</B>( argc != 2 ) {
      cerr &lt;&lt; "usage:  anyExample_clt &lt;object reference&gt;" &lt;&lt; endl;
      <B>return</B> 1;
    }

    {
      CORBA::Object_var obj = orb-&gt;string_to_object(argv[1]);
      anyExample_var ref = anyExample::_narrow(obj);
      <B>if</B>( CORBA::is_nil(ref) ) {
        cerr &lt;&lt; "Can't narrow reference to type anyExample (or it was nil)."
             &lt;&lt; endl;
        <B>return</B> 1;
      }
      hello(ref);
    }
    orb-&gt;destroy();
  }
  <B>catch</B>(CORBA::TRANSIENT&amp;) {
    cerr &lt;&lt; "Caught system exception TRANSIENT -- unable to contact the "
         &lt;&lt; "server." &lt;&lt; endl;
  }
  <B>catch</B>(CORBA::SystemException&amp; ex) {
    cerr &lt;&lt; "Caught a CORBA::" &lt;&lt; ex._name() &lt;&lt; endl;
  }
  <B>catch</B>(CORBA::Exception&amp; ex) {
    cerr &lt;&lt; "Caught CORBA::Exception: " &lt;&lt; ex._name() &lt;&lt; endl;
  }
  <B>catch</B>(omniORB::fatalException&amp; fe) {
    cerr &lt;&lt; "Caught omniORB::fatalException:" &lt;&lt; endl;
    cerr &lt;&lt; "  file: " &lt;&lt; fe.file() &lt;&lt; endl;
    cerr &lt;&lt; "  line: " &lt;&lt; fe.line() &lt;&lt; endl;
    cerr &lt;&lt; "  mesg: " &lt;&lt; fe.errmsg() &lt;&lt; endl;
  }
  <B>return</B> 0;
}</DIV><HR>
<A HREF="omniORB010.html"><IMG SRC="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC="contents_motif.gif" ALT="Up"></A>
<A HREF="omniORB012.html"><IMG SRC="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>