Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <title>Customization Features</title> | |
5 | <link rel="stylesheet" type="text/css" href="style.css"> | |
6 | </head> | |
7 | ||
8 | <body bgcolor="#ffffff"> | |
9 | <H1><a name="Customization"></a>11 Customization Features</H1> | |
10 | <!-- INDEX --> | |
11 | <div class="sectiontoc"> | |
12 | <ul> | |
13 | <li><a href="#exception">Exception handling with %exception</a> | |
14 | <ul> | |
15 | <li><a href="#Customization_nn3">Handling exceptions in C code</a> | |
16 | <li><a href="#Customization_nn4">Exception handling with longjmp()</a> | |
17 | <li><a href="#Customization_nn5">Handling C++ exceptions</a> | |
18 | <li><a href="#Customization_nn6">Defining different exception handlers</a> | |
19 | <li><a href="#Customization_nn7">Using The SWIG exception library</a> | |
20 | </ul> | |
21 | <li><a href="#ownership">Object ownership and %newobject</a> | |
22 | <li><a href="#features">Features and the %feature directive</a> | |
23 | <ul> | |
24 | <li><a href="#Customization_feature_flags">Feature flags</a> | |
25 | <li><a href="#Customization_clearing_features">Clearing features</a> | |
26 | <li><a href="#Customization_features_default_args">Features and default arguments</a> | |
27 | <li><a href="#features_example">Feature example</a> | |
28 | </ul> | |
29 | </ul> | |
30 | </div> | |
31 | <!-- INDEX --> | |
32 | ||
33 | ||
34 | ||
35 | <p> | |
36 | In many cases, it is desirable to change the default wrapping of | |
37 | particular declarations in an interface. For example, you might want | |
38 | to provide hooks for catching C++ exceptions, add assertions, or | |
39 | provide hints to the underlying code generator. This chapter | |
40 | describes some of these customization techniques. First, a discussion | |
41 | of exception handling is presented. Then, a more general-purpose | |
42 | customization mechanism known as "features" is described. | |
43 | </p> | |
44 | ||
45 | <H2><a name="exception"></a>11.1 Exception handling with %exception</H2> | |
46 | ||
47 | ||
48 | <p> | |
49 | The <tt>%exception</tt> directive allows you to define a general purpose exception | |
50 | handler. For example, you can specify the following: | |
51 | </p> | |
52 | ||
53 | <div class="code"><pre> | |
54 | %exception { | |
55 | try { | |
56 | $action | |
57 | } | |
58 | catch (RangeError) { | |
59 | PyErr_SetString(PyExc_IndexError,"index out-of-bounds"); | |
60 | return NULL; | |
61 | } | |
62 | } | |
63 | </pre></div> | |
64 | ||
65 | <p> | |
66 | When defined, the code enclosed in braces is inserted directly into the low-level wrapper | |
67 | functions. The special symbol <tt>$action</tt> gets replaced with the actual operation | |
68 | to be performed (a function call, method invocation, attribute access, etc.). An exception handler | |
69 | remains in effect until it is explicitly deleted. This is done by using either <tt>%exception</tt> | |
70 | or <tt>%noexception</tt> with no code. For example: | |
71 | </p> | |
72 | ||
73 | <div class="code"><pre> | |
74 | %exception; // Deletes any previously defined handler | |
75 | </pre></div> | |
76 | ||
77 | <p> | |
78 | <b>Compatibility note:</b> Previous versions of SWIG used a special directive <tt>%except</tt> | |
79 | for exception handling. That directive is deprecated--<tt>%exception</tt> | |
80 | provides the same functionality, but is substantially more flexible. | |
81 | </p> | |
82 | ||
83 | <H3><a name="Customization_nn3"></a>11.1.1 Handling exceptions in C code</H3> | |
84 | ||
85 | ||
86 | <p> | |
87 | C has no formal exception handling mechanism so there are several approaches that might be | |
88 | used. A somewhat common technique is to simply set a special error code. For example: | |
89 | </p> | |
90 | ||
91 | <div class="code"><pre> | |
92 | /* File : except.c */ | |
93 | ||
94 | static char error_message[256]; | |
95 | static int error_status = 0; | |
96 | ||
97 | void throw_exception(char *msg) { | |
98 | strncpy(error_message,msg,256); | |
99 | error_status = 1; | |
100 | } | |
101 | ||
102 | void clear_exception() { | |
103 | error_status = 0; | |
104 | } | |
105 | char *check_exception() { | |
106 | if (error_status) return error_message; | |
107 | else return NULL; | |
108 | } | |
109 | ||
110 | </pre></div> | |
111 | ||
112 | <p> | |
113 | To use these functions, functions simply call | |
114 | <tt>throw_exception()</tt> to indicate an error occurred. For example | |
115 | :</p> | |
116 | ||
117 | <div class="code"><pre> | |
118 | double inv(double x) { | |
119 | if (x != 0) return 1.0/x; | |
120 | else { | |
121 | throw_exception("Division by zero"); | |
122 | return 0; | |
123 | } | |
124 | } | |
125 | ||
126 | </pre></div> | |
127 | ||
128 | <p> | |
129 | To catch the exception, you can write a simple exception handler such | |
130 | as the following (shown for Perl5) :</p> | |
131 | ||
132 | <div class="code"><pre> | |
133 | %exception { | |
134 | char *err; | |
135 | clear_exception(); | |
136 | $action | |
137 | if ((err = check_exception())) { | |
138 | croak(err); | |
139 | } | |
140 | } | |
141 | </pre></div> | |
142 | ||
143 | <p> | |
144 | In this case, when an error occurs, it is translated into a Perl error. | |
145 | Each target language has its own approach to creating a runtime error/exception in | |
146 | and for Perl it is the <tt>croak</tt> method shown above. | |
147 | </p> | |
148 | ||
149 | <H3><a name="Customization_nn4"></a>11.1.2 Exception handling with longjmp()</H3> | |
150 | ||
151 | ||
152 | <p> | |
153 | Exception handling can also be added to C code using the | |
154 | <tt><setjmp.h></tt> library. Here is a minimalistic implementation that | |
155 | relies on the C preprocessor : | |
156 | </p> | |
157 | ||
158 | <div class="code"><pre> | |
159 | /* File : except.c | |
160 | Just the declaration of a few global variables we're going to use */ | |
161 | ||
162 | #include <setjmp.h> | |
163 | jmp_buf exception_buffer; | |
164 | int exception_status; | |
165 | ||
166 | /* File : except.h */ | |
167 | #include <setjmp.h> | |
168 | extern jmp_buf exception_buffer; | |
169 | extern int exception_status; | |
170 | ||
171 | #define try if ((exception_status = setjmp(exception_buffer)) == 0) | |
172 | #define catch(val) else if (exception_status == val) | |
173 | #define throw(val) longjmp(exception_buffer,val) | |
174 | #define finally else | |
175 | ||
176 | /* Exception codes */ | |
177 | ||
178 | #define RangeError 1 | |
179 | #define DivisionByZero 2 | |
180 | #define OutOfMemory 3 | |
181 | ||
182 | </pre></div> | |
183 | ||
184 | <p> | |
185 | Now, within a C program, you can do the following :</p> | |
186 | ||
187 | <div class="code"><pre> | |
188 | double inv(double x) { | |
189 | if (x) return 1.0/x; | |
190 | else throw(DivisionByZero); | |
191 | } | |
192 | ||
193 | </pre></div> | |
194 | ||
195 | <p> | |
196 | Finally, to create a SWIG exception handler, write the following :</p> | |
197 | ||
198 | <div class="code"><pre> | |
199 | %{ | |
200 | #include "except.h" | |
201 | %} | |
202 | ||
203 | %exception { | |
204 | try { | |
205 | $action | |
206 | } catch(RangeError) { | |
207 | croak("Range Error"); | |
208 | } catch(DivisionByZero) { | |
209 | croak("Division by zero"); | |
210 | } catch(OutOfMemory) { | |
211 | croak("Out of memory"); | |
212 | } finally { | |
213 | croak("Unknown exception"); | |
214 | } | |
215 | } | |
216 | </pre></div> | |
217 | ||
218 | <p> | |
219 | Note: This implementation is only intended to illustrate the general idea. To make it work better, you'll need to | |
220 | modify it to handle nested <tt>try</tt> declarations. | |
221 | </p> | |
222 | ||
223 | <H3><a name="Customization_nn5"></a>11.1.3 Handling C++ exceptions</H3> | |
224 | ||
225 | ||
226 | <p> | |
227 | Handling C++ exceptions is also straightforward. For example: | |
228 | </p> | |
229 | ||
230 | <div class="code"><pre> | |
231 | %exception { | |
232 | try { | |
233 | $action | |
234 | } catch(RangeError) { | |
235 | croak("Range Error"); | |
236 | } catch(DivisionByZero) { | |
237 | croak("Division by zero"); | |
238 | } catch(OutOfMemory) { | |
239 | croak("Out of memory"); | |
240 | } catch(...) { | |
241 | croak("Unknown exception"); | |
242 | } | |
243 | } | |
244 | ||
245 | </pre></div> | |
246 | ||
247 | <p> | |
248 | The exception types need to be declared as classes elsewhere, possibly | |
249 | in a header file :</p> | |
250 | ||
251 | <div class="code"><pre> | |
252 | class RangeError {}; | |
253 | class DivisionByZero {}; | |
254 | class OutOfMemory {}; | |
255 | </pre> | |
256 | </div> | |
257 | ||
258 | <H3><a name="Customization_nn6"></a>11.1.4 Defining different exception handlers</H3> | |
259 | ||
260 | ||
261 | <p> | |
262 | By default, the <tt>%exception</tt> directive creates an exception | |
263 | handler that is used for all wrapper functions that follow it. Unless | |
264 | there is a well-defined (and simple) error handling mechanism in place, | |
265 | defining one universal exception handler may be unwieldy and result | |
266 | in excessive code bloat since the handler is inlined into each wrapper function. | |
267 | </p> | |
268 | ||
269 | <p> | |
270 | To fix this, you can be more selective about how you use the | |
271 | <tt>%exception</tt> directive. One approach is to only place it around | |
272 | critical pieces of code. For example: | |
273 | </p> | |
274 | ||
275 | <div class="code"><pre> | |
276 | %exception { | |
277 | ... your exception handler ... | |
278 | } | |
279 | /* Define critical operations that can throw exceptions here */ | |
280 | ||
281 | %exception; | |
282 | ||
283 | /* Define non-critical operations that don't throw exceptions */ | |
284 | </pre></div> | |
285 | ||
286 | <p> | |
287 | More precise control over exception handling can be obtained by attaching an exception handler | |
288 | to specific declaration name. For example: | |
289 | </p> | |
290 | ||
291 | <div class="code"> | |
292 | <pre> | |
293 | %exception allocate { | |
294 | try { | |
295 | $action | |
296 | } | |
297 | catch (MemoryError) { | |
298 | croak("Out of memory"); | |
299 | } | |
300 | } | |
301 | </pre> | |
302 | </div> | |
303 | ||
304 | <p> | |
305 | In this case, the exception handler is only attached to declarations | |
306 | named "allocate". This would include both global and member | |
307 | functions. The names supplied to <tt>%exception</tt> follow the same | |
308 | rules as for <tt>%rename</tt> described in the section on | |
309 | <a href="SWIGPlus.html#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>. | |
310 | For example, if you wanted to define | |
311 | an exception handler for a specific class, you might write this: | |
312 | </p> | |
313 | ||
314 | <div class="code"> | |
315 | <pre> | |
316 | %exception Object::allocate { | |
317 | try { | |
318 | $action | |
319 | } | |
320 | catch (MemoryError) { | |
321 | croak("Out of memory"); | |
322 | } | |
323 | } | |
324 | </pre> | |
325 | </div> | |
326 | ||
327 | <p> | |
328 | When a class prefix is supplied, the exception handler is applied to the corresponding declaration | |
329 | in the specified class as well as for identically named functions appearing in derived classes. | |
330 | </p> | |
331 | ||
332 | <p> | |
333 | <tt>%exception</tt> can even be used to pinpoint a precise declaration when overloading is used. For example: | |
334 | </p> | |
335 | ||
336 | <div class="code"> | |
337 | <pre> | |
338 | %exception Object::allocate(int) { | |
339 | try { | |
340 | $action | |
341 | } | |
342 | catch (MemoryError) { | |
343 | croak("Out of memory"); | |
344 | } | |
345 | } | |
346 | </pre> | |
347 | </div> | |
348 | ||
349 | <p> | |
350 | Attaching exceptions to specific declarations is a good way to reduce code bloat. It can also be a useful way | |
351 | to attach exceptions to specific parts of a header file. For example: | |
352 | </p> | |
353 | ||
354 | <div class="code"> | |
355 | <pre> | |
356 | %module example | |
357 | %{ | |
358 | #include "someheader.h" | |
359 | %} | |
360 | ||
361 | // Define a few exception handlers for specific declarations | |
362 | %exception Object::allocate(int) { | |
363 | try { | |
364 | $action | |
365 | } | |
366 | catch (MemoryError) { | |
367 | croak("Out of memory"); | |
368 | } | |
369 | } | |
370 | ||
371 | %exception Object::getitem { | |
372 | try { | |
373 | $action | |
374 | } | |
375 | catch (RangeError) { | |
376 | croak("Index out of range"); | |
377 | } | |
378 | } | |
379 | ... | |
380 | // Read a raw header file | |
381 | %include "someheader.h" | |
382 | </pre> | |
383 | </div> | |
384 | ||
385 | <p> | |
386 | <b>Compatibility note:</b> The <tt>%exception</tt> directive replaces | |
387 | the functionality provided by the deprecated "except" typemap. | |
388 | The typemap would allow exceptions to be thrown in the target | |
389 | language based on the return type of a function and | |
390 | was intended to be a mechanism for pinpointing specific | |
391 | declarations. However, it never really worked that well and the new | |
392 | %exception directive is much better. | |
393 | </p> | |
394 | ||
395 | <H3><a name="Customization_nn7"></a>11.1.5 Using The SWIG exception library</H3> | |
396 | ||
397 | ||
398 | <p> | |
399 | The <tt>exception.i</tt> library file provides support for creating | |
400 | language independent exceptions in your interfaces. To use it, simply | |
401 | put an "<tt>%include exception.i</tt>" in your interface file. This | |
402 | creates a function<tt> SWIG_exception()</tt> that can be used to raise | |
403 | common scripting language exceptions in a portable manner. For example :</p> | |
404 | ||
405 | <div class="code"><pre> | |
406 | // Language independent exception handler | |
407 | %include exception.i | |
408 | ||
409 | %exception { | |
410 | try { | |
411 | $action | |
412 | } catch(RangeError) { | |
413 | SWIG_exception(SWIG_ValueError, "Range Error"); | |
414 | } catch(DivisionByZero) { | |
415 | SWIG_exception(SWIG_DivisionByZero, "Division by zero"); | |
416 | } catch(OutOfMemory) { | |
417 | SWIG_exception(SWIG_MemoryError, "Out of memory"); | |
418 | } catch(...) { | |
419 | SWIG_exception(SWIG_RuntimeError,"Unknown exception"); | |
420 | } | |
421 | } | |
422 | ||
423 | </pre></div> | |
424 | ||
425 | <p> | |
426 | As arguments, <tt>SWIG_exception()</tt> takes an error type code (an | |
427 | integer) and an error message string. The currently supported error | |
428 | types are :</p> | |
429 | ||
430 | <div class="diagram"><pre> | |
431 | SWIG_MemoryError | |
432 | SWIG_IOError | |
433 | SWIG_RuntimeError | |
434 | SWIG_IndexError | |
435 | SWIG_TypeError | |
436 | SWIG_DivisionByZero | |
437 | SWIG_OverflowError | |
438 | SWIG_SyntaxError | |
439 | SWIG_ValueError | |
440 | SWIG_SystemError | |
441 | SWIG_UnknownError | |
442 | </pre></div> | |
443 | ||
444 | <p> | |
445 | Since the <tt>SWIG_exception()</tt> function is defined at the C-level | |
446 | it can be used elsewhere in SWIG. This includes typemaps and helper | |
447 | functions. | |
448 | </p> | |
449 | ||
450 | <H2><a name="ownership"></a>11.2 Object ownership and %newobject</H2> | |
451 | ||
452 | ||
453 | <p> | |
454 | A common problem in some applications is managing proper ownership of objects. For | |
455 | example, consider a function like this: | |
456 | </p> | |
457 | ||
458 | <div class="code"> | |
459 | <pre> | |
460 | Foo *blah() { | |
461 | Foo *f = new Foo(); | |
462 | return f; | |
463 | } | |
464 | </pre> | |
465 | </div> | |
466 | ||
467 | <p> | |
468 | If you wrap the function <tt>blah()</tt>, SWIG has no idea that the | |
469 | return value is a newly allocated object. As a result, the resulting | |
470 | extension module may produce a memory leak (SWIG is conservative and | |
471 | will never delete objects unless it knows for certain that the | |
472 | returned object was newly created). | |
473 | </p> | |
474 | ||
475 | <p> | |
476 | To fix this, you can provide an extra hint to the code generator using | |
477 | the <tt>%newobject</tt> directive. For example: | |
478 | </p> | |
479 | ||
480 | <div class="code"> | |
481 | <pre> | |
482 | %newobject blah; | |
483 | Foo *blah(); | |
484 | </pre> | |
485 | </div> | |
486 | ||
487 | <p> | |
488 | <tt>%newobject</tt> works exactly like <tt>%rename</tt> and <tt>%exception</tt>. In other words, | |
489 | you can attach it to class members and parameterized declarations as before. For example: | |
490 | </p> | |
491 | ||
492 | <div class="code"> | |
493 | <pre> | |
494 | %newobject ::blah(); // Only applies to global blah | |
495 | %newobject Object::blah(int,double); // Only blah(int,double) in Object | |
496 | %newobject *::copy; // Copy method in all classes | |
497 | ... | |
498 | </pre> | |
499 | </div> | |
500 | ||
501 | <p> | |
502 | When <tt>%newobject</tt> is supplied, many language modules will | |
503 | arrange to take ownership of the return value. This allows the value | |
504 | to be automatically garbage-collected when it is no longer in use. However, | |
505 | this depends entirely on the target language (a language module may also choose to ignore | |
506 | the <tt>%newobject</tt> directive). | |
507 | </p> | |
508 | ||
509 | <p> | |
510 | Closely related to <tt>%newobject</tt> is a special typemap. The "newfree" typemap | |
511 | can be used to deallocate a newly allocated return value. It is only available on | |
512 | methods for which <tt>%newobject</tt> has been applied and is commonly used to clean-up string | |
513 | results. For example: | |
514 | </p> | |
515 | ||
516 | <div class="code"> | |
517 | <pre> | |
518 | %typemap(newfree) char * "free($1);"; | |
519 | ... | |
520 | %newobject strdup; | |
521 | ... | |
522 | char *strdup(const char *s); | |
523 | </pre> | |
524 | </div> | |
525 | ||
526 | <p> | |
527 | In this case, the result of the function is a string in the target language. Since this string | |
528 | is a copy of the original result, the data returned by <tt>strdup()</tt> is no longer needed. | |
529 | The "newfree" typemap in the example simply releases this memory. | |
530 | </p> | |
531 | ||
532 | <p> | |
533 | <b>Compatibility note:</b> Previous versions of SWIG had a special <tt>%new</tt> directive. However, unlike <tt>%newobject</tt>, | |
534 | it only applied to the next declaration. For example: | |
535 | </p> | |
536 | ||
537 | <div class="code"> | |
538 | <pre> | |
539 | %new char *strdup(const char *s); | |
540 | </pre> | |
541 | </div> | |
542 | ||
543 | <p> | |
544 | For now this is still supported but is deprecated. | |
545 | </p> | |
546 | ||
547 | <p> | |
548 | <b>How to shoot yourself in the foot:</b> The <tt>%newobject</tt> directive is not a declaration modifier like the old | |
549 | <tt>%new</tt> directive. Don't write code like this: | |
550 | </p> | |
551 | ||
552 | <div class="code"> | |
553 | <pre> | |
554 | %newobject | |
555 | char *strdup(const char *s); | |
556 | </pre> | |
557 | </div> | |
558 | <p> | |
559 | The results might not be what you expect. | |
560 | </p> | |
561 | ||
562 | <H2><a name="features"></a>11.3 Features and the %feature directive</H2> | |
563 | ||
564 | ||
565 | <p> | |
566 | Both <tt>%exception</tt> and <tt>%newobject</tt> are examples of a | |
567 | more general purpose customization mechanism known as "features." A | |
568 | feature is simply a user-definable property that is attached to | |
569 | specific declarations. Features are attached | |
570 | using the <tt>%feature</tt> directive. For example: | |
571 | </p> | |
572 | ||
573 | <div class="code"> | |
574 | <pre> | |
575 | %feature("except") Object::allocate { | |
576 | try { | |
577 | $action | |
578 | } | |
579 | catch (MemoryError) { | |
580 | croak("Out of memory"); | |
581 | } | |
582 | } | |
583 | ||
584 | %feature("new","1") *::copy; | |
585 | </pre> | |
586 | </div> | |
587 | ||
588 | <p> | |
589 | In fact, the <tt>%exception</tt> and <tt>%newobject</tt> directives are really nothing more than macros | |
590 | involving <tt>%feature</tt>: | |
591 | </p> | |
592 | ||
593 | <div class="code"> | |
594 | <pre> | |
595 | #define %exception %feature("except") | |
596 | #define %newobject %feature("new","1") | |
597 | </pre> | |
598 | </div> | |
599 | ||
600 | <p> | |
601 | The name matching rules outlined in the <a href="SWIGPlus.html#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> | |
602 | section applies to all <tt>%feature</tt> directives. | |
603 | In fact the the <tt>%rename</tt> directive is just a special form of <tt>%feature</tt>. | |
604 | The matching rules mean that features are very flexible and can be applied with | |
605 | pinpoint accuracy to specific declarations if needed. | |
606 | Additionally, if no declaration name is given, a global feature is said to be defined. | |
607 | This feature is then | |
608 | attached to <em>every</em> declaration that follows. This is how global exception handlers | |
609 | are defined. For example: | |
610 | </p> | |
611 | ||
612 | <div class="code"> | |
613 | <pre> | |
614 | /* Define a global exception handler */ | |
615 | %feature("except") { | |
616 | try { | |
617 | $action | |
618 | } | |
619 | ... | |
620 | } | |
621 | ||
622 | ... bunch of declarations ... | |
623 | </pre> | |
624 | </div> | |
625 | ||
626 | <p> | |
627 | The <tt>%feature</tt> directive can be used with different syntax. | |
628 | The following are all equivalent: | |
629 | </p> | |
630 | ||
631 | <div class="code"> | |
632 | <pre> | |
633 | %feature("except") Object::method { $action }; | |
634 | %feature("except") Object::method %{ $action %}; | |
635 | %feature("except") Object::method " $action "; | |
636 | %feature("except","$action") Object::method; | |
637 | </pre> | |
638 | </div> | |
639 | ||
640 | <p> | |
641 | The syntax in the first variation will generate the <tt>{ }</tt> delimiters used whereas the other variations will not. | |
642 | The <tt>%feature</tt> directive also accepts XML style attributes in the same way that typemaps will. | |
643 | Any number of attributes can be specified. | |
644 | The following is the generic syntax for features: | |
645 | </p> | |
646 | ||
647 | <div class="code"> | |
648 | <pre> | |
649 | %feature("name","value", attribute1="AttributeValue1") symbol; | |
650 | %feature("name", attribute1="AttributeValue1") symbol {value}; | |
651 | %feature("name", attribute1="AttributeValue1") symbol %{value%}; | |
652 | %feature("name", attribute1="AttributeValue1") symbol "value"; | |
653 | </pre> | |
654 | </div> | |
655 | ||
656 | <p> | |
657 | More than one attribute can be specified using a comma separated list. | |
658 | The Java module is an example that uses attributes in <tt>%feature("except")</tt>. | |
659 | The <tt>throws</tt> attribute specifies the name of a Java class to add to a proxy method's throws clause. | |
660 | In the following example, <tt>MyExceptionClass</tt> is the name of the Java class for adding to the throws clause. | |
661 | </p> | |
662 | ||
663 | <div class="code"> | |
664 | <pre> | |
665 | %feature("except", throws="MyExceptionClass") Object::method { | |
666 | try { | |
667 | $action | |
668 | } catch (...) { | |
669 | ... code to throw a MyExceptionClass Java exception ... | |
670 | } | |
671 | }; | |
672 | </pre> | |
673 | </div> | |
674 | ||
675 | <p> | |
676 | Further details can be obtained from the <a href="Java.html#exception_handling">Java exception handling</a> section. | |
677 | </p> | |
678 | ||
679 | <H3><a name="Customization_feature_flags"></a>11.3.1 Feature flags</H3> | |
680 | ||
681 | ||
682 | <p> | |
683 | Feature flags are used to enable or disable a particular feature. Feature flags are a common but simple usage of <tt>%feature</tt> | |
684 | and the feature value should be either <tt>1</tt> to enable or <tt>0</tt> to disable the feature. | |
685 | </p> | |
686 | ||
687 | <div class="code"> | |
688 | <pre> | |
689 | %feature("name") // enables feature | |
690 | %feature("name", "1") // enables feature | |
691 | %feature("name", "x") // enables feature | |
692 | %feature("name", "0") // disables feature | |
693 | %feature("name", "") // clears feature | |
694 | </pre> | |
695 | </div> | |
696 | ||
697 | <p> | |
698 | Actually any value other than zero will enable the feature. | |
699 | Note that if the value is omitted completely, the default value becomes <tt>1</tt>, thereby enabling the feature. | |
700 | A feature is cleared by specifying no value, see <a href="#Customization_clearing_features">Clearing features</a>. | |
701 | The <tt>%immutable</tt> directive described in the <a href="SWIG.html#SWIG_readonly_variables">Creating read-only variables</a> section, | |
702 | is just a macro for <tt>%feature("immutable")</tt>, and can be used to demonstrates feature flags: | |
703 | </p> | |
704 | ||
705 | <div class="code"> | |
706 | <pre> | |
707 | // features are disabled by default | |
708 | int red; // mutable | |
709 | ||
710 | %feature("immutable"); // global enable | |
711 | int orange; // immutable | |
712 | ||
713 | %feature("immutable","0"); // global disable | |
714 | int yellow; // mutable | |
715 | ||
716 | %feature("immutable","1"); // another form of global enable | |
717 | int green; // immutable | |
718 | ||
719 | %feature("immutable",""); // clears the global feature | |
720 | int blue; // mutable | |
721 | </pre> | |
722 | </div> | |
723 | ||
724 | <p> | |
725 | Note that features are disabled by default and must be explicitly enabled either globally or by specifying a targeted declaration. | |
726 | The above intersperses SWIG directives with C code. Of course you can target features explicitly, so the above could also be rewritten as: | |
727 | </p> | |
728 | ||
729 | <div class="code"> | |
730 | <pre> | |
731 | %feature("immutable","1") orange; | |
732 | %feature("immutable","1") green; | |
733 | int red; // mutable | |
734 | int orange; // immutable | |
735 | int yellow; // mutable | |
736 | int green; // immutable | |
737 | int blue; // mutable | |
738 | </pre> | |
739 | </div> | |
740 | ||
741 | <p> | |
742 | 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. | |
743 | The logic above can of course be inverted and rewritten as: | |
744 | </p> | |
745 | ||
746 | <div class="code"> | |
747 | <pre> | |
748 | %feature("immutable","1"); | |
749 | %feature("immutable","0") red; | |
750 | %feature("immutable","0") yellow; | |
751 | %feature("immutable","0") blue; | |
752 | int red; // mutable | |
753 | int orange; // immutable | |
754 | int yellow; // mutable | |
755 | int green; // immutable | |
756 | int blue; // mutable | |
757 | </pre> | |
758 | </div> | |
759 | ||
760 | ||
761 | <H3><a name="Customization_clearing_features"></a>11.3.2 Clearing features</H3> | |
762 | ||
763 | ||
764 | <p> | |
765 | A feature stays in effect until it is explicitly cleared. A feature is cleared by | |
766 | supplying a <tt>%feature</tt> directive with no value. For example <tt>%feature("name","")</tt>. | |
767 | A cleared feature means that any feature exactly matching any previously defined feature is no longer used in the name matching rules. | |
768 | So if a feature is cleared, it might mean that another name matching rule will apply. | |
769 | To clarify, let's consider the <tt>except</tt> feature again (<tt>%exception</tt>): | |
770 | </p> | |
771 | ||
772 | <div class="code"> | |
773 | <pre> | |
774 | // Define global exception handler | |
775 | %feature("except") { | |
776 | try { | |
777 | $action | |
778 | } catch (...) { | |
779 | croak("Unknown C++ exception"); | |
780 | } | |
781 | } | |
782 | ||
783 | // Define exception handler for all clone methods to log the method calls | |
784 | %feature("except") *::clone() { | |
785 | try { | |
786 | logger.info("$action"); | |
787 | $action | |
788 | } catch (...) { | |
789 | croak("Unknown C++ exception"); | |
790 | } | |
791 | } | |
792 | ||
793 | ... initial set of class declarations with clone methods ... | |
794 | ||
795 | // clear the previously defined feature | |
796 | %feature("except","") *::clone(); | |
797 | ||
798 | ... final set of class declarations with clone methods ... | |
799 | </pre> | |
800 | </div> | |
801 | ||
802 | <p> | |
803 | In the above scenario, the initial set of clone methods will log all method invocations from the target language. | |
804 | This specific feature is cleared for the final set of clone methods. | |
805 | 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. | |
806 | </p> | |
807 | ||
808 | <p> | |
809 | Note that clearing a feature is not always the same as disabling it. | |
810 | Clearing the feature above with <tt>%feature("except","") *::clone()</tt> is not the same as specifying | |
811 | <tt>%feature("except","0") *::clone()</tt>. The former will disable the feature for clone methods - | |
812 | the feature is still a better match than the global feature. | |
813 | If on the other hand, no global exception handler had been defined at all, | |
814 | then clearing the feature would be the same as disabling it as no other feature would have matched. | |
815 | </p> | |
816 | ||
817 | <p> | |
818 | Note that the feature must match exactly for it to be cleared by any previously defined feature. | |
819 | For example the following attempt to clear the initial feature will not work: | |
820 | </p> | |
821 | ||
822 | <div class="code"> | |
823 | <pre> | |
824 | %feature("except") clone() { logger.info("$action"); $action } | |
825 | %feature("except","") *::clone(); | |
826 | </pre> | |
827 | </div> | |
828 | ||
829 | <p> | |
830 | but this will: | |
831 | </p> | |
832 | ||
833 | <div class="code"> | |
834 | <pre> | |
835 | %feature("except") clone() { logger.info("$action"); $action } | |
836 | %feature("except","") clone(); | |
837 | </pre> | |
838 | </div> | |
839 | ||
840 | <H3><a name="Customization_features_default_args"></a>11.3.3 Features and default arguments</H3> | |
841 | ||
842 | ||
843 | <p> | |
844 | SWIG treats methods with default arguments as separate overloaded methods as detailed | |
845 | in the <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> section. | |
846 | Any <tt>%feature</tt> targeting a method with default arguments | |
847 | will apply to all the extra overloaded methods that SWIG generates if the | |
848 | default arguments are specified in the feature. If the default arguments are | |
849 | not specified in the feature, then the feature will match that exact | |
850 | wrapper method only and not the extra overloaded methods that SWIG generates. | |
851 | For example: | |
852 | </p> | |
853 | ||
854 | <div class="code"> | |
855 | <pre> | |
856 | %feature("except") void hello(int i=0, double d=0.0) { ... } | |
857 | void hello(int i=0, double d=0.0); | |
858 | </pre> | |
859 | </div> | |
860 | ||
861 | <p> | |
862 | will apply the feature to all three wrapper methods, that is: | |
863 | </p> | |
864 | ||
865 | <div class="code"> | |
866 | <pre> | |
867 | void hello(int i, double d); | |
868 | void hello(int i); | |
869 | void hello(); | |
870 | </pre> | |
871 | </div> | |
872 | ||
873 | <p> | |
874 | If the default arguments are not specified in the feature: | |
875 | </p> | |
876 | ||
877 | <div class="code"> | |
878 | <pre> | |
879 | %feature("except") void hello(int i, double d) { ... } | |
880 | void hello(int i=0, double d=0.0); | |
881 | </pre> | |
882 | </div> | |
883 | ||
884 | <p> | |
885 | then the feature will only apply to this wrapper method: | |
886 | </p> | |
887 | ||
888 | <div class="code"> | |
889 | <pre> | |
890 | void hello(int i, double d); | |
891 | </pre> | |
892 | </div> | |
893 | ||
894 | <p> | |
895 | and not these wrapper methods: | |
896 | </p> | |
897 | ||
898 | <div class="code"> | |
899 | <pre> | |
900 | void hello(int i); | |
901 | void hello(); | |
902 | </pre> | |
903 | </div> | |
904 | ||
905 | <p> | |
906 | If <a href="SWIGPlus.html#SWIGPlus_default_args">compactdefaultargs</a> are being used, then the difference between | |
907 | specifying or not specifying default arguments in a feature is not applicable as just one wrapper is generated. | |
908 | </p> | |
909 | ||
910 | <p> | |
911 | <b>Compatibility note:</b> The different behaviour of features specified with or without default arguments was introduced | |
912 | in SWIG-1.3.23 when the approach to wrapping methods with default arguments was changed. | |
913 | </p> | |
914 | ||
915 | <H3><a name="features_example"></a>11.3.4 Feature example</H3> | |
916 | ||
917 | ||
918 | <p> | |
919 | 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 | |
920 | declarations with additional information for use by specific target language modules. Another example is | |
921 | in the Python module. You might use <tt>%feature</tt> to rewrite proxy/shadow class code as follows: | |
922 | </p> | |
923 | ||
924 | <div class="code"> | |
925 | <pre> | |
926 | %module example | |
927 | %rename(bar_id) bar(int,double); | |
928 | ||
929 | // Rewrite bar() to allow some nice overloading | |
930 | ||
931 | %feature("shadow") Foo::bar(int) %{ | |
932 | def bar(*args): | |
933 | if len(args) == 3: | |
934 | return apply(examplec.Foo_bar_id,args) | |
935 | return apply(examplec.Foo_bar,args) | |
936 | %} | |
937 | ||
938 | class Foo { | |
939 | public: | |
940 | int bar(int x); | |
941 | int bar(int x, double y); | |
942 | } | |
943 | </pre> | |
944 | </div> | |
945 | ||
946 | <p> | |
947 | Further details of <tt>%feature</tt> usage is described in the documentation for specific language modules. | |
948 | </p> | |
949 | ||
950 | </body> | |
951 | </html> |