Document allowexcept feature git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8692 626c5289-ae23-0410-ae9c-e8d60b6d4f22
1019 lines
28 KiB
HTML
1019 lines
28 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<title>Customization Features</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<H1><a name="Customization"></a>11 Customization Features</H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#exception">Exception handling with %exception</a>
|
|
<ul>
|
|
<li><a href="#Customization_nn3">Handling exceptions in C code</a>
|
|
<li><a href="#Customization_nn4">Exception handling with longjmp()</a>
|
|
<li><a href="#Customization_nn5">Handling C++ exceptions</a>
|
|
<li><a href="#Customization_allowexcept">Exception handlers for variables</a>
|
|
<li><a href="#Customization_nn6">Defining different exception handlers</a>
|
|
<li><a href="#Customization_nn7">Using The SWIG exception library</a>
|
|
</ul>
|
|
<li><a href="#ownership">Object ownership and %newobject</a>
|
|
<li><a href="#features">Features and the %feature directive</a>
|
|
<ul>
|
|
<li><a href="#Customization_feature_flags">Feature flags</a>
|
|
<li><a href="#Customization_clearing_features">Clearing features</a>
|
|
<li><a href="#Customization_features_default_args">Features and default arguments</a>
|
|
<li><a href="#features_example">Feature example</a>
|
|
</ul>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
In many cases, it is desirable to change the default wrapping of
|
|
particular declarations in an interface. For example, you might want
|
|
to provide hooks for catching C++ exceptions, add assertions, or
|
|
provide hints to the underlying code generator. This chapter
|
|
describes some of these customization techniques. First, a discussion
|
|
of exception handling is presented. Then, a more general-purpose
|
|
customization mechanism known as "features" is described.
|
|
</p>
|
|
|
|
<H2><a name="exception"></a>11.1 Exception handling with %exception</H2>
|
|
|
|
|
|
<p>
|
|
The <tt>%exception</tt> directive allows you to define a general purpose exception
|
|
handler. For example, you can specify the following:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%exception {
|
|
try {
|
|
$action
|
|
}
|
|
catch (RangeError) {
|
|
PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
|
|
return NULL;
|
|
}
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
When defined, the code enclosed in braces is inserted directly into the low-level wrapper
|
|
functions. The special symbol <tt>$action</tt> gets replaced with the actual operation
|
|
to be performed (a function call, method invocation, attribute access, etc.). An exception handler
|
|
remains in effect until it is explicitly deleted. This is done by using either <tt>%exception</tt>
|
|
or <tt>%noexception</tt> with no code. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%exception; // Deletes any previously defined handler
|
|
</pre></div>
|
|
|
|
<p>
|
|
<b>Compatibility note:</b> Previous versions of SWIG used a special directive <tt>%except</tt>
|
|
for exception handling. That directive is deprecated--<tt>%exception</tt>
|
|
provides the same functionality, but is substantially more flexible.
|
|
</p>
|
|
|
|
<H3><a name="Customization_nn3"></a>11.1.1 Handling exceptions in C code</H3>
|
|
|
|
|
|
<p>
|
|
C has no formal exception handling mechanism so there are several approaches that might be
|
|
used. A somewhat common technique is to simply set a special error code. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
/* File : except.c */
|
|
|
|
static char error_message[256];
|
|
static int error_status = 0;
|
|
|
|
void throw_exception(char *msg) {
|
|
strncpy(error_message,msg,256);
|
|
error_status = 1;
|
|
}
|
|
|
|
void clear_exception() {
|
|
error_status = 0;
|
|
}
|
|
char *check_exception() {
|
|
if (error_status) return error_message;
|
|
else return NULL;
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
To use these functions, functions simply call
|
|
<tt>throw_exception()</tt> to indicate an error occurred. For example
|
|
:</p>
|
|
|
|
<div class="code"><pre>
|
|
double inv(double x) {
|
|
if (x != 0) return 1.0/x;
|
|
else {
|
|
throw_exception("Division by zero");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
To catch the exception, you can write a simple exception handler such
|
|
as the following (shown for Perl5) :</p>
|
|
|
|
<div class="code"><pre>
|
|
%exception {
|
|
char *err;
|
|
clear_exception();
|
|
$action
|
|
if ((err = check_exception())) {
|
|
croak(err);
|
|
}
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
In this case, when an error occurs, it is translated into a Perl error.
|
|
Each target language has its own approach to creating a runtime error/exception in
|
|
and for Perl it is the <tt>croak</tt> method shown above.
|
|
</p>
|
|
|
|
<H3><a name="Customization_nn4"></a>11.1.2 Exception handling with longjmp()</H3>
|
|
|
|
|
|
<p>
|
|
Exception handling can also be added to C code using the
|
|
<tt><setjmp.h></tt> library. Here is a minimalistic implementation that
|
|
relies on the C preprocessor :
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
/* File : except.c
|
|
Just the declaration of a few global variables we're going to use */
|
|
|
|
#include <setjmp.h>
|
|
jmp_buf exception_buffer;
|
|
int exception_status;
|
|
|
|
/* File : except.h */
|
|
#include <setjmp.h>
|
|
extern jmp_buf exception_buffer;
|
|
extern int exception_status;
|
|
|
|
#define try if ((exception_status = setjmp(exception_buffer)) == 0)
|
|
#define catch(val) else if (exception_status == val)
|
|
#define throw(val) longjmp(exception_buffer,val)
|
|
#define finally else
|
|
|
|
/* Exception codes */
|
|
|
|
#define RangeError 1
|
|
#define DivisionByZero 2
|
|
#define OutOfMemory 3
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Now, within a C program, you can do the following :</p>
|
|
|
|
<div class="code"><pre>
|
|
double inv(double x) {
|
|
if (x) return 1.0/x;
|
|
else throw(DivisionByZero);
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Finally, to create a SWIG exception handler, write the following :</p>
|
|
|
|
<div class="code"><pre>
|
|
%{
|
|
#include "except.h"
|
|
%}
|
|
|
|
%exception {
|
|
try {
|
|
$action
|
|
} catch(RangeError) {
|
|
croak("Range Error");
|
|
} catch(DivisionByZero) {
|
|
croak("Division by zero");
|
|
} catch(OutOfMemory) {
|
|
croak("Out of memory");
|
|
} finally {
|
|
croak("Unknown exception");
|
|
}
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
Note: This implementation is only intended to illustrate the general idea. To make it work better, you'll need to
|
|
modify it to handle nested <tt>try</tt> declarations.
|
|
</p>
|
|
|
|
<H3><a name="Customization_nn5"></a>11.1.3 Handling C++ exceptions</H3>
|
|
|
|
|
|
<p>
|
|
Handling C++ exceptions is also straightforward. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%exception {
|
|
try {
|
|
$action
|
|
} catch(RangeError) {
|
|
croak("Range Error");
|
|
} catch(DivisionByZero) {
|
|
croak("Division by zero");
|
|
} catch(OutOfMemory) {
|
|
croak("Out of memory");
|
|
} catch(...) {
|
|
croak("Unknown exception");
|
|
}
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
The exception types need to be declared as classes elsewhere, possibly
|
|
in a header file :</p>
|
|
|
|
<div class="code"><pre>
|
|
class RangeError {};
|
|
class DivisionByZero {};
|
|
class OutOfMemory {};
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Customization_allowexcept"></a>11.1.4 Exception handlers for variables</H3>
|
|
|
|
|
|
<p>
|
|
By default all variables will ignore <tt>%exception</tt>, so it is effectively turned off for all variables wrappers.
|
|
This applies to global variables, member variables and static member variables.
|
|
The approach is certainly a logical one when wrapping variables in C.
|
|
However, in C++, it is quite possible for an exception to be thrown while the variable is being assigned.
|
|
To ensure <tt>%exception</tt> is used when wrapping variables, it needs to be 'turned on' using the <tt>%allowexception</tt> feature.
|
|
Note that <tt>%allowexception</tt> is just a macro for <tt>%feature("allowexcept")</tt>, that is, it is a feature called "allowexcept".
|
|
Any variable which has this feature attached to it, will then use the <tt>%exception</tt> feature, but of course,
|
|
only if there is a <tt>%exception</tt> attached to the variable in the first place.
|
|
The <tt>%allowexception</tt> feature works like any other feature and so can be used globally or for selective variables.
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%allowexception; // turn on globally
|
|
%allowexception Klass::MyVar; // turn on for a specific variable
|
|
|
|
%noallowexception Klass::MyVar; // turn off for a specific variable
|
|
%noallowexception; // turn off globally
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Customization_nn6"></a>11.1.5 Defining different exception handlers</H3>
|
|
|
|
|
|
<p>
|
|
By default, the <tt>%exception</tt> directive creates an exception
|
|
handler that is used for all wrapper functions that follow it. Unless
|
|
there is a well-defined (and simple) error handling mechanism in place,
|
|
defining one universal exception handler may be unwieldy and result
|
|
in excessive code bloat since the handler is inlined into each wrapper function.
|
|
</p>
|
|
|
|
<p>
|
|
To fix this, you can be more selective about how you use the
|
|
<tt>%exception</tt> directive. One approach is to only place it around
|
|
critical pieces of code. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%exception {
|
|
... your exception handler ...
|
|
}
|
|
/* Define critical operations that can throw exceptions here */
|
|
|
|
%exception;
|
|
|
|
/* Define non-critical operations that don't throw exceptions */
|
|
</pre></div>
|
|
|
|
<p>
|
|
More precise control over exception handling can be obtained by attaching an exception handler
|
|
to specific declaration name. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%exception allocate {
|
|
try {
|
|
$action
|
|
}
|
|
catch (MemoryError) {
|
|
croak("Out of memory");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this case, the exception handler is only attached to declarations
|
|
named "allocate". This would include both global and member
|
|
functions. The names supplied to <tt>%exception</tt> follow the same
|
|
rules as for <tt>%rename</tt> described in the section on
|
|
<a href="SWIGPlus.html#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>.
|
|
For example, if you wanted to define
|
|
an exception handler for a specific class, you might write this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%exception Object::allocate {
|
|
try {
|
|
$action
|
|
}
|
|
catch (MemoryError) {
|
|
croak("Out of memory");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When a class prefix is supplied, the exception handler is applied to the corresponding declaration
|
|
in the specified class as well as for identically named functions appearing in derived classes.
|
|
</p>
|
|
|
|
<p>
|
|
<tt>%exception</tt> can even be used to pinpoint a precise declaration when overloading is used. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%exception Object::allocate(int) {
|
|
try {
|
|
$action
|
|
}
|
|
catch (MemoryError) {
|
|
croak("Out of memory");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Attaching exceptions to specific declarations is a good way to reduce code bloat. It can also be a useful way
|
|
to attach exceptions to specific parts of a header file. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%{
|
|
#include "someheader.h"
|
|
%}
|
|
|
|
// Define a few exception handlers for specific declarations
|
|
%exception Object::allocate(int) {
|
|
try {
|
|
$action
|
|
}
|
|
catch (MemoryError) {
|
|
croak("Out of memory");
|
|
}
|
|
}
|
|
|
|
%exception Object::getitem {
|
|
try {
|
|
$action
|
|
}
|
|
catch (RangeError) {
|
|
croak("Index out of range");
|
|
}
|
|
}
|
|
...
|
|
// Read a raw header file
|
|
%include "someheader.h"
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>Compatibility note:</b> The <tt>%exception</tt> directive replaces
|
|
the functionality provided by the deprecated "except" typemap.
|
|
The typemap would allow exceptions to be thrown in the target
|
|
language based on the return type of a function and
|
|
was intended to be a mechanism for pinpointing specific
|
|
declarations. However, it never really worked that well and the new
|
|
%exception directive is much better.
|
|
</p>
|
|
|
|
<H3><a name="Customization_nn7"></a>11.1.6 Using The SWIG exception library</H3>
|
|
|
|
|
|
<p>
|
|
The <tt>exception.i</tt> library file provides support for creating
|
|
language independent exceptions in your interfaces. To use it, simply
|
|
put an "<tt>%include exception.i</tt>" in your interface file. This
|
|
creates a function<tt> SWIG_exception()</tt> that can be used to raise
|
|
common scripting language exceptions in a portable manner. For example :</p>
|
|
|
|
<div class="code"><pre>
|
|
// Language independent exception handler
|
|
%include exception.i
|
|
|
|
%exception {
|
|
try {
|
|
$action
|
|
} catch(RangeError) {
|
|
SWIG_exception(SWIG_ValueError, "Range Error");
|
|
} catch(DivisionByZero) {
|
|
SWIG_exception(SWIG_DivisionByZero, "Division by zero");
|
|
} catch(OutOfMemory) {
|
|
SWIG_exception(SWIG_MemoryError, "Out of memory");
|
|
} catch(...) {
|
|
SWIG_exception(SWIG_RuntimeError,"Unknown exception");
|
|
}
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
As arguments, <tt>SWIG_exception()</tt> takes an error type code (an
|
|
integer) and an error message string. The currently supported error
|
|
types are :</p>
|
|
|
|
<div class="diagram"><pre>
|
|
SWIG_UnknownError
|
|
SWIG_IOError
|
|
SWIG_RuntimeError
|
|
SWIG_IndexError
|
|
SWIG_TypeError
|
|
SWIG_DivisionByZero
|
|
SWIG_OverflowError
|
|
SWIG_SyntaxError
|
|
SWIG_ValueError
|
|
SWIG_SystemError
|
|
SWIG_AttributeError
|
|
SWIG_MemoryError
|
|
SWIG_NullReferenceError
|
|
</pre></div>
|
|
|
|
<p>
|
|
Since the <tt>SWIG_exception()</tt> function is defined at the C-level
|
|
it can be used elsewhere in SWIG. This includes typemaps and helper
|
|
functions.
|
|
</p>
|
|
|
|
<H2><a name="ownership"></a>11.2 Object ownership and %newobject</H2>
|
|
|
|
|
|
<p>
|
|
A common problem in some applications is managing proper ownership of objects. For
|
|
example, consider a function like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
Foo *blah() {
|
|
Foo *f = new Foo();
|
|
return f;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If you wrap the function <tt>blah()</tt>, SWIG has no idea that the
|
|
return value is a newly allocated object. As a result, the resulting
|
|
extension module may produce a memory leak (SWIG is conservative and
|
|
will never delete objects unless it knows for certain that the
|
|
returned object was newly created).
|
|
</p>
|
|
|
|
<p>
|
|
To fix this, you can provide an extra hint to the code generator using
|
|
the <tt>%newobject</tt> directive. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%newobject blah;
|
|
Foo *blah();
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%newobject</tt> works exactly like <tt>%rename</tt> and <tt>%exception</tt>. In other words,
|
|
you can attach it to class members and parameterized declarations as before. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%newobject ::blah(); // Only applies to global blah
|
|
%newobject Object::blah(int,double); // Only blah(int,double) in Object
|
|
%newobject *::copy; // Copy method in all classes
|
|
...
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When <tt>%newobject</tt> is supplied, many language modules will
|
|
arrange to take ownership of the return value. This allows the value
|
|
to be automatically garbage-collected when it is no longer in use. However,
|
|
this depends entirely on the target language (a language module may also choose to ignore
|
|
the <tt>%newobject</tt> directive).
|
|
</p>
|
|
|
|
<p>
|
|
Closely related to <tt>%newobject</tt> is a special typemap. The "newfree" typemap
|
|
can be used to deallocate a newly allocated return value. It is only available on
|
|
methods for which <tt>%newobject</tt> has been applied and is commonly used to clean-up string
|
|
results. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(newfree) char * "free($1);";
|
|
...
|
|
%newobject strdup;
|
|
...
|
|
char *strdup(const char *s);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this case, the result of the function is a string in the target language. Since this string
|
|
is a copy of the original result, the data returned by <tt>strdup()</tt> is no longer needed.
|
|
The "newfree" typemap in the example simply releases this memory.
|
|
</p>
|
|
|
|
<p>
|
|
As a complement to the <tt>%newobject</tt>, from SWIG 1.3.28, you can
|
|
use the <tt>%delobject</tt> directive. For example, if you have two
|
|
methods, one to create objects and one to destroy them, you can use:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%newobject create_foo;
|
|
%delobject destroy_foo;
|
|
...
|
|
Foo *create_foo();
|
|
void destroy_foo(Foo *foo);
|
|
</pre>
|
|
</div>
|
|
|
|
<p> or in a member method as: </p>
|
|
<div class="code">
|
|
<pre>
|
|
%delobject Foo::destroy;
|
|
|
|
class Foo {
|
|
public:
|
|
void destroy() { delete this;}
|
|
|
|
private:
|
|
~Foo();
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%delobject</tt> instructs SWIG that the first argument passed to
|
|
the method will be destroyed, and therefore, the target language
|
|
should not attempt to deallocate it twice. This is similar to use the
|
|
DISOWN typemap in the first method argument, and in fact, it also
|
|
depends on the target language on implementing the 'disown' mechanism
|
|
properly.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Compatibility note:</b> Previous versions of SWIG had a special <tt>%new</tt> directive. However, unlike <tt>%newobject</tt>,
|
|
it only applied to the next declaration. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%new char *strdup(const char *s);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
For now this is still supported but is deprecated.
|
|
</p>
|
|
|
|
<p>
|
|
<b>How to shoot yourself in the foot:</b> The <tt>%newobject</tt> directive is not a declaration modifier like the old
|
|
<tt>%new</tt> directive. Don't write code like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%newobject
|
|
char *strdup(const char *s);
|
|
</pre>
|
|
</div>
|
|
<p>
|
|
The results might not be what you expect.
|
|
</p>
|
|
|
|
<H2><a name="features"></a>11.3 Features and the %feature directive</H2>
|
|
|
|
|
|
<p>
|
|
Both <tt>%exception</tt> and <tt>%newobject</tt> are examples of a
|
|
more general purpose customization mechanism known as "features." A
|
|
feature is simply a user-definable property that is attached to
|
|
specific declarations. Features are attached
|
|
using the <tt>%feature</tt> directive. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except") Object::allocate {
|
|
try {
|
|
$action
|
|
}
|
|
catch (MemoryError) {
|
|
croak("Out of memory");
|
|
}
|
|
}
|
|
|
|
%feature("new","1") *::copy;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In fact, the <tt>%exception</tt> and <tt>%newobject</tt> directives are really nothing more than macros
|
|
involving <tt>%feature</tt>:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define %exception %feature("except")
|
|
#define %newobject %feature("new","1")
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The name matching rules outlined in the <a href="SWIGPlus.html#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
|
|
section applies to all <tt>%feature</tt> directives.
|
|
In fact the the <tt>%rename</tt> directive is just a special form of <tt>%feature</tt>.
|
|
The matching rules mean that features are very flexible and can be applied with
|
|
pinpoint accuracy to specific declarations if needed.
|
|
Additionally, if no declaration name is given, a global feature is said to be defined.
|
|
This feature is then
|
|
attached to <em>every</em> declaration that follows. This is how global exception handlers
|
|
are defined. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* Define a global exception handler */
|
|
%feature("except") {
|
|
try {
|
|
$action
|
|
}
|
|
...
|
|
}
|
|
|
|
... bunch of declarations ...
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The <tt>%feature</tt> directive can be used with different syntax.
|
|
The following are all equivalent:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except") Object::method { $action };
|
|
%feature("except") Object::method %{ $action %};
|
|
%feature("except") Object::method " $action ";
|
|
%feature("except","$action") Object::method;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The syntax in the first variation will generate the <tt>{ }</tt> delimiters used whereas the other variations will not.
|
|
The <tt>%feature</tt> directive also accepts XML style attributes in the same way that typemaps will.
|
|
Any number of attributes can be specified.
|
|
The following is the generic syntax for features:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("name","value", attribute1="AttributeValue1") symbol;
|
|
%feature("name", attribute1="AttributeValue1") symbol {value};
|
|
%feature("name", attribute1="AttributeValue1") symbol %{value%};
|
|
%feature("name", attribute1="AttributeValue1") symbol "value";
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
More than one attribute can be specified using a comma separated list.
|
|
The Java module is an example that uses attributes in <tt>%feature("except")</tt>.
|
|
The <tt>throws</tt> attribute specifies the name of a Java class to add to a proxy method's throws clause.
|
|
In the following example, <tt>MyExceptionClass</tt> is the name of the Java class for adding to the throws clause.
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except", throws="MyExceptionClass") Object::method {
|
|
try {
|
|
$action
|
|
} catch (...) {
|
|
... code to throw a MyExceptionClass Java exception ...
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Further details can be obtained from the <a href="Java.html#exception_handling">Java exception handling</a> section.
|
|
</p>
|
|
|
|
<H3><a name="Customization_feature_flags"></a>11.3.1 Feature flags</H3>
|
|
|
|
|
|
<p>
|
|
Feature flags are used to enable or disable a particular feature. Feature flags are a common but simple usage of <tt>%feature</tt>
|
|
and the feature value should be either <tt>1</tt> to enable or <tt>0</tt> to disable the feature.
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("name") // enables feature
|
|
%feature("name", "1") // enables feature
|
|
%feature("name", "x") // enables feature
|
|
%feature("name", "0") // disables feature
|
|
%feature("name", "") // clears feature
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Actually any value other than zero will enable the feature.
|
|
Note that if the value is omitted completely, the default value becomes <tt>1</tt>, thereby enabling the feature.
|
|
A feature is cleared by specifying no value, see <a href="#Customization_clearing_features">Clearing features</a>.
|
|
The <tt>%immutable</tt> directive described in the <a href="SWIG.html#SWIG_readonly_variables">Creating read-only variables</a> section,
|
|
is just a macro for <tt>%feature("immutable")</tt>, and can be used to demonstrates feature flags:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
// features are disabled by default
|
|
int red; // mutable
|
|
|
|
%feature("immutable"); // global enable
|
|
int orange; // immutable
|
|
|
|
%feature("immutable","0"); // global disable
|
|
int yellow; // mutable
|
|
|
|
%feature("immutable","1"); // another form of global enable
|
|
int green; // immutable
|
|
|
|
%feature("immutable",""); // clears the global feature
|
|
int blue; // mutable
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Note that features are disabled by default and must be explicitly enabled either globally or by specifying a targeted declaration.
|
|
The above intersperses SWIG directives with C code. Of course you can target features explicitly, so the above could also be rewritten as:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("immutable","1") orange;
|
|
%feature("immutable","1") green;
|
|
int red; // mutable
|
|
int orange; // immutable
|
|
int yellow; // mutable
|
|
int green; // immutable
|
|
int blue; // mutable
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The above approach allows for the C declarations to be separated from the SWIG directives for when the C declarations are parsed from a C header file.
|
|
The logic above can of course be inverted and rewritten as:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("immutable","1");
|
|
%feature("immutable","0") red;
|
|
%feature("immutable","0") yellow;
|
|
%feature("immutable","0") blue;
|
|
int red; // mutable
|
|
int orange; // immutable
|
|
int yellow; // mutable
|
|
int green; // immutable
|
|
int blue; // mutable
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<H3><a name="Customization_clearing_features"></a>11.3.2 Clearing features</H3>
|
|
|
|
|
|
<p>
|
|
A feature stays in effect until it is explicitly cleared. A feature is cleared by
|
|
supplying a <tt>%feature</tt> directive with no value. For example <tt>%feature("name","")</tt>.
|
|
A cleared feature means that any feature exactly matching any previously defined feature is no longer used in the name matching rules.
|
|
So if a feature is cleared, it might mean that another name matching rule will apply.
|
|
To clarify, let's consider the <tt>except</tt> feature again (<tt>%exception</tt>):
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
// Define global exception handler
|
|
%feature("except") {
|
|
try {
|
|
$action
|
|
} catch (...) {
|
|
croak("Unknown C++ exception");
|
|
}
|
|
}
|
|
|
|
// Define exception handler for all clone methods to log the method calls
|
|
%feature("except") *::clone() {
|
|
try {
|
|
logger.info("$action");
|
|
$action
|
|
} catch (...) {
|
|
croak("Unknown C++ exception");
|
|
}
|
|
}
|
|
|
|
... initial set of class declarations with clone methods ...
|
|
|
|
// clear the previously defined feature
|
|
%feature("except","") *::clone();
|
|
|
|
... final set of class declarations with clone methods ...
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In the above scenario, the initial set of clone methods will log all method invocations from the target language.
|
|
This specific feature is cleared for the final set of clone methods.
|
|
However, these clone methods will still have an exception handler (without logging) as the next best feature match for them is the global exception handler.
|
|
</p>
|
|
|
|
<p>
|
|
Note that clearing a feature is not always the same as disabling it.
|
|
Clearing the feature above with <tt>%feature("except","") *::clone()</tt> is not the same as specifying
|
|
<tt>%feature("except","0") *::clone()</tt>. The former will disable the feature for clone methods -
|
|
the feature is still a better match than the global feature.
|
|
If on the other hand, no global exception handler had been defined at all,
|
|
then clearing the feature would be the same as disabling it as no other feature would have matched.
|
|
</p>
|
|
|
|
<p>
|
|
Note that the feature must match exactly for it to be cleared by any previously defined feature.
|
|
For example the following attempt to clear the initial feature will not work:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except") clone() { logger.info("$action"); $action }
|
|
%feature("except","") *::clone();
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
but this will:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except") clone() { logger.info("$action"); $action }
|
|
%feature("except","") clone();
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Customization_features_default_args"></a>11.3.3 Features and default arguments</H3>
|
|
|
|
|
|
<p>
|
|
SWIG treats methods with default arguments as separate overloaded methods as detailed
|
|
in the <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> section.
|
|
Any <tt>%feature</tt> targeting a method with default arguments
|
|
will apply to all the extra overloaded methods that SWIG generates if the
|
|
default arguments are specified in the feature. If the default arguments are
|
|
not specified in the feature, then the feature will match that exact
|
|
wrapper method only and not the extra overloaded methods that SWIG generates.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except") void hello(int i=0, double d=0.0) { ... }
|
|
void hello(int i=0, double d=0.0);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
will apply the feature to all three wrapper methods, that is:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void hello(int i, double d);
|
|
void hello(int i);
|
|
void hello();
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If the default arguments are not specified in the feature:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except") void hello(int i, double d) { ... }
|
|
void hello(int i=0, double d=0.0);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
then the feature will only apply to this wrapper method:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void hello(int i, double d);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
and not these wrapper methods:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void hello(int i);
|
|
void hello();
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If <a href="SWIGPlus.html#SWIGPlus_default_args">compactdefaultargs</a> are being used, then the difference between
|
|
specifying or not specifying default arguments in a feature is not applicable as just one wrapper is generated.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Compatibility note:</b> The different behaviour of features specified with or without default arguments was introduced
|
|
in SWIG-1.3.23 when the approach to wrapping methods with default arguments was changed.
|
|
</p>
|
|
|
|
<H3><a name="features_example"></a>11.3.4 Feature example</H3>
|
|
|
|
|
|
<p>
|
|
As has been shown earlier, the intended use for the <tt>%feature</tt> directive is as a highly flexible customization mechanism that can be used to annotate
|
|
declarations with additional information for use by specific target language modules. Another example is
|
|
in the Python module. You might use <tt>%feature</tt> to rewrite proxy/shadow class code as follows:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%rename(bar_id) bar(int,double);
|
|
|
|
// Rewrite bar() to allow some nice overloading
|
|
|
|
%feature("shadow") Foo::bar(int) %{
|
|
def bar(*args):
|
|
if len(args) == 3:
|
|
return apply(examplec.Foo_bar_id,args)
|
|
return apply(examplec.Foo_bar,args)
|
|
%}
|
|
|
|
class Foo {
|
|
public:
|
|
int bar(int x);
|
|
int bar(int x, double y);
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Further details of <tt>%feature</tt> usage is described in the documentation for specific language modules.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|