[Up: C++ mapping]
[Previous: Modules] [Next: Time Service]
Due to the limited support for exceptions in earlier versions of the GNU C++ compiler (namely gcc 2.7.2) MICO supports several kinds of exception handling:
Two common problems with exception handling are ``catching by base classes'' and ``exceptions in shared libraries'':
X
it should
be possible to catch it by specifying a base class of X
in the
catch clause. Some compilers (noteably gcc 2.7) do not support this.Which kind of exception handling is used is determined by the capabilities of the C++ compiler and command line options passed to the configure script. By default CORBA compliant exception handling will be selected if the C++ compiler supports catching by base classes, otherwise MICO specific exception handling is selected if the compiler supports exception handling at all. If exceptions in shared libraries do not work then no exception handling is selected for code in shared libraries. You can enforce MICO specific exception handling by specifying -disable-std-eh as a command line option to configure. You can disable exception handling by specifying -disable-except as a command line option to configure.
You can find out about the exception handling support of your MICO binaries by running the IDL-Compiler with the -config command line option:
$ idl --config MICO version: 2.2.7 supported CORBA version: 2.2 exceptions: CORBA compliant modules are mapped to: namespaces STL is: miniSTL SSL support: no loadable modules: yes
The following sections go into detail about each of the exception handling modes supported by MICO.
As the name already indicates this exception handling mode is conformant to the CORBA specification. You can use throw to throw exceptions. Exceptions are caught by specifying the exact type or one of the base types of the exception. Here are some examples:
// throw CORBA::UNKNOWN exception throw CORBA::UNKNOWN(); // catch CORBA::UNKNOWN exception try { ... } catch (CORBA::UNKNOWN &ex) { ... } // catch all system exceptions (including CORBA::UNKNOWN) try { ... } catch (CORBA::SystemException &ex) { ... } // catch all user exceptions (wont catch CORBA::UNKNOWN) try { ... } catch (CORBA::UserException &ex) { ... } // catch all exceptions (including CORBA::UNKNOWN) try { ... } catch (CORBA::Exception &ex) { ... }
If an exception is thrown but not caught MICO will print out a short description of the exception and terminate the process.
This kind of exception handling has been invented for C++ compilers
that do not support catching by base classes. For example it is quite
common to catch all system exceptions. Since catching
CORBA::SystemException & does not work one would have to
write one catch clause for each of the 30 system exceptions. To work
around this problem the function mico_throw()
and special _var
types have been introduced.
You must not use the throw
operator directly to throw an
exception, instead you should use the function mico_throw()
defined in mico/throw.h
, which is automatically included by IDL
compiler generated code:
// ok mico_throw (CORBA::UNKNOWN()); // wrong throw CORBA::UNKNOWN();
will throw the CORBA system exception UNKNOWN
. User defined exceptions
are thrown the same way.
Exceptions are always caught by reference using the _var
types.
System exceptions must be caught by SystemException_var
:
// ok try { ... mico_throw (CORBA::UNKNOWN()); ... } catch (CORBA::SystemException_var &ex) { ... } // wrong try { ... mico_throw (CORBA::UNKNOWN()); ... } catch (CORBA::UNKNOWN_var &ex) { ... } // wrong try { ... mico_throw (CORBA::UNKNOWN()); ... } catch (CORBA::Exception_var &ex) { ... }
Sometimes it is necessary to know exactly which system exception has been thrown:
// ok try { ... mico_throw (CORBA::UNKNOWN()); ... } catch (CORBA::SystemException_var &sys_ex) { if (CORBA::UNKNOWN *ukn_ex = CORBA::UNKNOWN::_narrow (sys_ex)) { // something1 } else { // something2 } } // wrong try { ... } catch (CORBA::UNKNOWN_var &ukn_ex) { // something1 } catch (CORBA::SystemException_var &other_ex) { // something2 }
In contrast to system exceptions a user exception X
must be caught by
X_var
(i.e., not by UserException_var
):
// ok try { ... mico_throw (SomeExcept()); ... } catch (SomeExcept_var &some_ex) { ... } // wrong try { ... mico_throw (SomeExcept()); ... } catch (CORBA::UserException_var &usr_ex) { ... } // wrong try { ... mico_throw (SomeExcept()); ... } catch (CORBA::Exception_var &ex) { ... }
It is possible to write code that works both with CORBA compliant
exception handling and MICO specific exception handling. For this
one should follow the instructions in this section but replace
_var
by _catch
. In MICO specific exception handling
mode X_catch
is typedef'ed to X_var
, in CORBA compliant
exception handling mode X_catch
is typedef'ed to X
.
Furthermore each exception X
provides an overloaded ->
operator so that you can use ->
to access the exception members
in the catch body independent of the exception handling mode. Here
is an example:
// throw mico_throw (CORBA::UNKNOWN()); // catch try { ... } catch (CORBA::SystemException_catch &ex) { cout << ex->minor() << endl; }
If an exception is thrown but not caught MICO will print out a short description of the exception and terminate the process.
Some C++ compilers do not properly support exceptions in shared libraries, others do not support exceptions at all. In these cases exception handling is not available in shared libraries or not available at all, respectively.
Exception handling related C++ keywords (try, throw,
catch) cannot be used in this mode. mico_throw()
can
be used but will only print out a short description of the passed
exception and terminate the process.
[Previous: Modules] [Next: Time Service]
[Up: C++ mapping]