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
|
<!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 Fortran 90</TITLE>
<META NAME="description" CONTENT="Catching and Throwing Exceptions in Fortran 90">
<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="node145.html">
<LINK REL="previous" HREF="node143.html">
<LINK REL="up" HREF="node140.html">
<LINK REL="next" HREF="node145.html">
</HEAD>
<BODY >
<DIV CLASS="navigation"><!--Navigation Panel-->
<A NAME="tex2html2860"
HREF="node145.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A>
<A NAME="tex2html2854"
HREF="node140.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A>
<A NAME="tex2html2848"
HREF="node143.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A>
<A NAME="tex2html2856"
HREF="node14.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A>
<A NAME="tex2html2858"
HREF="node317.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A>
<BR>
<B> Next:</B> <A NAME="tex2html2861"
HREF="node145.html">Invoking Babel to Generate</A>
<B> Up:</B> <A NAME="tex2html2855"
HREF="node140.html">FORTRAN 90 Bindings</A>
<B> Previous:</B> <A NAME="tex2html2849"
HREF="node143.html">Calling Methods From FORTRAN</A>
<B> <A NAME="tex2html2857"
HREF="node14.html">Contents</A></B>
<B> <A NAME="tex2html2859"
HREF="node317.html">Index</A></B>
<BR>
<BR></DIV>
<!--End of Navigation Panel-->
<H1><A NAME="SECTION03440000000000000000"></A>
<A NAME="8083"></A>
<BR>
Catching and Throwing Exceptions in Fortran 90
</H1>
<P>
When a method can throw an exception (i.e., its SIDL definition has
a throws clause), a variable should be passed to hold an exception.
For maximum backward compatibility, the exception argument type is a
<TT><I CLASS="slanted">sidl.BaseInterface</I></TT> pointer that is assumed to implement the
<TT><I CLASS="slanted">sidl.BaseException</I></TT> interface. The exception argument should
appear after the return value when both occur in a method, and it
behaves like an <TT>out</TT> parameter. After the call, the client
should test this argument using <TT>is_null</TT> or <TT>not_null</TT>.
If it is <TT>not_null</TT>, an exception was thrown by the method, and
the method should respond appropriately. When an exception is thrown,
the value of all other arguments is undefined, and the best course of
action is to ignore their values. If your code does not check the
exception argument after each call that can throw an exception, any
exceptions that are thrown will be utterly ignored; they will not
propagate automatically to higher level routines.
<P>
Here is another example adapted from the Babel regression tests.
Package ExceptionTest has a class named Fib with a method declared in SIDL as follows:
<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 outline of a FORTRAN 90 code fragment to use this method.
<P>
<BR>
<PRE CLASS="verbatim"> use ExceptionTest_Fib
use ExceptionTest_FibException
use ExceptionTest_NegativeValueException
use sidl_BaseInterface
type(ExceptionTest_Fib_t) :: fib
type(sidl_BaseInterface_t) :: except
type(ExceptionTest_FibException_t) :: fibexcept
type(ExceptionTest_NegativeValueException_t) :: nvexcept
integer (selected_int_kind(9)) :: index, maxdepth, maxval, depth, result
call new(fib)
index = 4
maxdepth = 100
maxvalue = 32000
depth = 0
call getFib(fib, index, maxdepth, maxvalue, depth, result, except)
if (not_null(except)) then
call cast(except, fibexcept)
if (not_null(fibexcept)) then
! do something here with the FibException
else
call cast(except, nvexcept)
! do something here with the NegativeValueException
endif
call deleteRef(except)
else
write (*,*) 'getFib for ', index, ' returned ', result
endif
call deleteRef(fib)
</PRE></td></tr></table></blockquote>
<P>
Here is an example of an implementation subroutine that throws an
exception. Note you must <TT>cast</TT> the returned exception object
into the exception <TT>out</TT> parameter. The <TT>setNote</TT> method
provides a useful error message, and the <TT>add</TT> method helps
provide a multi-language traceback capability (provided each layer of
the call stack calls <TT>add</TT>).
<P>
<BR>
<PRE CLASS="verbatim">recursive subroutine ExceptionTest_Fib_getFib_mi(self, n, max_depth, &
max_value, depth, retval, exception)
use sidl_BaseInterface
use ExceptionTest_Fib
use ExceptionTest_NegativeValueException
use ExceptionTest_FibException
use ExceptionTest_Fib_impl
! DO-NOT-DELETE splicer.begin(ExceptionTest.Fib.getFib.use)
use ExceptionTest_TooBigException
use ExceptionTest_TooDeepException
! DO-NOT-DELETE splicer.end(ExceptionTest.Fib.getFib.use)
implicit none
type(ExceptionTest_Fib_t) :: self
integer (selected_int_kind(9)) :: n, max_depth, max_value
integer (selected_int_kind(9)) :: retval, depth
type(sidl_BaseInterface_t) :: exception
! DO-NOT-DELETE splicer.begin(ExceptionTest.Fib.getFib)
type(ExceptionTest_NegativeValueException_t) :: negexc
! ...lines deleted...
character (len=*) myfilename
parameter(myfilename='ExceptionTest_Fib_Impl.f')
retval = 0
if (n .lt. 0) then
call new(negexc)
if (not_null(negexc)) then
call setNote(negexc, &
'called with negative n')
call add(negexc, myfilename, 57, &
'ExceptionTest_Fib_getFib_impl')
call cast(negexc, exception)
return
endif
else
! ...numerous lines deleted....
! DO-NOT-DELETE splicer.end(ExceptionTest.Fib.getFib)
end subroutine ExceptionTest_Fib_getFib_mi
</PRE></td></tr></table></blockquote>
<P>
Please note that when your code throws an exception it should
<TT>deleteRef</TT> any references it was planning to return to its
caller. Any caller of a method that returns an exception should ignore
the values of <TT>out</TT> and <TT>inout</TT> parameters, so anything you
do not free will become a reference and memory leak. In general, it is
good practice to call <TT>set_null</TT> on all <TT>out</TT> and
<TT>inout</TT> array, class and interface arguments before returning
when throwing an exception. 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="tex2html2860"
HREF="node145.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A>
<A NAME="tex2html2854"
HREF="node140.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A>
<A NAME="tex2html2848"
HREF="node143.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A>
<A NAME="tex2html2856"
HREF="node14.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A>
<A NAME="tex2html2858"
HREF="node317.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A>
<BR>
<B> Next:</B> <A NAME="tex2html2861"
HREF="node145.html">Invoking Babel to Generate</A>
<B> Up:</B> <A NAME="tex2html2855"
HREF="node140.html">FORTRAN 90 Bindings</A>
<B> Previous:</B> <A NAME="tex2html2849"
HREF="node143.html">Calling Methods From FORTRAN</A>
<B> <A NAME="tex2html2857"
HREF="node14.html">Contents</A></B>
<B> <A NAME="tex2html2859"
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>
|