1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--Converted with LaTeX2HTML 2002-2-1 (1.70)
original version by: Nikos Drakos, CBLU, University of Leeds
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<HTML>
<HEAD>
<TITLE>Catching and Throwing Exceptions in C</TITLE>
<META NAME="description" CONTENT="Catching and Throwing Exceptions in C">
<META NAME="keywords" CONTENT="users_guide">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META NAME="Generator" CONTENT="LaTeX2HTML v2002-2-1">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
<LINK REL="STYLESHEET" HREF="users_guide.css">
<LINK REL="next" HREF="node117.html">
<LINK REL="previous" HREF="node115.html">
<LINK REL="up" HREF="node110.html">
<LINK REL="next" HREF="node117.html">
</HEAD>
<BODY >
<DIV CLASS="navigation"><!--Navigation Panel-->
<A NAME="tex2html2449"
HREF="node117.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A>
<A NAME="tex2html2443"
HREF="node110.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A>
<A NAME="tex2html2437"
HREF="node115.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A>
<A NAME="tex2html2445"
HREF="node14.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A>
<A NAME="tex2html2447"
HREF="node317.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A>
<BR>
<B> Next:</B> <A NAME="tex2html2450"
HREF="node117.html">Implicitly defined methods</A>
<B> Up:</B> <A NAME="tex2html2444"
HREF="node110.html">C Bindings</A>
<B> Previous:</B> <A NAME="tex2html2438"
HREF="node115.html">Calling SIDL methods from</A>
<B> <A NAME="tex2html2446"
HREF="node14.html">Contents</A></B>
<B> <A NAME="tex2html2448"
HREF="node317.html">Index</A></B>
<BR>
<BR></DIV>
<!--End of Navigation Panel-->
<H1><A NAME="SECTION03160000000000000000"></A>
<A NAME="5714"></A><A NAME="5715"></A>
<BR>
Catching and Throwing Exceptions in C
</H1>
For methods that can throw exceptions, there is an extra <TT>out</TT>
argument in the generated code that holds the exception. For maximum
backward compatibility and consistency, the extra argument is of type
<TT>sidl.BaseInterface</TT>. When the exception parameter is not
<TT>NULL</TT>, it indicates that an exception has been thrown. When an
exception is thrown, the caller should ignore the value of the other
<TT>out</TT> parameters as well as the function's return value. Every
time you call a method that potentially can throw an exception, you
must check the result. Otherwise, those exceptions will be utterly
ignored and leak memory.
<A NAME="5720"></A>
<A NAME="5721"></A><A NAME="5722"></A><A NAME="5723"></A>
<A NAME="5724"></A>
There are are four macros provided in sidl_Exception.h to help with
exception checking. Their use is fairly obvious from their names. They are:
<P>
<BR>
<PRE CLASS="verbatim">SIDL_THROW(EX_VAR,EX_CLS,MSG)
SIDL_CHECK(EX_VAR)
SIDL_CLEAR(EX_VAR)
SIDL_CATCH(EX_VAR,sidl_NAME)
</PRE></td></tr></table></blockquote>
<P>
In these macros, EX_VAR is the exception object itself, EX_CLS is the
name of the SIDL type we wish the exception to be in a string, MSG is
the message we wish to include with the exception and a string, and
sidl_NAME is the type of the exception we expect to catch, as a string.
<P>
The following SIDL method taken from the Babel regression tests
demonstrates how exceptions are handled.
<P>
<BR>
<PRE CLASS="verbatim">int getFib(in int n, in int max_depth, in int max_value, in int depth)
throws NegativeValueException, FibException;
</I></PRE></td></tr></table></blockquote>
<P>
Here is the C binding for this method:
<P>
<BR>
<PRE CLASS="verbatim">int32_t
ExceptionTest_Fib_getFib(
ExceptionTest_Fib self,
int32_t n,
int32_t max_depth,
int32_t max_value,
int32_t depth,
sidl_BaseInterface *_ex);
</PRE></td></tr></table></blockquote>
<P>
Here is an example of how to perform exception handling in C using a
package of macros defined in <TT>sidl_Exception.h</TT>. Note that the
macros assume the exception class that is being thrown and caught inherits
from or implements
<BR><TT><I CLASS="slanted">sidl.BaseException</I></TT> -- something guaranteed
by Babel.
<P>
<BR>
<PRE CLASS="verbatim">#include "sidl_Exception.h"
/* ...numerous lines deleted... */
int x;
sidl_BaseInterface _ex = NULL;
x = ExceptionTest_Fib_getFib(f, 10, 1, 100, 0, &_ex);
if (SIDL_CATCH(_ex, "ExceptionTest.TooDeepException")) {
traceback(_ex);
SIDL_CLEAR(_ex);
}
else if (SIDL_CATCH(_ex, "ExceptionTest.TooBigException")) {
traceback(_ex);
SIDL_CLEAR(_ex);
}
else if (_ex == NULL) {
return FALSE;
}
SIDL_CHECK(_ex);
return TRUE;
EXIT:;
traceback(_ex);
SIDL_CLEAR(_ex);
return FALSE;
</PRE></td></tr></table></blockquote>
<P>
You do not have to use the macros provided in <TT>sidl_Exception.h</TT>
if you do no want to. You can check <TT>_ex</TT> by checking if it is
not <TT>NULL</TT> and then trying to cast it to the various potential
exception types.
<P>
The following code snippet shows how to throw an exception in C using
the macros from <TT>sidl_Exception.h</TT>. The first argument to
<TT>SIDL_THROW</TT> is the exception output parameter, and the
second argument is the type of exception being thrown. The third
argument provides a textual description of the exception.
<P>
<BR>
<PRE CLASS="verbatim">#include "sidl_Exception.h"
/* ...numerous lines deleted... */
int32_t
impl_ExceptionTest_Fib_getFib(
ExceptionTest_Fib self, int32_t n, int32_t max_depth, int32_t max_value,
int32_t depth, sidl_BaseInterface* _ex)
{
/* DO-NOT-DELETE splicer.begin(ExceptionTest.Fib.getFib) */
if (n < 0) {
SIDL_THROW(*_ex,
ExceptionTest_NegativeValueException,
"called with negative n");
}
/* ...lines deleted... */
EXIT:;
/* SIDL_THROW macro will jump here. */
/* Clean up code should be here. */
return theValue;
/* DO-NOT-DELETE splicer.end(ExceptionTest.Fib.getFib) */
}
</PRE></td></tr></table></blockquote>
<P>
The code section labeled <TT>EXIT</TT> is where you should put clean up
code. The caller will ignore all the values leaving your C function
(i.e., <TT>out</TT> or <TT>inout</TT> parameters) because you have thrown
an exception, so your code should delete any references you were
planning to return to the caller. It's good practice to set all
<TT>inout</TT> and <TT>out</TT> array, interface or class pointers to
<TT>NULL</TT>. This makes things work out better for clients who forget
to check if an exception occurred or willfully choose to ignore it.
<P>
<DIV CLASS="navigation"><HR>
<!--Navigation Panel-->
<A NAME="tex2html2449"
HREF="node117.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A>
<A NAME="tex2html2443"
HREF="node110.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A>
<A NAME="tex2html2437"
HREF="node115.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A>
<A NAME="tex2html2445"
HREF="node14.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A>
<A NAME="tex2html2447"
HREF="node317.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A>
<BR>
<B> Next:</B> <A NAME="tex2html2450"
HREF="node117.html">Implicitly defined methods</A>
<B> Up:</B> <A NAME="tex2html2444"
HREF="node110.html">C Bindings</A>
<B> Previous:</B> <A NAME="tex2html2438"
HREF="node115.html">Calling SIDL methods from</A>
<B> <A NAME="tex2html2446"
HREF="node14.html">Contents</A></B>
<B> <A NAME="tex2html2448"
HREF="node317.html">Index</A></B> </DIV>
<!--End of Navigation Panel-->
<ADDRESS>
<br><br>babel-0.10.2<br>users_guide Last Modified 2005-03-23<br><br><a href="http://www.llnl.gov/CASC/components">http://www.llnl.gov/CASC/components</a><br><a href="mailto:components@llnl.gov">components@llnl.gov</a>
</ADDRESS>
</BODY>
</HTML>
|