diff options
Diffstat (limited to 'Doc/Manual/SWIGDocumentation.html')
| -rw-r--r-- | Doc/Manual/SWIGDocumentation.html | 50041 |
1 files changed, 50041 insertions, 0 deletions
diff --git a/Doc/Manual/SWIGDocumentation.html b/Doc/Manual/SWIGDocumentation.html new file mode 100644 index 0000000..a998b95 --- /dev/null +++ b/Doc/Manual/SWIGDocumentation.html @@ -0,0 +1,50041 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> +<HTML> +<HEAD> +<TITLE>SWIG-1.3 Documentation</TITLE> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-iso-8859-1"> +<STYLE TYPE="text/css"><!-- +div.sectiontoc { + border-style: dotted; + border-width: 2px; + padding: 2pt; +} + +h2 { + padding: 3px; + color: #000000; + border-bottom: 2px + solid #dddddd; +} + +h3, h4 { + margin-left: 1em; +} + +p,li,table,dl { + margin-left: 2em; + margin-right: 2em; +} + +div.indent { + margin-left: 4em; + margin-right: 4em; +} + +div.code { + border-style: solid; + border-width: 1px; + padding: 2pt; + margin-left: 4em; + margin-right: 4em; + background-color: #F0FFFF; +} + +div.targetlang { + border-style: solid; + border-width: 1px; + padding: 2pt; + margin-left: 4em; + margin-right: 4em; + background-color: #d7f6bb; +} + + +div.shell { + border-style: solid; + border-width: 1px; + padding: 2pt; + margin-left: 4em; + margin-right: 4em; + background-color: #DCDCDC; +} + +div.diagram { + border-style: solid; + border-width: 1px; + padding: 2pt; + margin-left: 4em; + margin-right: 4em; + background-color: #FFEBCD; +} + +ul li p { + margin-left: 0; + margin-right: 0; +} + +ol li p { + margin-left: 0; + margin-right: 0; +} + +dl dd p { + margin-left: 0; + margin-right: 0; +} + +div.indent p { + margin-left: 0; + margin-right: 0; +} + + +BODY { font-family: serif } +H1 { font-family: sans-serif } +H2 { font-family: sans-serif } +H3 { font-family: sans-serif } +H4 { font-family: sans-serif } +H5 { font-family: sans-serif } +H6 { font-family: sans-serif } +SUB { font-size: smaller } +SUP { font-size: smaller } +PRE { font-family: monospace } +--></STYLE> +</HEAD> +<BODY BGCOLOR="#ffffff" LINK="#0000ff" VLINK="#0000ff" ALINK="#0000ff"> +<CENTER><A HREF="#CONTENTS"><IMG SRC="swig16.png" BORDER="0" WIDTH="167" HEIGHT="85" ALT="SWIG-1.3 Documentation"><BR> +<H1>SWIG-1.3 Documentation</H1></A><BR> +</CENTER> +<HR NOSHADE> +<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1> +<BR> +<BR><B><A HREF="#Sections">SWIG-1.3 Development Documentation</A></B> +<UL> +<LI><A HREF="#1_1">Sections</A> +<UL> +<LI><A HREF="#1_1_1">SWIG Core Documentation</A></LI> +<LI><A HREF="#1_1_2">Language Module Documentation</A></LI> +<LI><A HREF="#1_1_3">Developer Documentation</A></LI> +<LI><A HREF="#1_1_4">Documentation that has not yet been updated</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Preface">1 Preface</A></B> +<UL> +<LI><A HREF="#Preface_nn2">1.1 Introduction</A></LI> +<LI><A HREF="#Preface_nn3">1.2 Special Introduction for Version 1.3</A></LI> +<LI><A HREF="#Preface_nn4">1.3 SWIG Versions</A></LI> +<LI><A HREF="#Preface_nn5">1.4 SWIG resources</A></LI> +<LI><A HREF="#Preface_nn6">1.5 Prerequisites</A></LI> +<LI><A HREF="#Preface_nn7">1.6 Organization of this manual</A></LI> +<LI><A HREF="#Preface_nn8">1.7 How to avoid reading the manual</A></LI> +<LI><A HREF="#Preface_nn9">1.8 Backwards Compatibility</A></LI> +<LI><A HREF="#Preface_nn10">1.9 Credits</A></LI> +<LI><A HREF="#Preface_nn11">1.10 Bug reports</A></LI> +</UL> +<B><A HREF="#Introduction">2 Introduction</A></B> +<UL> +<LI><A HREF="#Introduction_nn2">2.1 What is SWIG?</A></LI> +<LI><A HREF="#Introduction_nn3">2.2 Why use SWIG?</A></LI> +<LI><A HREF="#Introduction_nn4">2.3 A SWIG example</A> +<UL> +<LI><A HREF="#Introduction_nn5">2.3.1 SWIG interface file</A></LI> +<LI><A HREF="#Introduction_nn6">2.3.2 The swig command</A></LI> +<LI><A HREF="#Introduction_nn7">2.3.3 Building a Perl5 module</A></LI> +<LI><A HREF="#Introduction_nn8">2.3.4 Building a Python module</A></LI> +<LI><A HREF="#Introduction_nn9">2.3.5 Shortcuts</A></LI> +</UL> +</LI> +<LI><A HREF="#Introduction_nn10">2.4 Supported C/C++ language features</A> +</LI> +<LI><A HREF="#Introduction_nn11">2.5 Non-intrusive interface building</A> +</LI> +<LI><A HREF="#Introduction_build_system">2.6 Incorporating SWIG into a + build system</A></LI> +<LI><A HREF="#Introduction_nn12">2.7 Hands off code generation</A></LI> +<LI><A HREF="#Introduction_nn13">2.8 SWIG and freedom</A></LI> +</UL> +<B><A HREF="#Windows">3 Getting started on Windows</A></B> +<UL> +<LI><A HREF="#Windows_installation">3.1 Installation on Windows</A> +<UL> +<LI><A HREF="#Windows_executable">3.1.1 Windows Executable</A></LI> +</UL> +</LI> +<LI><A HREF="#Windows_examples">3.2 SWIG Windows Examples</A> +<UL> +<LI><A HREF="#Windows_visual_studio">3.2.1 Instructions for using the + Examples with Visual Studio</A> +<UL> +<LI><A HREF="#Windows_csharp">3.2.1.1 C#</A></LI> +<LI><A HREF="#Windows_java">3.2.1.2 Java</A></LI> +<LI><A HREF="#Windows_perl">3.2.1.3 Perl</A></LI> +<LI><A HREF="#Windows_python">3.2.1.4 Python</A></LI> +<LI><A HREF="#Windows_tcl">3.2.1.5 TCL</A></LI> +<LI><A HREF="#Windows_r">3.2.1.6 R</A></LI> +<LI><A HREF="#Windows_ruby">3.2.1.7 Ruby</A></LI> +</UL> +</LI> +<LI><A HREF="#Windows_other_compilers">3.2.2 Instructions for using the + Examples with other compilers</A></LI> +</UL> +</LI> +<LI><A HREF="#Windows_cygwin_mingw">3.3 SWIG on Cygwin and MinGW</A> +<UL> +<LI><A HREF="#Windows_swig_exe">3.3.1 Building swig.exe on Windows</A> +<UL> +<LI><A HREF="#Windows_mingw_msys">3.3.1.1 Building swig.exe using MinGW + and MSYS</A></LI> +<LI><A HREF="#Windows_cygwin">3.3.1.2 Building swig.exe using Cygwin</A></LI> +<LI><A HREF="#Windows_building_alternatives">3.3.1.3 Building swig.exe + alternatives</A></LI> +</UL> +</LI> +<LI><A HREF="#Windows_examples_cygwin">3.3.2 Running the examples on + Windows using Cygwin</A></LI> +</UL> +</LI> +<LI><A HREF="#Windows_interface_file">3.4 Microsoft extensions and other + Windows quirks</A></LI> +</UL> +<B><A HREF="#Scripting">4 Scripting Languages</A></B> +<UL> +<LI><A HREF="#Scripting_nn2">4.1 The two language view of the world</A></LI> +<LI><A HREF="#Scripting_nn3">4.2 How does a scripting language talk to + C?</A> +<UL> +<LI><A HREF="#Scripting_nn4">4.2.1 Wrapper functions</A></LI> +<LI><A HREF="#Scripting_nn5">4.2.2 Variable linking</A></LI> +<LI><A HREF="#Scripting_nn6">4.2.3 Constants</A></LI> +<LI><A HREF="#Scripting_nn7">4.2.4 Structures and classes</A></LI> +<LI><A HREF="#Scripting_nn8">4.2.5 Proxy classes</A></LI> +</UL> +</LI> +<LI><A HREF="#Scripting_nn9">4.3 Building scripting language extensions</A> +<UL> +<LI><A HREF="#Scripting_nn10">4.3.1 Shared libraries and dynamic loading</A> +</LI> +<LI><A HREF="#Scripting_nn11">4.3.2 Linking with shared libraries</A></LI> +<LI><A HREF="#Scripting_nn12">4.3.3 Static linking</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#SWIG">5 SWIG Basics</A></B> +<UL> +<LI><A HREF="#SWIG_nn2">5.1 Running SWIG</A> +<UL> +<LI><A HREF="#SWIG_nn3">5.1.1 Input format</A></LI> +<LI><A HREF="#output">5.1.2 SWIG Output</A></LI> +<LI><A HREF="#SWIG_nn5">5.1.3 Comments</A></LI> +<LI><A HREF="#SWIG_nn6">5.1.4 C Preprocessor</A></LI> +<LI><A HREF="#SWIG_nn7">5.1.5 SWIG Directives</A></LI> +<LI><A HREF="#SWIG_nn8">5.1.6 Parser Limitations</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIG_nn9">5.2 Wrapping Simple C Declarations</A> +<UL> +<LI><A HREF="#SWIG_nn10">5.2.1 Basic Type Handling</A></LI> +<LI><A HREF="#SWIG_nn11">5.2.2 Global Variables</A></LI> +<LI><A HREF="#SWIG_nn12">5.2.3 Constants</A></LI> +<LI><A HREF="#SWIG_nn13">5.2.4 A brief word about const</A></LI> +<LI><A HREF="#SWIG_nn14">5.2.5 A cautionary tale of char *</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIG_nn15">5.3 Pointers and complex objects</A> +<UL> +<LI><A HREF="#SWIG_nn16">5.3.1 Simple pointers</A></LI> +<LI><A HREF="#SWIG_nn17">5.3.2 Run time pointer type checking</A></LI> +<LI><A HREF="#SWIG_nn18">5.3.3 Derived types, structs, and classes</A></LI> +<LI><A HREF="#SWIG_nn19">5.3.4 Undefined datatypes</A></LI> +<LI><A HREF="#SWIG_nn20">5.3.5 Typedef</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIG_nn21">5.4 Other Practicalities</A> +<UL> +<LI><A HREF="#SWIG_nn22">5.4.1 Passing structures by value</A></LI> +<LI><A HREF="#SWIG_nn23">5.4.2 Return by value</A></LI> +<LI><A HREF="#SWIG_nn24">5.4.3 Linking to structure variables</A></LI> +<LI><A HREF="#SWIG_nn25">5.4.4 Linking to char *</A></LI> +<LI><A HREF="#SWIG_nn26">5.4.5 Arrays</A></LI> +<LI><A HREF="#SWIG_readonly_variables">5.4.6 Creating read-only + variables</A></LI> +<LI><A HREF="#SWIG_rename_ignore">5.4.7 Renaming and ignoring + declarations</A></LI> +<LI><A HREF="#SWIG_default_args">5.4.8 Default/optional arguments</A></LI> +<LI><A HREF="#SWIG_nn30">5.4.9 Pointers to functions and callbacks</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIG_nn31">5.5 Structures and unions</A> +<UL> +<LI><A HREF="#SWIG_nn32">5.5.1 Typedef and structures</A></LI> +<LI><A HREF="#SWIG_nn33">5.5.2 Character strings and structures</A></LI> +<LI><A HREF="#SWIG_nn34">5.5.3 Array members</A></LI> +<LI><A HREF="#SWIG_structure_data_members">5.5.4 Structure data members</A> +</LI> +<LI><A HREF="#SWIG_nn36">5.5.5 C constructors and destructors</A></LI> +<LI><A HREF="#SWIG_adding_member_functions">5.5.6 Adding member + functions to C structures</A></LI> +<LI><A HREF="#SWIG_nested_structs">5.5.7 Nested structures</A></LI> +<LI><A HREF="#SWIG_nn39">5.5.8 Other things to note about structure + wrapping</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIG_nn40">5.6 Code Insertion</A> +<UL> +<LI><A HREF="#SWIG_nn41">5.6.1 The output of SWIG</A></LI> +<LI><A HREF="#SWIG_nn42">5.6.2 Code insertion blocks</A></LI> +<LI><A HREF="#SWIG_nn43">5.6.3 Inlined code blocks</A></LI> +<LI><A HREF="#SWIG_nn44">5.6.4 Initialization blocks</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIG_nn45">5.7 An Interface Building Strategy</A> +<UL> +<LI><A HREF="#SWIG_nn46">5.7.1 Preparing a C program for SWIG</A></LI> +<LI><A HREF="#SWIG_nn47">5.7.2 The SWIG interface file</A></LI> +<LI><A HREF="#SWIG_nn48">5.7.3 Why use separate interface files?</A></LI> +<LI><A HREF="#SWIG_nn49">5.7.4 Getting the right header files</A></LI> +<LI><A HREF="#SWIG_nn50">5.7.5 What to do with main()</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#SWIGPlus">6 SWIG and C++</A></B> +<UL> +<LI><A HREF="#SWIGPlus_nn2">6.1 Comments on C++ Wrapping</A></LI> +<LI><A HREF="#SWIGPlus_nn3">6.2 Approach</A></LI> +<LI><A HREF="#SWIGPlus_nn4">6.3 Supported C++ features</A></LI> +<LI><A HREF="#SWIGPlus_nn5">6.4 Command line options and compilation</A></LI> +<LI><A HREF="#SWIGPlus_nn38">6.5 Proxy classes</A> +<UL> +<LI><A HREF="#SWIGPlus_nn39">6.5.1 Construction of proxy classes</A></LI> +<LI><A HREF="#SWIGPlus_nn40">6.5.2 Resource management in proxies</A></LI> +<LI><A HREF="#SWIGPlus_nn41">6.5.3 Language specific details</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIGPlus_nn6">6.6 Simple C++ wrapping</A> +<UL> +<LI><A HREF="#SWIGPlus_nn7">6.6.1 Constructors and destructors</A></LI> +<LI><A HREF="#SWIGPlus_nn8">6.6.2 Default constructors, copy + constructors and implicit destructors</A></LI> +<LI><A HREF="#SWIGPlus_nn9">6.6.3 When constructor wrappers aren't + created</A></LI> +<LI><A HREF="#SWIGPlus_nn10">6.6.4 Copy constructors</A></LI> +<LI><A HREF="#SWIGPlus_nn11">6.6.5 Member functions</A></LI> +<LI><A HREF="#SWIGPlus_nn12">6.6.6 Static members</A></LI> +<LI><A HREF="#SWIGPlus_member_data">6.6.7 Member data</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIGPlus_default_args">6.7 Default arguments</A></LI> +<LI><A HREF="#SWIGPlus_nn15">6.8 Protection</A></LI> +<LI><A HREF="#SWIGPlus_nn16">6.9 Enums and constants</A></LI> +<LI><A HREF="#SWIGPlus_nn17">6.10 Friends</A></LI> +<LI><A HREF="#SWIGPlus_nn18">6.11 References and pointers</A></LI> +<LI><A HREF="#SWIGPlus_nn19">6.12 Pass and return by value</A></LI> +<LI><A HREF="#SWIGPlus_nn20">6.13 Inheritance</A></LI> +<LI><A HREF="#SWIGPlus_nn21">6.14 A brief discussion of multiple + inheritance, pointers, and type checking</A></LI> +<LI><A HREF="#SWIGPlus_overloaded_methods">6.15 Wrapping Overloaded + Functions and Methods</A> +<UL> +<LI><A HREF="#SWIGPlus_nn24">6.15.1 Dispatch function generation</A></LI> +<LI><A HREF="#SWIGPlus_nn25">6.15.2 Ambiguity in Overloading</A></LI> +<LI><A HREF="#ambiguity_resolution_renaming">6.15.3 Ambiguity resolution + and renaming</A></LI> +<LI><A HREF="#SWIGPlus_nn27">6.15.4 Comments on overloading</A></LI> +</UL> +</LI> +<LI><A HREF="#SWIGPlus_nn28">6.16 Wrapping overloaded operators</A></LI> +<LI><A HREF="#SWIGPlus_class_extension">6.17 Class extension</A></LI> +<LI><A HREF="#SWIGPlus_nn30">6.18 Templates</A></LI> +<LI><A HREF="#SWIGPlus_nn31">6.19 Namespaces</A></LI> +<LI><A HREF="#SWIGPlus_renaming_templated_types_namespaces">6.20 + Renaming templated types in namespaces</A></LI> +<LI><A HREF="#SWIGPlus_exception_specifications">6.21 Exception + specifications</A></LI> +<LI><A HREF="#SWIGPlus_catches">6.22 Exception handling with %catches</A> +</LI> +<LI><A HREF="#SWIGPlus_nn33">6.23 Pointers to Members</A></LI> +<LI><A HREF="#SWIGPlus_nn34">6.24 Smart pointers and operator->()</A></LI> +<LI><A HREF="#SWIGPlus_nn35">6.25 Using declarations and inheritance</A></LI> +<LI><A HREF="#SWIGPlus_nested_classes">6.26 Nested classes</A></LI> +<LI><A HREF="#SWIGPlus_nn37">6.27 A brief rant about const-correctness</A> +</LI> +<LI><A HREF="#SWIGPlus_nn42">6.28 Where to go for more information</A></LI> +</UL> +<B><A HREF="#Preprocessor">7 Preprocessing</A></B> +<UL> +<LI><A HREF="#Preprocessor_nn2">7.1 File inclusion</A></LI> +<LI><A HREF="#Preprocessor_nn3">7.2 File imports</A></LI> +<LI><A HREF="#Preprocessor_condition_compilation">7.3 Conditional + Compilation</A></LI> +<LI><A HREF="#Preprocessor_nn5">7.4 Macro Expansion</A></LI> +<LI><A HREF="#Preprocessor_nn6">7.5 SWIG Macros</A></LI> +<LI><A HREF="#Preprocessor_nn7">7.6 C99 and GNU Extensions</A></LI> +<LI><A HREF="#Preprocessor_nn8">7.7 Preprocessing and %{ ... %} & " ... + " delimiters</A></LI> +<LI><A HREF="#Preprocessor_nn9">7.8 Preprocessing and { ... } delimiters</A> +</LI> +<LI><A HREF="#Preprocessor_typemap_delimiters">7.9 Preprocessor and + Typemaps</A></LI> +<LI><A HREF="#Preprocessor_nn10">7.10 Viewing preprocessor output</A></LI> +<LI><A HREF="#Preprocessor_warning_error">7.11 The #error and #warning + directives</A></LI> +</UL> +<B><A HREF="#Library">8 SWIG library</A></B> +<UL> +<LI><A HREF="#Library_nn2">8.1 The %include directive and library search + path</A></LI> +<LI><A HREF="#Library_nn3">8.2 C Arrays and Pointers</A> +<UL> +<LI><A HREF="#Library_nn4">8.2.1 cpointer.i</A></LI> +<LI><A HREF="#Library_carrays">8.2.2 carrays.i</A></LI> +<LI><A HREF="#Library_nn6">8.2.3 cmalloc.i</A></LI> +<LI><A HREF="#Library_nn7">8.2.4 cdata.i</A></LI> +</UL> +</LI> +<LI><A HREF="#Library_nn8">8.3 C String Handling</A> +<UL> +<LI><A HREF="#Library_nn9">8.3.1 Default string handling</A></LI> +<LI><A HREF="#Library_nn10">8.3.2 Passing binary data</A></LI> +<LI><A HREF="#Library_nn11">8.3.3 Using %newobject to release memory</A></LI> +<LI><A HREF="#Library_nn12">8.3.4 cstring.i</A></LI> +</UL> +</LI> +<LI><A HREF="#Library_stl_cpp_library">8.4 STL/C++ Library</A> +<UL> +<LI><A HREF="#Library_nn14">8.4.1 std_string.i</A></LI> +<LI><A HREF="#Library_nn15">8.4.2 std_vector.i</A></LI> +<LI><A HREF="#Library_stl_exceptions">8.4.3 STL exceptions</A></LI> +</UL> +</LI> +<LI><A HREF="#Library_nn16">8.5 Utility Libraries</A> +<UL> +<LI><A HREF="#Library_nn17">8.5.1 exception.i</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Arguments">9 Argument Handling</A></B> +<UL> +<LI><A HREF="#Arguments_nn2">9.1 The typemaps.i library</A> +<UL> +<LI><A HREF="#Arguments_nn3">9.1.1 Introduction</A></LI> +<LI><A HREF="#Arguments_nn4">9.1.2 Input parameters</A></LI> +<LI><A HREF="#Arguments_nn5">9.1.3 Output parameters</A></LI> +<LI><A HREF="#Arguments_nn6">9.1.4 Input/Output parameters</A></LI> +<LI><A HREF="#Arguments_nn7">9.1.5 Using different names</A></LI> +</UL> +</LI> +<LI><A HREF="#Arguments_nn8">9.2 Applying constraints to input values</A> +<UL> +<LI><A HREF="#Arguments_nn9">9.2.1 Simple constraint example</A></LI> +<LI><A HREF="#Arguments_nn10">9.2.2 Constraint methods</A></LI> +<LI><A HREF="#Arguments_nn11">9.2.3 Applying constraints to new + datatypes</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Typemaps">10 Typemaps</A></B> +<UL> +<LI><A HREF="#Typemaps_nn2">10.1 Introduction</A> +<UL> +<LI><A HREF="#Typemaps_nn3">10.1.1 Type conversion</A></LI> +<LI><A HREF="#Typemaps_nn4">10.1.2 Typemaps</A></LI> +<LI><A HREF="#Typemaps_nn5">10.1.3 Pattern matching</A></LI> +<LI><A HREF="#Typemaps_nn6">10.1.4 Reusing typemaps</A></LI> +<LI><A HREF="#Typemaps_nn7">10.1.5 What can be done with typemaps?</A></LI> +<LI><A HREF="#Typemaps_nn8">10.1.6 What can't be done with typemaps?</A></LI> +<LI><A HREF="#Typemaps_nn9">10.1.7 The rest of this chapter</A></LI> +</UL> +</LI> +<LI><A HREF="#Typemaps_nn10">10.2 Typemap specifications</A> +<UL> +<LI><A HREF="#Typemaps_defining">10.2.1 Defining a typemap</A></LI> +<LI><A HREF="#Typemaps_nn12">10.2.2 Typemap scope</A></LI> +<LI><A HREF="#Typemaps_nn13">10.2.3 Copying a typemap</A></LI> +<LI><A HREF="#Typemaps_nn14">10.2.4 Deleting a typemap</A></LI> +<LI><A HREF="#Typemaps_nn15">10.2.5 Placement of typemaps</A></LI> +</UL> +</LI> +<LI><A HREF="#Typemaps_pattern_matching">10.3 Pattern matching rules</A> +<UL> +<LI><A HREF="#Typemaps_nn17">10.3.1 Basic matching rules</A></LI> +<LI><A HREF="#Typemaps_nn18">10.3.2 Typedef reductions</A></LI> +<LI><A HREF="#Typemaps_nn19">10.3.3 Default typemaps</A></LI> +<LI><A HREF="#Typemaps_mixed_default">10.3.4 Mixed default typemaps</A></LI> +<LI><A HREF="#Typemaps_nn20">10.3.5 Multi-arguments typemaps</A></LI> +</UL> +</LI> +<LI><A HREF="#Typemaps_nn21">10.4 Code generation rules</A> +<UL> +<LI><A HREF="#Typemaps_nn22">10.4.1 Scope</A></LI> +<LI><A HREF="#Typemaps_nn23">10.4.2 Declaring new local variables</A></LI> +<LI><A HREF="#Typemaps_special_variables">10.4.3 Special variables</A></LI> +<LI><A HREF="#Typemaps_special_variable_macros">10.4.4 Special variable + macros</A> +<UL> +<LI><A HREF="#Typemaps_special_macro_descriptor">10.4.4.1 + $descriptor(type)</A></LI> +<LI><A HREF="#Typemaps_special_macro_typemap">10.4.4.2 $typemap(method, + typepattern)</A></LI> +</UL> +</LI> +</UL> +</LI> +<LI><A HREF="#Typemaps_nn25">10.5 Common typemap methods</A> +<UL> +<LI><A HREF="#Typemaps_nn26">10.5.1 "in" typemap</A></LI> +<LI><A HREF="#Typemaps_nn27">10.5.2 "typecheck" typemap</A></LI> +<LI><A HREF="#Typemaps_nn28">10.5.3 "out" typemap</A></LI> +<LI><A HREF="#Typemaps_nn29">10.5.4 "arginit" typemap</A></LI> +<LI><A HREF="#Typemaps_nn30">10.5.5 "default" typemap</A></LI> +<LI><A HREF="#Typemaps_nn31">10.5.6 "check" typemap</A></LI> +<LI><A HREF="#Typemaps_nn32">10.5.7 "argout" typemap</A></LI> +<LI><A HREF="#Typemaps_nn33">10.5.8 "freearg" typemap</A></LI> +<LI><A HREF="#Typemaps_nn34">10.5.9 "newfree" typemap</A></LI> +<LI><A HREF="#Typemaps_nn35">10.5.10 "memberin" typemap</A></LI> +<LI><A HREF="#Typemaps_nn36">10.5.11 "varin" typemap</A></LI> +<LI><A HREF="#Typemaps_nn37">10.5.12 "varout" typemap</A></LI> +<LI><A HREF="#throws_typemap">10.5.13 "throws" typemap</A></LI> +</UL> +</LI> +<LI><A HREF="#Typemaps_nn39">10.6 Some typemap examples</A> +<UL> +<LI><A HREF="#Typemaps_nn40">10.6.1 Typemaps for arrays</A></LI> +<LI><A HREF="#Typemaps_nn41">10.6.2 Implementing constraints with + typemaps</A></LI> +</UL> +</LI> +<LI><A HREF="#Typemaps_nn43">10.7 Typemaps for multiple languages</A></LI> +<LI><A HREF="#Typemaps_optimal">10.8 Optimal code generation when + returning by value</A></LI> +<LI><A HREF="#Typemaps_multi_argument_typemaps">10.9 Multi-argument + typemaps</A></LI> +<LI><A HREF="#runtime_type_checker">10.10 The run-time type checker</A> +<UL> +<LI><A HREF="#Typemaps_nn45">10.10.1 Implementation</A></LI> +<LI><A HREF="#Typemaps_runtime_type_checker_usage">10.10.2 Usage</A></LI> +</UL> +</LI> +<LI><A HREF="#Typemaps_overloading">10.11 Typemaps and overloading</A></LI> +<LI><A HREF="#Typemaps_nn48">10.12 More about %apply and %clear</A></LI> +<LI><A HREF="#Typemaps_nn49">10.13 Reducing wrapper code size</A></LI> +<LI><A HREF="#Typemaps_nn47">10.14 Passing data between typemaps</A></LI> +<LI><A HREF="#Typemaps_nn52">10.15 C++ "this" pointer</A></LI> +<LI><A HREF="#Typemaps_nn51">10.16 Where to go for more information?</A></LI> +</UL> +<B><A HREF="#Customization">11 Customization Features</A></B> +<UL> +<LI><A HREF="#exception">11.1 Exception handling with %exception</A> +<UL> +<LI><A HREF="#Customization_nn3">11.1.1 Handling exceptions in C code</A> +</LI> +<LI><A HREF="#Customization_nn4">11.1.2 Exception handling with + longjmp()</A></LI> +<LI><A HREF="#Customization_nn5">11.1.3 Handling C++ exceptions</A></LI> +<LI><A HREF="#Customization_allowexcept">11.1.4 Exception handlers for + variables</A></LI> +<LI><A HREF="#Customization_nn6">11.1.5 Defining different exception + handlers</A></LI> +<LI><A HREF="#Customization_exception_special_variables">11.1.6 Special + variables for %exception</A></LI> +<LI><A HREF="#Customization_nn7">11.1.7 Using The SWIG exception library</A> +</LI> +</UL> +</LI> +<LI><A HREF="#ownership">11.2 Object ownership and %newobject</A></LI> +<LI><A HREF="#features">11.3 Features and the %feature directive</A> +<UL> +<LI><A HREF="#Customization_feature_attributes">11.3.1 Feature + attributes</A></LI> +<LI><A HREF="#Customization_feature_flags">11.3.2 Feature flags</A></LI> +<LI><A HREF="#Customization_clearing_features">11.3.3 Clearing features</A> +</LI> +<LI><A HREF="#Customization_features_default_args">11.3.4 Features and + default arguments</A></LI> +<LI><A HREF="#features_example">11.3.5 Feature example</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Contract">12 Contracts</A></B> +<UL> +<LI><A HREF="#Contract_nn2">12.1 The %contract directive</A></LI> +<LI><A HREF="#Contract_nn3">12.2 %contract and classes</A></LI> +<LI><A HREF="#Contract_nn4">12.3 Constant aggregation and + %aggregate_check</A></LI> +<LI><A HREF="#Contract_nn5">12.4 Notes</A></LI> +</UL> +<B><A HREF="#Varargs">13 Variable Length Arguments</A></B> +<UL> +<LI><A HREF="#Varargs_nn2">13.1 Introduction</A></LI> +<LI><A HREF="#Varargs_nn3">13.2 The Problem</A></LI> +<LI><A HREF="#Varargs_nn4">13.3 Default varargs support</A></LI> +<LI><A HREF="#Varargs_nn5">13.4 Argument replacement using %varargs</A></LI> +<LI><A HREF="#Varargs_nn6">13.5 Varargs and typemaps</A></LI> +<LI><A HREF="#Varargs_nn7">13.6 Varargs wrapping with libffi</A></LI> +<LI><A HREF="#Varargs_nn8">13.7 Wrapping of va_list</A></LI> +<LI><A HREF="#Varargs_nn9">13.8 C++ Issues</A></LI> +<LI><A HREF="#Varargs_nn10">13.9 Discussion</A></LI> +</UL> +<B><A HREF="#Warnings">14 Warning Messages</A></B> +<UL> +<LI><A HREF="#Warnings_nn2">14.1 Introduction</A></LI> +<LI><A HREF="#Warnings_suppression">14.2 Warning message suppression</A></LI> +<LI><A HREF="#Warnings_nn4">14.3 Enabling extra warnings</A></LI> +<LI><A HREF="#Warnings_nn5">14.4 Issuing a warning message</A></LI> +<LI><A HREF="#Warnings_symbolic_symbols">14.5 Symbolic symbols</A></LI> +<LI><A HREF="#Warnings_nn6">14.6 Commentary</A></LI> +<LI><A HREF="#Warnings_nn7">14.7 Warnings as errors</A></LI> +<LI><A HREF="#Warnings_nn8">14.8 Message output format</A></LI> +<LI><A HREF="#Warnings_nn9">14.9 Warning number reference</A> +<UL> +<LI><A HREF="#Warnings_nn10">14.9.1 Deprecated features (100-199)</A></LI> +<LI><A HREF="#Warnings_nn11">14.9.2 Preprocessor (200-299)</A></LI> +<LI><A HREF="#Warnings_nn12">14.9.3 C/C++ Parser (300-399)</A></LI> +<LI><A HREF="#Warnings_nn13">14.9.4 Types and typemaps (400-499)</A></LI> +<LI><A HREF="#Warnings_nn14">14.9.5 Code generation (500-599)</A></LI> +<LI><A HREF="#Warnings_nn15">14.9.6 Language module specific (800-899)</A> +</LI> +<LI><A HREF="#Warnings_nn16">14.9.7 User defined (900-999)</A></LI> +</UL> +</LI> +<LI><A HREF="#Warnings_nn17">14.10 History</A></LI> +</UL> +<B><A HREF="#Modules">15 Working with Modules</A></B> +<UL> +<LI><A HREF="#Modules_introduction">15.1 Modules Introduction</A></LI> +<LI><A HREF="#Modules_nn1">15.2 Basics</A></LI> +<LI><A HREF="#Modules_nn2">15.3 The SWIG runtime code</A></LI> +<LI><A HREF="#external_run_time">15.4 External access to the runtime</A></LI> +<LI><A HREF="#Modules_nn4">15.5 A word of caution about static libraries</A> +</LI> +<LI><A HREF="#Modules_nn5">15.6 References</A></LI> +<LI><A HREF="#Modules_nn6">15.7 Reducing the wrapper file size</A></LI> +</UL> +<B><A HREF="#CCache">16 Using SWIG with ccache - ccache-swig(1) manpage</A> +</B> +<UL> +<LI><A HREF="#CCache_nn2">16.1 NAME</A></LI> +<LI><A HREF="#CCache_nn3">16.2 SYNOPSIS</A></LI> +<LI><A HREF="#CCache_nn4">16.3 DESCRIPTION</A></LI> +<LI><A HREF="#CCache_nn5">16.4 OPTIONS SUMMARY</A></LI> +<LI><A HREF="#CCache_nn6">16.5 OPTIONS</A></LI> +<LI><A HREF="#CCache_nn7">16.6 INSTALLATION</A></LI> +<LI><A HREF="#CCache_nn8">16.7 EXTRA OPTIONS</A></LI> +<LI><A HREF="#CCache_nn9">16.8 ENVIRONMENT VARIABLES</A></LI> +<LI><A HREF="#CCache_nn10">16.9 CACHE SIZE MANAGEMENT</A></LI> +<LI><A HREF="#CCache_nn11">16.10 CACHE COMPRESSION</A></LI> +<LI><A HREF="#CCache_nn12">16.11 HOW IT WORKS</A></LI> +<LI><A HREF="#CCache_nn13">16.12 USING CCACHE WITH DISTCC</A></LI> +<LI><A HREF="#CCache_nn14">16.13 SHARING A CACHE</A></LI> +<LI><A HREF="#CCache_nn15">16.14 HISTORY</A></LI> +<LI><A HREF="#CCache_nn16">16.15 DIFFERENCES FROM COMPILERCACHE</A></LI> +<LI><A HREF="#CCache_nn17">16.16 CREDITS</A></LI> +<LI><A HREF="#CCache_nn18">16.17 AUTHOR</A></LI> +</UL> +<B><A HREF="#Allegrocl_nn1">17 SWIG and Allegro Common Lisp</A></B> +<UL> +<LI><A HREF="#Allegrocl_nn2">17.1 Basics</A> +<UL> +<LI><A HREF="#Allegrocl_nn3">17.1.1 Running Swig</A></LI> +<LI><A HREF="#Allegrocl_nn4">17.1.2 Command Line Options</A></LI> +<LI><A HREF="#Allegrocl_nn5">17.1.3 Inserting user code into generated + files</A></LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn6">17.2 Wrapping Overview</A> +<UL> +<LI><A HREF="#Allegrocl_nn7">17.2.1 Function Wrapping</A></LI> +<LI><A HREF="#Allegrocl_nn8">17.2.2 Foreign Wrappers</A></LI> +<LI><A HREF="#Allegrocl_nn9">17.2.3 FFI Wrappers</A></LI> +<LI><A HREF="#Allegrocl_nn10">17.2.4 Non-overloaded Defuns</A></LI> +<LI><A HREF="#Allegrocl_nn11">17.2.5 Overloaded Defuns</A></LI> +<LI><A HREF="#Allegrocl_nn12">17.2.6 What about constant and variable + access?</A></LI> +<LI><A HREF="#Allegrocl_nn13">17.2.7 Object Wrapping</A></LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn14">17.3 Wrapping Details</A> +<UL> +<LI><A HREF="#Allegrocl_nn15">17.3.1 Namespaces</A></LI> +<LI><A HREF="#Allegrocl_nn16">17.3.2 Constants</A></LI> +<LI><A HREF="#Allegrocl_nn17">17.3.3 Variables</A></LI> +<LI><A HREF="#Allegrocl_nn18">17.3.4 Enumerations</A></LI> +<LI><A HREF="#Allegrocl_nn19">17.3.5 Arrays</A></LI> +<LI><A HREF="#Allegrocl_nn20">17.3.6 Classes and Structs and Unions (oh + my!)</A> +<UL> +<LI><A HREF="#Allegrocl_nn21">17.3.6.1 CLOS wrapping of</A></LI> +<LI><A HREF="#Allegrocl_nn22">17.3.6.2 CLOS Inheritance</A></LI> +<LI><A HREF="#Allegrocl_nn23">17.3.6.3 Member fields and functions</A></LI> +<LI><A HREF="#Allegrocl_nn24">17.3.6.4 Why not directly access C++ + classes using foreign types?</A></LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn25">17.3.7 Templates</A> +<UL> +<LI><A HREF="#Allegrocl_nn26">17.3.7.1 Generating wrapper code for + templates</A></LI> +<LI><A HREF="#Allegrocl_nn27">17.3.7.2 Implicit Template instantiation</A> +</LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn28">17.3.8 Typedef, Templates, and Synonym + Types</A> +<UL> +<LI><A HREF="#Allegrocl_nn29">17.3.8.1 Choosing a primary type</A></LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn30">17.3.9 Function overloading/Parameter + defaulting</A></LI> +<LI><A HREF="#Allegrocl_nn31">17.3.10 Operator wrapping and Operator + overloading</A></LI> +<LI><A HREF="#Allegrocl_nn32">17.3.11 Varargs</A></LI> +<LI><A HREF="#Allegrocl_nn33">17.3.12 C++ Exceptions</A></LI> +<LI><A HREF="#Allegrocl_nn34">17.3.13 Pass by value, pass by reference</A> +</LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn35">17.4 Typemaps</A> +<UL> +<LI><A HREF="#Allegrocl_nn36">17.4.1 Code Generation in the C++ Wrapper</A> +<UL> +<LI><A HREF="#Allegrocl_nn37">17.4.1.1 IN Typemap</A></LI> +<LI><A HREF="#Allegrocl_nn38">17.4.1.2 OUT Typemap</A></LI> +<LI><A HREF="#Allegrocl_nn39">17.4.1.3 CTYPE Typemap</A></LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn40">17.4.2 Code generation in Lisp wrappers</A> +<UL> +<LI><A HREF="#Allegrocl_nn41">17.4.2.1 LIN Typemap</A></LI> +<LI><A HREF="#Allegrocl_nn42">17.4.2.2 LOUT Typemap</A></LI> +<LI><A HREF="#Allegrocl_nn43">17.4.2.3 FFITYPE Typemap</A></LI> +<LI><A HREF="#Allegrocl_nn44">17.4.2.4 LISPTYPE Typemap</A></LI> +<LI><A HREF="#Allegrocl_nn45">17.4.2.5 LISPCLASS Typemap</A></LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn46">17.4.3 Modifying SWIG behavior using + typemaps</A></LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn47">17.5 Identifier Converter functions</A> +<UL> +<LI><A HREF="#Allegrocl_nn48">17.5.1 Creating symbols in the lisp + environment</A></LI> +<LI><A HREF="#Allegrocl_nn49">17.5.2 Existing identifier-converter + functions</A> +<UL> +<LI><A HREF="#Allegrocl_nn50">17.5.2.1 identifier-convert-null</A></LI> +<LI><A HREF="#Allegrocl_nn51">17.5.2.2 identifier-convert-lispify</A></LI> +<LI><A HREF="#Allegrocl_nn52">17.5.2.3 Default identifier to symbol + conversions</A></LI> +</UL> +</LI> +<LI><A HREF="#Allegrocl_nn53">17.5.3 Defining your own + identifier-converter</A></LI> +<LI><A HREF="#Allegrocl_nn54">17.5.4 Instructing SWIG to use a + particular identifier-converter</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#CSharp">18 SWIG and C#</A></B> +<UL> +<LI><A HREF="#csharp_introduction">18.1 Introduction</A></LI> +<LI><A HREF="#csharp_differences_java">18.2 Differences to the Java + module</A></LI> +<LI><A HREF="#CSharp_arrays">18.3 C# Arrays</A> +<UL> +<LI><A HREF="#CSharp_arrays_swig_library">18.3.1 The SWIG C arrays + library</A></LI> +<LI><A HREF="#CSharp_arrays_pinvoke_default_array_marshalling">18.3.2 + Managed arrays using P/Invoke default array marshalling</A></LI> +<LI><A HREF="#CSharp_arrays_pinning">18.3.3 Managed arrays using pinning</A> +</LI> +</UL> +</LI> +<LI><A HREF="#csharp_exceptions">18.4 C# Exceptions</A> +<UL> +<LI><A HREF="#csharp_exception_example_check_typemap">18.4.1 C# + exception example using "check" typemap</A></LI> +<LI><A HREF="#csharp_exception_example_percent_exception">18.4.2 C# + exception example using %exception</A></LI> +<LI><A HREF="#csharp_exception_example_exception_specifications">18.4.3 + C# exception example using exception specifications</A></LI> +<LI><A HREF="#csharp_custom_application_exception">18.4.4 Custom C# + ApplicationException example</A></LI> +</UL> +</LI> +<LI><A HREF="#csharp_directors">18.5 C# Directors</A> +<UL> +<LI><A HREF="#csharp_directors_example">18.5.1 Directors example</A></LI> +<LI><A HREF="#csharp_directors_implementation">18.5.2 Directors + implementation</A></LI> +<LI><A HREF="#csharp_director_caveats">18.5.3 Director caveats</A></LI> +</UL> +</LI> +<LI><A HREF="#csharp_typemap_examples">18.6 C# Typemap examples</A> +<UL> +<LI><A HREF="#csharp_memory_management_member_variables">18.6.1 Memory + management when returning references to member variables</A></LI> +<LI><A HREF="#csharp_memory_management_objects">18.6.2 Memory management + for objects passed to the C++ layer</A></LI> +<LI><A HREF="#csharp_date_marshalling">18.6.3 Date marshalling using the + csin typemap and associated attributes</A></LI> +<LI><A HREF="#csharp_date_properties">18.6.4 A date example + demonstrating marshalling of C# properties</A></LI> +<LI><A HREF="#csharp_partial_classes">18.6.5 Turning wrapped classes + into partial classes</A></LI> +<LI><A HREF="#csharp_extending_proxy_class">18.6.6 Extending proxy + classes with additional C# code</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Chicken">19 SWIG and Chicken</A></B> +<UL> +<LI><A HREF="#Chicken_nn2">19.1 Preliminaries</A> +<UL> +<LI><A HREF="#Chicken_nn3">19.1.1 Running SWIG in C mode</A></LI> +<LI><A HREF="#Chicken_nn4">19.1.2 Running SWIG in C++ mode</A></LI> +</UL> +</LI> +<LI><A HREF="#Chicken_nn5">19.2 Code Generation</A> +<UL> +<LI><A HREF="#Chicken_nn6">19.2.1 Naming Conventions</A></LI> +<LI><A HREF="#Chicken_nn7">19.2.2 Modules</A></LI> +<LI><A HREF="#Chicken_nn8">19.2.3 Constants and Variables</A></LI> +<LI><A HREF="#Chicken_nn9">19.2.4 Functions</A></LI> +<LI><A HREF="#Chicken_nn10">19.2.5 Exceptions</A></LI> +</UL> +</LI> +<LI><A HREF="#Chicken_nn11">19.3 TinyCLOS</A></LI> +<LI><A HREF="#Chicken_nn12">19.4 Linkage</A> +<UL> +<LI><A HREF="#Chicken_nn13">19.4.1 Static binary or shared library + linked at compile time</A></LI> +<LI><A HREF="#Chicken_nn14">19.4.2 Building chicken extension libraries</A> +</LI> +<LI><A HREF="#Chicken_nn15">19.4.3 Linking multiple SWIG modules with + TinyCLOS</A></LI> +</UL> +</LI> +<LI><A HREF="#Chicken_nn16">19.5 Typemaps</A></LI> +<LI><A HREF="#Chicken_nn17">19.6 Pointers</A> +<UL> +<LI><A HREF="#collection">19.6.1 Garbage collection</A></LI> +</UL> +</LI> +<LI><A HREF="#Chicken_nn18">19.7 Unsupported features and known problems</A> +<UL> +<LI><A HREF="#Chicken_nn19">19.7.1 TinyCLOS problems with Chicken + version <= 1.92</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Guile">20 SWIG and Guile</A></B> +<UL> +<LI><A HREF="#Guile_nn2">20.1 Meaning of "Module"</A></LI> +<LI><A HREF="#Guile_nn3">20.2 Using the SCM or GH Guile API</A></LI> +<LI><A HREF="#Guile_nn4">20.3 Linkage</A> +<UL> +<LI><A HREF="#Guile_nn5">20.3.1 Simple Linkage</A></LI> +<LI><A HREF="#Guile_nn6">20.3.2 Passive Linkage</A></LI> +<LI><A HREF="#Guile_nn7">20.3.3 Native Guile Module Linkage</A></LI> +<LI><A HREF="#Guile_nn8">20.3.4 Old Auto-Loading Guile Module Linkage</A> +</LI> +<LI><A HREF="#Guile_nn9">20.3.5 Hobbit4D Linkage</A></LI> +</UL> +</LI> +<LI><A HREF="#Guile_nn10">20.4 Underscore Folding</A></LI> +<LI><A HREF="#Guile_nn11">20.5 Typemaps</A></LI> +<LI><A HREF="#Guile_nn12">20.6 Representation of pointers as smobs</A> +<UL> +<LI><A HREF="#Guile_nn13">20.6.1 GH Smobs</A></LI> +<LI><A HREF="#Guile_nn14">20.6.2 SCM Smobs</A></LI> +<LI><A HREF="#Guile_nn15">20.6.3 Garbage Collection</A></LI> +</UL> +</LI> +<LI><A HREF="#Guile_nn16">20.7 Exception Handling</A></LI> +<LI><A HREF="#Guile_nn17">20.8 Procedure documentation</A></LI> +<LI><A HREF="#Guile_nn18">20.9 Procedures with setters</A></LI> +<LI><A HREF="#Guile_nn19">20.10 GOOPS Proxy Classes</A> +<UL> +<LI><A HREF="#Guile_nn20">20.10.1 Naming Issues</A></LI> +<LI><A HREF="#Guile_nn21">20.10.2 Linking</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Java">21 SWIG and Java</A></B> +<UL> +<LI><A HREF="#java_overview">21.1 Overview</A></LI> +<LI><A HREF="#java_preliminaries">21.2 Preliminaries</A> +<UL> +<LI><A HREF="#running_swig">21.2.1 Running SWIG</A></LI> +<LI><A HREF="#java_commandline">21.2.2 Additional Commandline Options</A> +</LI> +<LI><A HREF="#getting_right_headers">21.2.3 Getting the right header + files</A></LI> +<LI><A HREF="#compiling_dynamic">21.2.4 Compiling a dynamic module</A></LI> +<LI><A HREF="#using_module">21.2.5 Using your module</A></LI> +<LI><A HREF="#dynamic_linking_problems">21.2.6 Dynamic linking problems</A> +</LI> +<LI><A HREF="#compilation_problems_cpp">21.2.7 Compilation problems and + compiling with C++</A></LI> +<LI><A HREF="#building_windows">21.2.8 Building on Windows</A> +<UL> +<LI><A HREF="#visual_studio">21.2.8.1 Running SWIG from Visual Studio</A> +</LI> +<LI><A HREF="#nmake">21.2.8.2 Using NMAKE</A></LI> +</UL> +</LI> +</UL> +</LI> +<LI><A HREF="#java_basic_tour">21.3 A tour of basic C/C++ wrapping</A> +<UL> +<LI><A HREF="#module_packages_classes">21.3.1 Modules, packages and + generated Java classes</A></LI> +<LI><A HREF="#functions">21.3.2 Functions</A></LI> +<LI><A HREF="#global_variables">21.3.3 Global variables</A></LI> +<LI><A HREF="#constants">21.3.4 Constants</A></LI> +<LI><A HREF="#enumerations">21.3.5 Enumerations</A> +<UL> +<LI><A HREF="#anonymous_enums">21.3.5.1 Anonymous enums</A></LI> +<LI><A HREF="#typesafe_enums">21.3.5.2 Typesafe enums</A></LI> +<LI><A HREF="#proper_enums">21.3.5.3 Proper Java enums</A></LI> +<LI><A HREF="#typeunsafe_enums">21.3.5.4 Type unsafe enums</A></LI> +<LI><A HREF="#simple_enums">21.3.5.5 Simple enums</A></LI> +</UL> +</LI> +<LI><A HREF="#pointers">21.3.6 Pointers</A></LI> +<LI><A HREF="#structures">21.3.7 Structures</A></LI> +<LI><A HREF="#classes">21.3.8 C++ classes</A></LI> +<LI><A HREF="#inheritance">21.3.9 C++ inheritance</A></LI> +<LI><A HREF="#pointers_refs_arrays">21.3.10 Pointers, references, arrays + and pass by value</A> +<UL> +<LI><A HREF="#null_pointers">21.3.10.1 Null pointers</A></LI> +</UL> +</LI> +<LI><A HREF="#overloaded_functions">21.3.11 C++ overloaded functions</A></LI> +<LI><A HREF="#java_default_arguments">21.3.12 C++ default arguments</A></LI> +<LI><A HREF="#namespaces">21.3.13 C++ namespaces</A></LI> +<LI><A HREF="#templates">21.3.14 C++ templates</A></LI> +<LI><A HREF="#smart_pointers">21.3.15 C++ Smart Pointers</A></LI> +</UL> +</LI> +<LI><A HREF="#further_details">21.4 Further details on the generated + Java classes</A> +<UL> +<LI><A HREF="#imclass">21.4.1 The intermediary JNI class</A> +<UL> +<LI><A HREF="#imclass_pragmas">21.4.1.1 The intermediary JNI class + pragmas</A></LI> +</UL> +</LI> +<LI><A HREF="#java_module_class">21.4.2 The Java module class</A> +<UL> +<LI><A HREF="#module_class_pragmas">21.4.2.1 The Java module class + pragmas</A></LI> +</UL> +</LI> +<LI><A HREF="#java_proxy_classes">21.4.3 Java proxy classes</A> +<UL> +<LI><A HREF="#memory_management">21.4.3.1 Memory management</A></LI> +<LI><A HREF="#inheritance_mirroring">21.4.3.2 Inheritance</A></LI> +<LI><A HREF="#proxy_classes_gc">21.4.3.3 Proxy classes and garbage + collection</A></LI> +<LI><A HREF="#java_pgcpp">21.4.3.4 The premature garbage collection + prevention parameter for proxy class marshalling</A></LI> +<LI><A HREF="#java_multithread_libraries">21.4.3.5 Single threaded + applications and thread safety</A></LI> +</UL> +</LI> +<LI><A HREF="#type_wrapper_classes">21.4.4 Type wrapper classes</A></LI> +<LI><A HREF="#enum_classes">21.4.5 Enum classes</A> +<UL> +<LI><A HREF="#typesafe_enums_classes">21.4.5.1 Typesafe enum classes</A></LI> +<LI><A HREF="#proper_enums_classes">21.4.5.2 Proper Java enum classes</A> +</LI> +<LI><A HREF="#typeunsafe_enums_classes">21.4.5.3 Type unsafe enum + classes</A></LI> +</UL> +</LI> +</UL> +</LI> +<LI><A HREF="#java_directors">21.5 Cross language polymorphism using + directors</A> +<UL> +<LI><A HREF="#java_enabling_directors">21.5.1 Enabling directors</A></LI> +<LI><A HREF="#java_directors_classes">21.5.2 Director classes</A></LI> +<LI><A HREF="#java_directors_overhead">21.5.3 Overhead and code bloat</A> +</LI> +<LI><A HREF="#java_directors_example">21.5.4 Simple directors example</A> +</LI> +<LI><A HREF="#java_directors_threading">21.5.5 Director threading issues</A> +</LI> +</UL> +</LI> +<LI><A HREF="#java_allprotected">21.6 Accessing protected members</A></LI> +<LI><A HREF="#common_customization">21.7 Common customization features</A> +<UL> +<LI><A HREF="#helper_functions">21.7.1 C/C++ helper functions</A></LI> +<LI><A HREF="#class_extension">21.7.2 Class extension with %extend</A></LI> +<LI><A HREF="#exception_handling">21.7.3 Exception handling with + %exception and %javaexception</A></LI> +<LI><A HREF="#method_access">21.7.4 Method access with + %javamethodmodifiers</A></LI> +</UL> +</LI> +<LI><A HREF="#tips_techniques">21.8 Tips and techniques</A> +<UL> +<LI><A HREF="#input_output_parameters">21.8.1 Input and output + parameters using primitive pointers and references</A></LI> +<LI><A HREF="#simple_pointers">21.8.2 Simple pointers</A></LI> +<LI><A HREF="#c_arrays">21.8.3 Wrapping C arrays with Java arrays</A></LI> +<LI><A HREF="#unbounded_c_arrays">21.8.4 Unbounded C Arrays</A></LI> +<LI><A HREF="#java_heap_allocations">21.8.5 Overriding new and delete to + allocate from Java heap</A></LI> +</UL> +</LI> +<LI><A HREF="#java_typemaps">21.9 Java typemaps</A> +<UL> +<LI><A HREF="#default_primitive_type_mappings">21.9.1 Default primitive + type mappings</A></LI> +<LI><A HREF="#Java_default_non_primitive_typemaps">21.9.2 Default + typemaps for non-primitive types</A></LI> +<LI><A HREF="#jvm64">21.9.3 Sixty four bit JVMs</A></LI> +<LI><A HREF="#what_is_typemap">21.9.4 What is a typemap?</A></LI> +<LI><A HREF="#typemaps_c_to_java_types">21.9.5 Typemaps for mapping + C/C++ types to Java types</A></LI> +<LI><A HREF="#typemap_attributes">21.9.6 Java typemap attributes</A></LI> +<LI><A HREF="#special_variables">21.9.7 Java special variables</A></LI> +<LI><A HREF="#typemaps_for_c_and_cpp">21.9.8 Typemaps for both C and C++ + compilation</A></LI> +<LI><A HREF="#java_code_typemaps">21.9.9 Java code typemaps</A></LI> +<LI><A HREF="#java_directors_typemaps">21.9.10 Director specific + typemaps</A></LI> +</UL> +</LI> +<LI><A HREF="#typemap_examples">21.10 Typemap Examples</A> +<UL> +<LI><A HREF="#simpler_enum_classes">21.10.1 Simpler Java enums for enums + without initializers</A></LI> +<LI><A HREF="#exception_typemap">21.10.2 Handling C++ exception + specifications as Java exceptions</A></LI> +<LI><A HREF="#nan_exception_typemap">21.10.3 NaN Exception - exception + handling for a particular type</A></LI> +<LI><A HREF="#converting_java_string_arrays">21.10.4 Converting Java + String arrays to char **</A></LI> +<LI><A HREF="#expanding_java_object">21.10.5 Expanding a Java object to + multiple arguments</A></LI> +<LI><A HREF="#using_typemaps_return_arguments">21.10.6 Using typemaps to + return arguments</A></LI> +<LI><A HREF="#adding_downcasts">21.10.7 Adding Java downcasts to + polymorphic return types</A></LI> +<LI><A HREF="#adding_equals_method">21.10.8 Adding an equals method to + the Java classes</A></LI> +<LI><A HREF="#void_pointers">21.10.9 Void pointers and a common Java + base class</A></LI> +<LI><A HREF="#struct_pointer_pointer">21.10.10 Struct pointer to pointer</A> +</LI> +<LI><A HREF="#java_memory_management_member_variables">21.10.11 Memory + management when returning references to member variables</A></LI> +<LI><A HREF="#java_memory_management_objects">21.10.12 Memory management + for objects passed to the C++ layer</A></LI> +<LI><A HREF="#java_date_marshalling">21.10.13 Date marshalling using the + javain typemap and associated attributes</A></LI> +</UL> +</LI> +<LI><A HREF="#java_directors_faq">21.11 Living with Java Directors</A></LI> +<LI><A HREF="#odds_ends">21.12 Odds and ends</A> +<UL> +<LI><A HREF="#javadoc_comments">21.12.1 JavaDoc comments</A></LI> +<LI><A HREF="#functional_interface">21.12.2 Functional interface without + proxy classes</A></LI> +<LI><A HREF="#using_own_jni_functions">21.12.3 Using your own JNI + functions</A></LI> +<LI><A HREF="#performance">21.12.4 Performance concerns and hints</A></LI> +<LI><A HREF="#java_debugging">21.12.5 Debugging</A></LI> +</UL> +</LI> +<LI><A HREF="#java_examples">21.13 Examples</A></LI> +</UL> +<B><A HREF="#Lisp_nn1">22 SWIG and Common Lisp</A></B> +<UL> +<LI><A HREF="#Lisp_nn2">22.1 Allegro Common Lisp</A></LI> +<LI><A HREF="#Lisp_nn3">22.2 Common Foreign Function Interface(CFFI)</A> +<UL> +<LI><A HREF="#Lisp_nn4">22.2.1 Additional Commandline Options</A></LI> +<LI><A HREF="#Lisp_nn5">22.2.2 Generating CFFI bindings</A></LI> +<LI><A HREF="#Lisp_nn6">22.2.3 Generating CFFI bindings for C++ code</A></LI> +<LI><A HREF="#Lisp_nn7">22.2.4 Inserting user code into generated files</A> +</LI> +</UL> +</LI> +<LI><A HREF="#Lisp_nn8">22.3 CLISP</A> +<UL> +<LI><A HREF="#Lisp_nn9">22.3.1 Additional Commandline Options</A></LI> +<LI><A HREF="#Lisp_nn10">22.3.2 Details on CLISP bindings</A></LI> +</UL> +</LI> +<LI><A HREF="#Lisp_nn11">22.4 UFFI</A></LI> +</UL> +<B><A HREF="#Lua_nn1">23 SWIG and Lua</A></B> +<UL> +<LI><A HREF="#Lua_nn2">23.1 Preliminaries</A></LI> +<LI><A HREF="#Lua_nn3">23.2 Running SWIG</A> +<UL> +<LI><A HREF="#Lua_nn4">23.2.1 Compiling and Linking and Interpreter</A></LI> +<LI><A HREF="#Lua_nn5">23.2.2 Compiling a dynamic module</A></LI> +<LI><A HREF="#Lua_nn6">23.2.3 Using your module</A></LI> +</UL> +</LI> +<LI><A HREF="#Lua_nn7">23.3 A tour of basic C/C++ wrapping</A> +<UL> +<LI><A HREF="#Lua_nn8">23.3.1 Modules</A></LI> +<LI><A HREF="#Lua_nn9">23.3.2 Functions</A></LI> +<LI><A HREF="#Lua_nn10">23.3.3 Global variables</A></LI> +<LI><A HREF="#Lua_nn11">23.3.4 Constants and enums</A></LI> +<LI><A HREF="#Lua_nn12">23.3.5 Pointers</A></LI> +<LI><A HREF="#Lua_nn13">23.3.6 Structures</A></LI> +<LI><A HREF="#Lua_nn14">23.3.7 C++ classes</A></LI> +<LI><A HREF="#Lua_nn15">23.3.8 C++ inheritance</A></LI> +<LI><A HREF="#Lua_nn16">23.3.9 Pointers, references, values, and arrays</A> +</LI> +<LI><A HREF="#Lua_nn17">23.3.10 C++ overloaded functions</A></LI> +<LI><A HREF="#Lua_nn18">23.3.11 C++ operators</A></LI> +<LI><A HREF="#Lua_nn19">23.3.12 Class extension with %extend</A></LI> +<LI><A HREF="#Lua_nn20">23.3.13 C++ templates</A></LI> +<LI><A HREF="#Lua_nn21">23.3.14 C++ Smart Pointers</A></LI> +<LI><A HREF="#Lua_nn22">23.3.15 C++ Exceptions</A></LI> +</UL> +</LI> +<LI><A HREF="#Lua_nn23">23.4 Typemaps</A> +<UL> +<LI><A HREF="#Lua_nn24">23.4.1 What is a typemap?</A></LI> +<LI><A HREF="#Lua_nn25">23.4.2 Using typemaps</A></LI> +<LI><A HREF="#Lua_nn26">23.4.3 Typemaps and arrays</A></LI> +<LI><A HREF="#Lua_nn27">23.4.4 Typemaps and pointer-pointer functions</A> +</LI> +</UL> +</LI> +<LI><A HREF="#Lua_nn28">23.5 Writing typemaps</A> +<UL> +<LI><A HREF="#Lua_nn29">23.5.1 Typemaps you can write</A></LI> +<LI><A HREF="#Lua_nn30">23.5.2 SWIG's Lua-C API</A></LI> +</UL> +</LI> +<LI><A HREF="#Lua_nn31">23.6 Customization of your Bindings</A> +<UL> +<LI><A HREF="#Lua_nn32">23.6.1 Writing your own custom wrappers</A></LI> +<LI><A HREF="#Lua_nn33">23.6.2 Adding additional Lua code</A></LI> +</UL> +</LI> +<LI><A HREF="#Lua_nn34">23.7 Details on the Lua binding</A> +<UL> +<LI><A HREF="#Lua_nn35">23.7.1 Binding global data into the module.</A></LI> +<LI><A HREF="#Lua_nn36">23.7.2 Userdata and Metatables</A></LI> +<LI><A HREF="#Lua_nn37">23.7.3 Memory management</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Modula3">24 SWIG and Modula-3</A></B> +<UL> +<LI><A HREF="#modula3_overview">24.1 Overview</A> +<UL> +<LI><A HREF="#whyscripting">24.1.1 Why not scripting ?</A></LI> +<LI><A HREF="#whymodula3">24.1.2 Why Modula-3 ?</A></LI> +<LI><A HREF="#whycpp">24.1.3 Why C / C++ ?</A></LI> +<LI><A HREF="#whyswig">24.1.4 Why SWIG ?</A></LI> +</UL> +</LI> +<LI><A HREF="#conception">24.2 Conception</A> +<UL> +<LI><A HREF="#cinterface">24.2.1 Interfaces to C libraries</A></LI> +<LI><A HREF="#cppinterface">24.2.2 Interfaces to C++ libraries</A></LI> +</UL> +</LI> +<LI><A HREF="#preliminaries">24.3 Preliminaries</A> +<UL> +<LI><A HREF="#compilers">24.3.1 Compilers</A></LI> +<LI><A HREF="#commandline">24.3.2 Additional Commandline Options</A></LI> +</UL> +</LI> +<LI><A HREF="#modula3_typemaps">24.4 Modula-3 typemaps</A> +<UL> +<LI><A HREF="#inoutparam">24.4.1 Inputs and outputs</A></LI> +<LI><A HREF="#ordinals">24.4.2 Subranges, Enumerations, Sets</A></LI> +<LI><A HREF="#class">24.4.3 Objects</A></LI> +<LI><A HREF="#imports">24.4.4 Imports</A></LI> +<LI><A HREF="#exceptions">24.4.5 Exceptions</A></LI> +<LI><A HREF="#typemap_example">24.4.6 Example</A></LI> +</UL> +</LI> +<LI><A HREF="#hints">24.5 More hints to the generator</A> +<UL> +<LI><A HREF="#features">24.5.1 Features</A></LI> +<LI><A HREF="#pragmas">24.5.2 Pragmas</A></LI> +</UL> +</LI> +<LI><A HREF="#remarks">24.6 Remarks</A></LI> +</UL> +<B><A HREF="#MzScheme">25 SWIG and MzScheme</A></B> +<UL> +<LI><A HREF="#MzScheme_nn2">25.1 Creating native MzScheme structures</A></LI> +</UL> +<B><A HREF="#Ocaml">26 SWIG and Ocaml</A></B> +<UL> +<LI><A HREF="#Ocaml_nn2">26.1 Preliminaries</A> +<UL> +<LI><A HREF="#Ocaml_nn3">26.1.1 Running SWIG</A></LI> +<LI><A HREF="#Ocaml_nn4">26.1.2 Compiling the code</A></LI> +<LI><A HREF="#Ocaml_nn5">26.1.3 The camlp4 module</A></LI> +<LI><A HREF="#Ocaml_nn6">26.1.4 Using your module</A></LI> +<LI><A HREF="#Ocaml_nn7">26.1.5 Compilation problems and compiling with + C++</A></LI> +</UL> +</LI> +<LI><A HREF="#Ocaml_nn8">26.2 The low-level Ocaml/C interface</A> +<UL> +<LI><A HREF="#Ocaml_nn9">26.2.1 The generated module</A></LI> +<LI><A HREF="#Ocaml_nn10">26.2.2 Enums</A> +<UL> +<LI><A HREF="#Ocaml_nn11">26.2.2.1 Enum typing in Ocaml</A></LI> +</UL> +</LI> +<LI><A HREF="#Ocaml_nn12">26.2.3 Arrays</A> +<UL> +<LI><A HREF="#Ocaml_nn13">26.2.3.1 Simple types of bounded arrays</A></LI> +<LI><A HREF="#Ocaml_nn14">26.2.3.2 Complex and unbounded arrays</A></LI> +<LI><A HREF="#Ocaml_nn15">26.2.3.3 Using an object</A></LI> +<LI><A HREF="#Ocaml_nn16">26.2.3.4 Example typemap for a function taking + float * and int</A></LI> +</UL> +</LI> +<LI><A HREF="#Ocaml_nn17">26.2.4 C++ Classes</A> +<UL> +<LI><A HREF="#Ocaml_nn18">26.2.4.1 STL vector and string Example</A></LI> +<LI><A HREF="#Ocaml_nn19">26.2.4.2 C++ Class Example</A></LI> +<LI><A HREF="#Ocaml_nn20">26.2.4.3 Compiling the example</A></LI> +<LI><A HREF="#Ocaml_nn21">26.2.4.4 Sample Session</A></LI> +</UL> +</LI> +<LI><A HREF="#Ocaml_nn22">26.2.5 Director Classes</A> +<UL> +<LI><A HREF="#Ocaml_nn23">26.2.5.1 Director Introduction</A></LI> +<LI><A HREF="#Ocaml_nn24">26.2.5.2 Overriding Methods in Ocaml</A></LI> +<LI><A HREF="#Ocaml_nn25">26.2.5.3 Director Usage Example</A></LI> +<LI><A HREF="#Ocaml_nn26">26.2.5.4 Creating director objects</A></LI> +<LI><A HREF="#Ocaml_nn27">26.2.5.5 Typemaps for directors, directorin, + directorout, directorargout</A></LI> +<LI><A HREF="#Ocaml_nn28">26.2.5.6 directorin typemap</A></LI> +<LI><A HREF="#Ocaml_nn29">26.2.5.7 directorout typemap</A></LI> +<LI><A HREF="#Ocaml_nn30">26.2.5.8 directorargout typemap</A></LI> +</UL> +</LI> +<LI><A HREF="#Ocaml_nn31">26.2.6 Exceptions</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Octave">27 SWIG and Octave</A></B> +<UL> +<LI><A HREF="#Octave_nn2">27.1 Preliminaries</A></LI> +<LI><A HREF="#Octave_nn3">27.2 Running SWIG</A> +<UL> +<LI><A HREF="#Octave_nn5">27.2.1 Compiling a dynamic module</A></LI> +<LI><A HREF="#Octave_nn6">27.2.2 Using your module</A></LI> +</UL> +</LI> +<LI><A HREF="#Octave_nn7">27.3 A tour of basic C/C++ wrapping</A> +<UL> +<LI><A HREF="#Octave_nn8">27.3.1 Modules</A></LI> +<LI><A HREF="#Octave_nn9">27.3.2 Functions</A></LI> +<LI><A HREF="#Octave_nn10">27.3.3 Global variables</A></LI> +<LI><A HREF="#Octave_nn11">27.3.4 Constants and enums</A></LI> +<LI><A HREF="#Octave_nn12">27.3.5 Pointers</A></LI> +<LI><A HREF="#Octave_nn13">27.3.6 Structures and C++ classes</A></LI> +<LI><A HREF="#Octave_nn15">27.3.7 C++ inheritance</A></LI> +<LI><A HREF="#Octave_nn17">27.3.8 C++ overloaded functions</A></LI> +<LI><A HREF="#Octave_nn18">27.3.9 C++ operators</A></LI> +<LI><A HREF="#Octave_nn19">27.3.10 Class extension with %extend</A></LI> +<LI><A HREF="#Octave_nn20">27.3.11 C++ templates</A></LI> +<LI><A HREF="#Octave_nn21">27.3.12 C++ Smart Pointers</A></LI> +<LI><A HREF="#Octave_nn22">27.3.13 Directors (calling Octave from C++ + code)</A></LI> +<LI><A HREF="#Octave_nn23">27.3.14 Threads</A></LI> +<LI><A HREF="#Octave_nn24">27.3.15 Memory management</A></LI> +<LI><A HREF="#Octave_nn25">27.3.16 STL support</A></LI> +<LI><A HREF="#Octave_nn26">27.3.17 Matrix typemaps</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Perl5">28 SWIG and Perl5</A></B> +<UL> +<LI><A HREF="#Perl5_nn2">28.1 Overview</A></LI> +<LI><A HREF="#Perl5_nn3">28.2 Preliminaries</A> +<UL> +<LI><A HREF="#Perl5_nn4">28.2.1 Getting the right header files</A></LI> +<LI><A HREF="#Perl5_nn5">28.2.2 Compiling a dynamic module</A></LI> +<LI><A HREF="#Perl5_nn6">28.2.3 Building a dynamic module with MakeMaker</A> +</LI> +<LI><A HREF="#Perl5_nn7">28.2.4 Building a static version of Perl</A></LI> +<LI><A HREF="#Perl5_nn8">28.2.5 Using the module</A></LI> +<LI><A HREF="#Perl5_nn9">28.2.6 Compilation problems and compiling with + C++</A></LI> +<LI><A HREF="#Perl5_nn10">28.2.7 Compiling for 64-bit platforms</A></LI> +</UL> +</LI> +<LI><A HREF="#Perl5_nn11">28.3 Building Perl Extensions under Windows</A> +<UL> +<LI><A HREF="#Perl5_nn12">28.3.1 Running SWIG from Developer Studio</A></LI> +<LI><A HREF="#Perl5_nn13">28.3.2 Using other compilers</A></LI> +</UL> +</LI> +<LI><A HREF="#Perl5_nn14">28.4 The low-level interface</A> +<UL> +<LI><A HREF="#Perl5_nn15">28.4.1 Functions</A></LI> +<LI><A HREF="#Perl5_nn16">28.4.2 Global variables</A></LI> +<LI><A HREF="#Perl5_nn17">28.4.3 Constants</A></LI> +<LI><A HREF="#Perl5_nn18">28.4.4 Pointers</A></LI> +<LI><A HREF="#Perl5_nn19">28.4.5 Structures</A></LI> +<LI><A HREF="#Perl5_nn20">28.4.6 C++ classes</A></LI> +<LI><A HREF="#Perl5_nn21">28.4.7 C++ classes and type-checking</A></LI> +<LI><A HREF="#Perl5_nn22">28.4.8 C++ overloaded functions</A></LI> +<LI><A HREF="#Perl5_nn23">28.4.9 Operators</A></LI> +<LI><A HREF="#Perl5_nn24">28.4.10 Modules and packages</A></LI> +</UL> +</LI> +<LI><A HREF="#Perl5_nn25">28.5 Input and output parameters</A></LI> +<LI><A HREF="#Perl5_nn26">28.6 Exception handling</A></LI> +<LI><A HREF="#Perl5_nn27">28.7 Remapping datatypes with typemaps</A> +<UL> +<LI><A HREF="#Perl5_nn28">28.7.1 A simple typemap example</A></LI> +<LI><A HREF="#Perl5_nn29">28.7.2 Perl5 typemaps</A></LI> +<LI><A HREF="#Perl5_nn30">28.7.3 Typemap variables</A></LI> +<LI><A HREF="#Perl5_nn31">28.7.4 Useful functions</A></LI> +</UL> +</LI> +<LI><A HREF="#Perl5_nn32">28.8 Typemap Examples</A> +<UL> +<LI><A HREF="#Perl5_nn33">28.8.1 Converting a Perl5 array to a char **</A> +</LI> +<LI><A HREF="#Perl5_nn34">28.8.2 Return values</A></LI> +<LI><A HREF="#Perl5_nn35">28.8.3 Returning values from arguments</A></LI> +<LI><A HREF="#Perl5_nn36">28.8.4 Accessing array structure members</A></LI> +<LI><A HREF="#Perl5_nn37">28.8.5 Turning Perl references into C pointers</A> +</LI> +<LI><A HREF="#Perl5_nn38">28.8.6 Pointer handling</A></LI> +</UL> +</LI> +<LI><A HREF="#Perl5_nn39">28.9 Proxy classes</A> +<UL> +<LI><A HREF="#Perl5_nn40">28.9.1 Preliminaries</A></LI> +<LI><A HREF="#Perl5_nn41">28.9.2 Structure and class wrappers</A></LI> +<LI><A HREF="#Perl5_nn42">28.9.3 Object Ownership</A></LI> +<LI><A HREF="#Perl5_nn43">28.9.4 Nested Objects</A></LI> +<LI><A HREF="#Perl5_nn44">28.9.5 Proxy Functions</A></LI> +<LI><A HREF="#Perl5_nn45">28.9.6 Inheritance</A></LI> +<LI><A HREF="#Perl5_nn46">28.9.7 Modifying the proxy methods</A></LI> +</UL> +</LI> +<LI><A HREF="#Perl5_nn47">28.10 Adding additional Perl code</A></LI> +</UL> +<B><A HREF="#Php">29 SWIG and PHP</A></B> +<UL> +<LI><A HREF="#Php_nn1">29.1 Generating PHP Extensions</A> +<UL> +<LI><A HREF="#Php_nn1_1">29.1.1 Building a loadable extension</A></LI> +<LI><A HREF="#Php_nn1_3">29.1.2 Using PHP Extensions</A></LI> +</UL> +</LI> +<LI><A HREF="#Php_nn2">29.2 Basic PHP interface</A> +<UL> +<LI><A HREF="#Php_nn2_1">29.2.1 Constants</A></LI> +<LI><A HREF="#Php_nn2_2">29.2.2 Global Variables</A></LI> +<LI><A HREF="#Php_nn2_3">29.2.3 Functions</A></LI> +<LI><A HREF="#Php_nn2_4">29.2.4 Overloading</A></LI> +<LI><A HREF="#Php_nn2_5">29.2.5 Pointers and References</A></LI> +<LI><A HREF="#Php_nn2_6">29.2.6 Structures and C++ classes</A> +<UL> +<LI><A HREF="#Php_nn2_6_1">29.2.6.1 Using -noproxy</A></LI> +<LI><A HREF="#Php_nn2_6_2">29.2.6.2 Constructors and Destructors</A></LI> +<LI><A HREF="#Php_nn2_6_3">29.2.6.3 Static Member Variables</A></LI> +<LI><A HREF="#Php_nn2_6_4">29.2.6.4 Static Member Functions</A></LI> +</UL> +</LI> +<LI><A HREF="#Php_nn2_7">29.2.7 PHP Pragmas, Startup and Shutdown code</A> +</LI> +</UL> +</LI> +<LI><A HREF="#Php_nn3">29.3 Cross language polymorphism</A> +<UL> +<LI><A HREF="#Php_nn3_1">29.3.1 Enabling directors</A></LI> +<LI><A HREF="#Php_nn3_2">29.3.2 Director classes</A></LI> +<LI><A HREF="#Php_nn3_3">29.3.3 Ownership and object destruction</A></LI> +<LI><A HREF="#Php_nn3_4">29.3.4 Exception unrolling</A></LI> +<LI><A HREF="#Php_nn3_5">29.3.5 Overhead and code bloat</A></LI> +<LI><A HREF="#Php_nn3_6">29.3.6 Typemaps</A></LI> +<LI><A HREF="#Php_nn3_7">29.3.7 Miscellaneous</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Pike">30 SWIG and Pike</A></B> +<UL> +<LI><A HREF="#Pike_nn2">30.1 Preliminaries</A> +<UL> +<LI><A HREF="#Pike_nn3">30.1.1 Running SWIG</A></LI> +<LI><A HREF="#Pike_nn4">30.1.2 Getting the right header files</A></LI> +<LI><A HREF="#Pike_nn5">30.1.3 Using your module</A></LI> +</UL> +</LI> +<LI><A HREF="#Pike_nn6">30.2 Basic C/C++ Mapping</A> +<UL> +<LI><A HREF="#Pike_nn7">30.2.1 Modules</A></LI> +<LI><A HREF="#Pike_nn8">30.2.2 Functions</A></LI> +<LI><A HREF="#Pike_nn9">30.2.3 Global variables</A></LI> +<LI><A HREF="#Pike_nn10">30.2.4 Constants and enumerated types</A></LI> +<LI><A HREF="#Pike_nn11">30.2.5 Constructors and Destructors</A></LI> +<LI><A HREF="#Pike_nn12">30.2.6 Static Members</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Python">31 SWIG and Python</A></B> +<UL> +<LI><A HREF="#Python_nn2">31.1 Overview</A></LI> +<LI><A HREF="#Python_nn3">31.2 Preliminaries</A> +<UL> +<LI><A HREF="#Python_nn4">31.2.1 Running SWIG</A></LI> +<LI><A HREF="#Python_nn6">31.2.2 Using distutils</A></LI> +<LI><A HREF="#Python_nn7">31.2.3 Hand compiling a dynamic module</A></LI> +<LI><A HREF="#Python_nn8">31.2.4 Static linking</A></LI> +<LI><A HREF="#Python_nn9">31.2.5 Using your module</A></LI> +<LI><A HREF="#Python_nn10">31.2.6 Compilation of C++ extensions</A></LI> +<LI><A HREF="#Python_nn11">31.2.7 Compiling for 64-bit platforms</A></LI> +<LI><A HREF="#Python_nn12">31.2.8 Building Python Extensions under + Windows</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_nn13">31.3 A tour of basic C/C++ wrapping</A> +<UL> +<LI><A HREF="#Python_nn14">31.3.1 Modules</A></LI> +<LI><A HREF="#Python_nn15">31.3.2 Functions</A></LI> +<LI><A HREF="#Python_nn16">31.3.3 Global variables</A></LI> +<LI><A HREF="#Python_nn17">31.3.4 Constants and enums</A></LI> +<LI><A HREF="#Python_nn18">31.3.5 Pointers</A></LI> +<LI><A HREF="#Python_nn19">31.3.6 Structures</A></LI> +<LI><A HREF="#Python_nn20">31.3.7 C++ classes</A></LI> +<LI><A HREF="#Python_nn21">31.3.8 C++ inheritance</A></LI> +<LI><A HREF="#Python_nn22">31.3.9 Pointers, references, values, and + arrays</A></LI> +<LI><A HREF="#Python_nn23">31.3.10 C++ overloaded functions</A></LI> +<LI><A HREF="#Python_nn24">31.3.11 C++ operators</A></LI> +<LI><A HREF="#Python_nn25">31.3.12 C++ namespaces</A></LI> +<LI><A HREF="#Python_nn26">31.3.13 C++ templates</A></LI> +<LI><A HREF="#Python_nn27">31.3.14 C++ Smart Pointers</A></LI> +<LI><A HREF="#Python_nn27a">31.3.15 C++ Reference Counted Objects + (ref/unref)</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_nn28">31.4 Further details on the Python class + interface</A> +<UL> +<LI><A HREF="#Python_nn29">31.4.1 Proxy classes</A></LI> +<LI><A HREF="#Python_nn30">31.4.2 Memory management</A></LI> +<LI><A HREF="#Python_nn31">31.4.3 Python 2.2 and classic classes</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_directors">31.5 Cross language polymorphism</A> +<UL> +<LI><A HREF="#Python_nn33">31.5.1 Enabling directors</A></LI> +<LI><A HREF="#Python_nn34">31.5.2 Director classes</A></LI> +<LI><A HREF="#Python_nn35">31.5.3 Ownership and object destruction</A></LI> +<LI><A HREF="#Python_nn36">31.5.4 Exception unrolling</A></LI> +<LI><A HREF="#Python_nn37">31.5.5 Overhead and code bloat</A></LI> +<LI><A HREF="#Python_nn38">31.5.6 Typemaps</A></LI> +<LI><A HREF="#Python_nn39">31.5.7 Miscellaneous</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_nn40">31.6 Common customization features</A> +<UL> +<LI><A HREF="#Python_nn41">31.6.1 C/C++ helper functions</A></LI> +<LI><A HREF="#Python_nn42">31.6.2 Adding additional Python code</A></LI> +<LI><A HREF="#Python_nn43">31.6.3 Class extension with %extend</A></LI> +<LI><A HREF="#Python_nn44">31.6.4 Exception handling with %exception</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_nn45">31.7 Tips and techniques</A> +<UL> +<LI><A HREF="#Python_nn46">31.7.1 Input and output parameters</A></LI> +<LI><A HREF="#Python_nn47">31.7.2 Simple pointers</A></LI> +<LI><A HREF="#Python_nn48">31.7.3 Unbounded C Arrays</A></LI> +<LI><A HREF="#Python_nn49">31.7.4 String handling</A></LI> +<LI><A HREF="#Python_nn50">31.7.5 Arrays</A></LI> +<LI><A HREF="#Python_nn51">31.7.6 String arrays</A></LI> +<LI><A HREF="#Python_nn52">31.7.7 STL wrappers</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_nn53">31.8 Typemaps</A> +<UL> +<LI><A HREF="#Python_nn54">31.8.1 What is a typemap?</A></LI> +<LI><A HREF="#Python_nn55">31.8.2 Python typemaps</A></LI> +<LI><A HREF="#Python_nn56">31.8.3 Typemap variables</A></LI> +<LI><A HREF="#Python_nn57">31.8.4 Useful Python Functions</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_nn58">31.9 Typemap Examples</A> +<UL> +<LI><A HREF="#Python_nn59">31.9.1 Converting Python list to a char **</A> +</LI> +<LI><A HREF="#Python_nn60">31.9.2 Expanding a Python object into + multiple arguments</A></LI> +<LI><A HREF="#Python_nn61">31.9.3 Using typemaps to return arguments</A></LI> +<LI><A HREF="#Python_nn62">31.9.4 Mapping Python tuples into small + arrays</A></LI> +<LI><A HREF="#Python_nn63">31.9.5 Mapping sequences to C arrays</A></LI> +<LI><A HREF="#Python_nn64">31.9.6 Pointer handling</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_nn65">31.10 Docstring Features</A> +<UL> +<LI><A HREF="#Python_nn66">31.10.1 Module docstring</A></LI> +<LI><A HREF="#Python_nn67">31.10.2 %feature("autodoc")</A> +<UL> +<LI><A HREF="#Python_nn68">31.10.2.1 %feature("autodoc", "0")</A></LI> +<LI><A HREF="#Python_nn69">31.10.2.2 %feature("autodoc", "1")</A></LI> +<LI><A HREF="#Python_nn70">31.10.2.3 %feature("autodoc", "docstring")</A> +</LI> +</UL> +</LI> +<LI><A HREF="#Python_nn71">31.10.3 %feature("docstring")</A></LI> +</UL> +</LI> +<LI><A HREF="#Python_nn72">31.11 Python Packages</A></LI> +<LI><A HREF="#Python_python3support">31.12 Python 3 Support</A> +<UL> +<LI><A HREF="#Python_nn74">31.12.1 Function annotation</A></LI> +<LI><A HREF="#Python_nn75">31.12.2 Buffer interface</A></LI> +<LI><A HREF="#Python_nn76">31.12.3 Abstract base classes</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Ruby">32 SWIG and Ruby</A></B> +<UL> +<LI><A HREF="#Ruby_nn2">32.1 Preliminaries</A> +<UL> +<LI><A HREF="#Ruby_nn3">32.1.1 Running SWIG</A></LI> +<LI><A HREF="#Ruby_nn4">32.1.2 Getting the right header files</A></LI> +<LI><A HREF="#Ruby_nn5">32.1.3 Compiling a dynamic module</A></LI> +<LI><A HREF="#Ruby_nn6">32.1.4 Using your module</A></LI> +<LI><A HREF="#Ruby_nn7">32.1.5 Static linking</A></LI> +<LI><A HREF="#Ruby_nn8">32.1.6 Compilation of C++ extensions</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn9">32.2 Building Ruby Extensions under Windows + 95/NT</A> +<UL> +<LI><A HREF="#Ruby_nn10">32.2.1 Running SWIG from Developer Studio</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn11">32.3 The Ruby-to-C/C++ Mapping</A> +<UL> +<LI><A HREF="#Ruby_nn12">32.3.1 Modules</A></LI> +<LI><A HREF="#Ruby_nn13">32.3.2 Functions</A></LI> +<LI><A HREF="#Ruby_nn14">32.3.3 Variable Linking</A></LI> +<LI><A HREF="#Ruby_nn15">32.3.4 Constants</A></LI> +<LI><A HREF="#Ruby_nn16">32.3.5 Pointers</A></LI> +<LI><A HREF="#Ruby_nn17">32.3.6 Structures</A></LI> +<LI><A HREF="#Ruby_nn18">32.3.7 C++ classes</A></LI> +<LI><A HREF="#Ruby_nn19">32.3.8 C++ Inheritance</A></LI> +<LI><A HREF="#Ruby_nn20">32.3.9 C++ Overloaded Functions</A></LI> +<LI><A HREF="#Ruby_nn21">32.3.10 C++ Operators</A></LI> +<LI><A HREF="#Ruby_nn22">32.3.11 C++ namespaces</A></LI> +<LI><A HREF="#Ruby_nn23">32.3.12 C++ templates</A></LI> +<LI><A HREF="#Ruby_nn23_1">32.3.13 C++ Standard Template Library (STL)</A> +</LI> +<LI><A HREF="#C_STL_Functors">32.3.14 C++ STL Functors</A></LI> +<LI><A HREF="#Ruby_C_Iterators">32.3.15 C++ STL Iterators</A></LI> +<LI><A HREF="#Ruby_nn24">32.3.16 C++ Smart Pointers</A></LI> +<LI><A HREF="#Ruby_nn25">32.3.17 Cross-Language Polymorphism</A> +<UL> +<LI><A HREF="#Ruby_nn26">32.3.17.1 Exception Unrolling</A></LI> +</UL> +</LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn27">32.4 Naming</A> +<UL> +<LI><A HREF="#Ruby_nn28">32.4.1 Defining Aliases</A></LI> +<LI><A HREF="#Ruby_nn29">32.4.2 Predicate Methods</A></LI> +<LI><A HREF="#Ruby_nn30">32.4.3 Bang Methods</A></LI> +<LI><A HREF="#Ruby_nn31">32.4.4 Getters and Setters</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn32">32.5 Input and output parameters</A></LI> +<LI><A HREF="#Ruby_nn33">32.6 Exception handling</A> +<UL> +<LI><A HREF="#Ruby_nn34">32.6.1 Using the %exception directive</A></LI> +<LI><A HREF="#Ruby_nn34_2">32.6.2 Handling Ruby Blocks</A></LI> +<LI><A HREF="#Ruby_nn35">32.6.3 Raising exceptions</A></LI> +<LI><A HREF="#Ruby_nn36">32.6.4 Exception classes</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn37">32.7 Typemaps</A> +<UL> +<LI><A HREF="#Ruby_nn38">32.7.1 What is a typemap?</A></LI> +<LI><A HREF="#Ruby_Typemap_scope">32.7.2 Typemap scope</A></LI> +<LI><A HREF="#Ruby_Copying_a_typemap">32.7.3 Copying a typemap</A></LI> +<LI><A HREF="#Ruby_Deleting_a_typemap">32.7.4 Deleting a typemap</A></LI> +<LI><A HREF="#Ruby_Placement_of_typemaps">32.7.5 Placement of typemaps</A> +</LI> +<LI><A HREF="#Ruby_nn39">32.7.6 Ruby typemaps</A> +<UL> +<LI><A HREF="#Ruby_in_typemap">32.7.6.1 "in" typemap</A></LI> +<LI><A HREF="#Ruby_typecheck_typemap">32.7.6.2 "typecheck" typemap</A></LI> +<LI><A HREF="#Ruby_out_typemap">32.7.6.3 "out" typemap</A></LI> +<LI><A HREF="#Ruby_arginit_typemap">32.7.6.4 "arginit" typemap</A></LI> +<LI><A HREF="#Ruby_default_typemap">32.7.6.5 "default" typemap</A></LI> +<LI><A HREF="#Ruby_check_typemap">32.7.6.6 "check" typemap</A></LI> +<LI><A HREF="#Ruby_argout_typemap_">32.7.6.7 "argout" typemap</A></LI> +<LI><A HREF="#Ruby_freearg_typemap_">32.7.6.8 "freearg" typemap</A></LI> +<LI><A HREF="#Ruby_newfree_typemap">32.7.6.9 "newfree" typemap</A></LI> +<LI><A HREF="#Ruby_memberin_typemap">32.7.6.10 "memberin" typemap</A></LI> +<LI><A HREF="#Ruby_varin_typemap">32.7.6.11 "varin" typemap</A></LI> +<LI><A HREF="#Ruby_varout_typemap_">32.7.6.12 "varout" typemap</A></LI> +<LI><A HREF="#Ruby_throws_typemap">32.7.6.13 "throws" typemap</A></LI> +<LI><A HREF="#Ruby_directorin_typemap">32.7.6.14 directorin typemap</A></LI> +<LI><A HREF="#Ruby_directorout_typemap">32.7.6.15 directorout typemap</A> +</LI> +<LI><A HREF="#Ruby_directorargout_typemap">32.7.6.16 directorargout + typemap</A></LI> +<LI><A HREF="#Ruby_ret_typemap">32.7.6.17 ret typemap</A></LI> +<LI><A HREF="#Ruby_globalin_typemap">32.7.6.18 globalin typemap</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn40">32.7.7 Typemap variables</A></LI> +<LI><A HREF="#Ruby_nn41">32.7.8 Useful Functions</A> +<UL> +<LI><A HREF="#Ruby_nn42">32.7.8.1 C Datatypes to Ruby Objects</A></LI> +<LI><A HREF="#Ruby_nn43">32.7.8.2 Ruby Objects to C Datatypes</A></LI> +<LI><A HREF="#Ruby_nn44">32.7.8.3 Macros for VALUE</A></LI> +<LI><A HREF="#Ruby_nn45">32.7.8.4 Exceptions</A></LI> +<LI><A HREF="#Ruby_nn46">32.7.8.5 Iterators</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn47">32.7.9 Typemap Examples</A></LI> +<LI><A HREF="#Ruby_nn48">32.7.10 Converting a Ruby array to a char **</A> +</LI> +<LI><A HREF="#Ruby_nn49">32.7.11 Collecting arguments in a hash</A></LI> +<LI><A HREF="#Ruby_nn50">32.7.12 Pointer handling</A> +<UL> +<LI><A HREF="#Ruby_nn51">32.7.12.1 Ruby Datatype Wrapping</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn52">32.7.13 Example: STL Vector to Ruby Array</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn65">32.8 Docstring Features</A> +<UL> +<LI><A HREF="#Ruby_nn66">32.8.1 Module docstring</A></LI> +<LI><A HREF="#Ruby_nn67">32.8.2 %feature("autodoc")</A> +<UL> +<LI><A HREF="#Ruby_nn68">32.8.2.1 %feature("autodoc", "0")</A></LI> +<LI><A HREF="#Ruby_autodoc1">32.8.2.2 %feature("autodoc", "1")</A></LI> +<LI><A HREF="#Ruby_autodoc2">32.8.2.3 %feature("autodoc", "2")</A></LI> +<LI><A HREF="#Ruby_feature_autodoc3">32.8.2.4 %feature("autodoc", "3")</A> +</LI> +<LI><A HREF="#Ruby_nn70">32.8.2.5 %feature("autodoc", "docstring")</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn71">32.8.3 %feature("docstring")</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn53">32.9 Advanced Topics</A> +<UL> +<LI><A HREF="#Ruby_nn54">32.9.1 Operator overloading</A></LI> +<LI><A HREF="#Ruby_nn55">32.9.2 Creating Multi-Module Packages</A></LI> +<LI><A HREF="#Ruby_nn56">32.9.3 Specifying Mixin Modules</A></LI> +</UL> +</LI> +<LI><A HREF="#Ruby_nn57">32.10 Memory Management</A> +<UL> +<LI><A HREF="#Ruby_nn58">32.10.1 Mark and Sweep Garbage Collector</A></LI> +<LI><A HREF="#Ruby_nn59">32.10.2 Object Ownership</A></LI> +<LI><A HREF="#Ruby_nn60">32.10.3 Object Tracking</A></LI> +<LI><A HREF="#Ruby_nn61">32.10.4 Mark Functions</A></LI> +<LI><A HREF="#Ruby_nn62">32.10.5 Free Functions</A></LI> +<LI><A HREF="#Ruby_nn63">32.10.6 Embedded Ruby and the C++ Stack</A></LI> +</UL> +</LI> +</UL> +<B><A HREF="#Tcl">33 SWIG and Tcl</A></B> +<UL> +<LI><A HREF="#Tcl_nn2">33.1 Preliminaries</A> +<UL> +<LI><A HREF="#Tcl_nn3">33.1.1 Getting the right header files</A></LI> +<LI><A HREF="#Tcl_nn4">33.1.2 Compiling a dynamic module</A></LI> +<LI><A HREF="#Tcl_nn5">33.1.3 Static linking</A></LI> +<LI><A HREF="#Tcl_nn6">33.1.4 Using your module</A></LI> +<LI><A HREF="#Tcl_nn7">33.1.5 Compilation of C++ extensions</A></LI> +<LI><A HREF="#Tcl_nn8">33.1.6 Compiling for 64-bit platforms</A></LI> +<LI><A HREF="#Tcl_nn9">33.1.7 Setting a package prefix</A></LI> +<LI><A HREF="#Tcl_nn10">33.1.8 Using namespaces</A></LI> +</UL> +</LI> +<LI><A HREF="#Tcl_nn11">33.2 Building Tcl/Tk Extensions under Windows + 95/NT</A> +<UL> +<LI><A HREF="#Tcl_nn12">33.2.1 Running SWIG from Developer Studio</A></LI> +<LI><A HREF="#Tcl_nn13">33.2.2 Using NMAKE</A></LI> +</UL> +</LI> +<LI><A HREF="#Tcl_nn14">33.3 A tour of basic C/C++ wrapping</A> +<UL> +<LI><A HREF="#Tcl_nn15">33.3.1 Modules</A></LI> +<LI><A HREF="#Tcl_nn16">33.3.2 Functions</A></LI> +<LI><A HREF="#Tcl_nn17">33.3.3 Global variables</A></LI> +<LI><A HREF="#Tcl_nn18">33.3.4 Constants and enums</A></LI> +<LI><A HREF="#Tcl_nn19">33.3.5 Pointers</A></LI> +<LI><A HREF="#Tcl_nn20">33.3.6 Structures</A></LI> +<LI><A HREF="#Tcl_nn21">33.3.7 C++ classes</A></LI> +<LI><A HREF="#Tcl_nn22">33.3.8 C++ inheritance</A></LI> +<LI><A HREF="#Tcl_nn23">33.3.9 Pointers, references, values, and arrays</A> +</LI> +<LI><A HREF="#Tcl_nn24">33.3.10 C++ overloaded functions</A></LI> +<LI><A HREF="#Tcl_nn25">33.3.11 C++ operators</A></LI> +<LI><A HREF="#Tcl_nn26">33.3.12 C++ namespaces</A></LI> +<LI><A HREF="#Tcl_nn27">33.3.13 C++ templates</A></LI> +<LI><A HREF="#Tcl_nn28">33.3.14 C++ Smart Pointers</A></LI> +</UL> +</LI> +<LI><A HREF="#Tcl_nn29">33.4 Further details on the Tcl class interface</A> +<UL> +<LI><A HREF="#Tcl_nn30">33.4.1 Proxy classes</A></LI> +<LI><A HREF="#Tcl_nn31">33.4.2 Memory management</A></LI> +</UL> +</LI> +<LI><A HREF="#Tcl_nn32">33.5 Input and output parameters</A></LI> +<LI><A HREF="#Tcl_nn33">33.6 Exception handling</A></LI> +<LI><A HREF="#Tcl_nn34">33.7 Typemaps</A> +<UL> +<LI><A HREF="#Tcl_nn35">33.7.1 What is a typemap?</A></LI> +<LI><A HREF="#Tcl_nn36">33.7.2 Tcl typemaps</A></LI> +<LI><A HREF="#Tcl_nn37">33.7.3 Typemap variables</A></LI> +<LI><A HREF="#Tcl_nn38">33.7.4 Converting a Tcl list to a char **</A></LI> +<LI><A HREF="#Tcl_nn39">33.7.5 Returning values in arguments</A></LI> +<LI><A HREF="#Tcl_nn40">33.7.6 Useful functions</A></LI> +<LI><A HREF="#Tcl_nn41">33.7.7 Standard typemaps</A></LI> +<LI><A HREF="#Tcl_nn42">33.7.8 Pointer handling</A></LI> +</UL> +</LI> +<LI><A HREF="#Tcl_nn43">33.8 Turning a SWIG module into a Tcl Package.</A> +</LI> +<LI><A HREF="#Tcl_nn44">33.9 Building new kinds of Tcl interfaces (in + Tcl)</A> +<UL> +<LI><A HREF="#Tcl_nn45">33.9.1 Proxy classes</A></LI> +</UL> +</LI> +<LI><A HREF="#Tcl_nn46">33.10 Tcl/Tk Stubs</A></LI> +</UL> +<B><A HREF="#R">34 SWIG and R</A></B> +<UL> +<LI><A HREF="#R_nn2">34.1 Bugs</A></LI> +<LI><A HREF="#R_nn3">34.2 Using R and SWIG</A></LI> +<LI><A HREF="#R_nn4">34.3 Precompiling large R files</A></LI> +<LI><A HREF="#R_nn5">34.4 General policy</A></LI> +<LI><A HREF="#R_language_conventions">34.5 Language conventions</A></LI> +<LI><A HREF="#R_nn6">34.6 C++ classes</A></LI> +<LI><A HREF="#R_nn7">34.7 Enumerations</A></LI> +</UL> +<B><A HREF="#Extending">35 Extending SWIG to support new languages</A></B> +<UL> +<LI><A HREF="#Extending_nn2">35.1 Introduction</A></LI> +<LI><A HREF="#Extending_nn3">35.2 Prerequisites</A></LI> +<LI><A HREF="#Extending_nn4">35.3 The Big Picture</A></LI> +<LI><A HREF="#Extending_nn5">35.4 Execution Model</A> +<UL> +<LI><A HREF="#Extending_nn6">35.4.1 Preprocessing</A></LI> +<LI><A HREF="#Extending_nn7">35.4.2 Parsing</A></LI> +<LI><A HREF="#Extending_nn8">35.4.3 Parse Trees</A></LI> +<LI><A HREF="#Extending_nn9">35.4.4 Attribute namespaces</A></LI> +<LI><A HREF="#Extending_nn10">35.4.5 Symbol Tables</A></LI> +<LI><A HREF="#Extending_nn11">35.4.6 The %feature directive</A></LI> +<LI><A HREF="#Extending_nn12">35.4.7 Code Generation</A></LI> +<LI><A HREF="#Extending_nn13">35.4.8 SWIG and XML</A></LI> +</UL> +</LI> +<LI><A HREF="#Extending_nn14">35.5 Primitive Data Structures</A> +<UL> +<LI><A HREF="#Extending_nn15">35.5.1 Strings</A></LI> +<LI><A HREF="#Extending_nn16">35.5.2 Hashes</A></LI> +<LI><A HREF="#Extending_nn17">35.5.3 Lists</A></LI> +<LI><A HREF="#Extending_nn18">35.5.4 Common operations</A></LI> +<LI><A HREF="#Extending_nn19">35.5.5 Iterating over Lists and Hashes</A></LI> +<LI><A HREF="#Extending_nn20">35.5.6 I/O</A></LI> +</UL> +</LI> +<LI><A HREF="#Extending_nn21">35.6 Navigating and manipulating parse + trees</A></LI> +<LI><A HREF="#Extending_nn22">35.7 Working with attributes</A></LI> +<LI><A HREF="#Extending_nn23">35.8 Type system</A> +<UL> +<LI><A HREF="#Extending_nn24">35.8.1 String encoding of types</A></LI> +<LI><A HREF="#Extending_nn25">35.8.2 Type construction</A></LI> +<LI><A HREF="#Extending_nn26">35.8.3 Type tests</A></LI> +<LI><A HREF="#Extending_nn27">35.8.4 Typedef and inheritance</A></LI> +<LI><A HREF="#Extending_nn28">35.8.5 Lvalues</A></LI> +<LI><A HREF="#Extending_nn29">35.8.6 Output functions</A></LI> +</UL> +</LI> +<LI><A HREF="#Extending_nn30">35.9 Parameters</A></LI> +<LI><A HREF="#Extending_nn31">35.10 Writing a Language Module</A> +<UL> +<LI><A HREF="#Extending_nn32">35.10.1 Execution model</A></LI> +<LI><A HREF="#Extending_nn33">35.10.2 Starting out</A></LI> +<LI><A HREF="#Extending_nn34">35.10.3 Command line options</A></LI> +<LI><A HREF="#Extending_nn35">35.10.4 Configuration and preprocessing</A> +</LI> +<LI><A HREF="#Extending_nn36">35.10.5 Entry point to code generation</A></LI> +<LI><A HREF="#Extending_nn37">35.10.6 Module I/O and wrapper skeleton</A> +</LI> +<LI><A HREF="#Extending_nn38">35.10.7 Low-level code generators</A></LI> +<LI><A HREF="#Extending_nn39">35.10.8 Configuration files</A></LI> +<LI><A HREF="#Extending_nn40">35.10.9 Runtime support</A></LI> +<LI><A HREF="#Extending_nn41">35.10.10 Standard library files</A></LI> +<LI><A HREF="#Extending_nn42">35.10.11 Examples and test cases</A></LI> +<LI><A HREF="#Extending_nn43">35.10.12 Documentation</A></LI> +<LI><A HREF="#Extending_prerequisites">35.10.13 Prerequisites for adding + a new language module to the SWIG distribution</A></LI> +<LI><A HREF="#Extending_coding_style_guidelines">35.10.14 Coding style + guidelines</A></LI> +</UL> +</LI> +<LI><A HREF="#Extending_nn44">35.11 Typemaps</A> +<UL> +<LI><A HREF="#Extending_nn45">35.11.1 Proxy classes</A></LI> +</UL> +</LI> +<LI><A HREF="#Extending_nn46">35.12 Guide to parse tree nodes</A></LI> +</UL> +<HR NOSHADE> +<H1><A name="Sections"></A>SWIG-1.3 Development Documentation</H1> + Last update : SWIG-1.3.40 (18 August 2009) +<H2><A NAME="1_1">Sections</A></H2> +<P> The SWIG documentation is being updated to reflect new SWIG features + and enhancements. However, this update process is not quite + finished--there is a lot of old SWIG-1.1 documentation and it is taking + some time to update all of it. Please pardon our dust (or volunteer to + help!).</P> +<H3><A NAME="1_1_1">SWIG Core Documentation</A></H3> +<UL> +<LI><A href="#Preface">Preface</A></LI> +<LI><A href="#Introduction">Introduction</A></LI> +<LI><A href="#Windows">Getting started on Windows</A></LI> +<LI><A href="#Scripting">Scripting</A></LI> +<LI><A href="#SWIG">SWIG Basics</A> (Read this!)</LI> +<LI><A href="#SWIGPlus">SWIG and C++</A></LI> +<LI><A href="#Preprocessor">The SWIG preprocessor</A></LI> +<LI><A href="#Library">The SWIG Library</A></LI> +<LI><A href="#Arguments">Argument handling</A></LI> +<LI><A href="#Typemaps">Typemaps</A></LI> +<LI><A href="#Customization">Customization features</A></LI> +<LI><A href="#Contract">Contracts</A></LI> +<LI><A href="#Varargs">Variable length arguments</A></LI> +<LI><A href="#Warnings">Warning messages</A></LI> +<LI><A href="#Modules">Working with Modules</A></LI> +<LI><A href="#CCache">Using SWIG with ccache</A></LI> +</UL> +<H3><A NAME="1_1_2">Language Module Documentation</A></H3> +<UL> +<LI><A href="#Allegrocl_nn1">Allegro CL support</A></LI> +<LI><A href="#CSharp">C# support</A></LI> +<LI><A href="#Chicken">Chicken support</A></LI> +<LI><A href="#Guile">Guile support</A></LI> +<LI><A href="#Java">Java support</A></LI> +<LI><A href="#Lua_nn1">Lua support</A></LI> +<LI><A href="#Lisp_nn1">Common Lisp support</A></LI> +<LI><A href="#Modula3">Modula3 support</A></LI> +<LI><A href="#MzScheme">MzScheme support</A></LI> +<LI><A href="#Ocaml">Ocaml support</A></LI> +<LI><A href="#Octave">Octave support</A></LI> +<LI><A href="#Perl5">Perl5 support</A></LI> +<LI><A href="#Php">PHP support</A></LI> +<LI><A href="#Pike">Pike support</A></LI> +<LI><A href="#Python">Python support</A></LI> +<LI><A href="#Ruby">Ruby support</A></LI> +<LI><A href="#R">R support</A></LI> +<LI><A href="#Tcl">Tcl support</A></LI> +</UL> +<H3><A NAME="1_1_3">Developer Documentation</A></H3> +<UL> +<LI><A href="#Extending">Extending SWIG</A></LI> +</UL> +<H3><A NAME="1_1_4">Documentation that has not yet been updated</A></H3> +<P> This documentation has not been completely updated from SWIG-1.1, + but most of the topics still apply to the current release. Make sure + you read the <A href="#SWIG">SWIG Basics</A> chapter before reading any + of these chapters. Also, SWIG-1.3.10 features extensive changes to the + implementation of typemaps. Make sure you read the <A href="#Typemaps"> +Typemaps</A> chapter above if you are using this feature.</P> +<UL> +<LI><A href="Advanced.html#Advanced">Advanced topics</A> (see <A href="#Modules"> +Modules</A> for updated information).</LI> +</UL> +<HR NOSHADE> +<H1><A name="Preface"></A>1 Preface</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Preface_nn2">Introduction</A></LI> +<LI><A href="#Preface_nn3">Special Introduction for Version 1.3</A></LI> +<LI><A href="#Preface_nn4">SWIG Versions</A></LI> +<LI><A href="#Preface_nn5">SWIG resources</A></LI> +<LI><A href="#Preface_nn6">Prerequisites</A></LI> +<LI><A href="#Preface_nn7">Organization of this manual</A></LI> +<LI><A href="#Preface_nn8">How to avoid reading the manual</A></LI> +<LI><A href="#Preface_nn9">Backwards Compatibility</A></LI> +<LI><A href="#Preface_nn10">Credits</A></LI> +<LI><A href="#Preface_nn11">Bug reports</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<H2><A name="Preface_nn2"></A>1.1 Introduction</H2> +<P> SWIG (Simplified Wrapper and Interface Generator) is a software + development tool for building scripting language interfaces to C and + C++ programs. Originally developed in 1995, SWIG was first used by + scientists in the Theoretical Physics Division at Los Alamos National + Laboratory for building user interfaces to simulation codes running on + the Connection Machine 5 supercomputer. In this environment, scientists + needed to work with huge amounts of simulation data, complex hardware, + and a constantly changing code base. The use of a scripting language + interface provided a simple yet highly flexible foundation for solving + these types of problems. SWIG simplifies development by largely + automating the task of scripting language integration--allowing + developers and users to focus on more important problems.</P> +<P> Although SWIG was originally developed for scientific applications, + it has since evolved into a general purpose tool that is used in a wide + variety of applications--in fact almost anything where C/C++ + programming is involved.</P> +<H2><A name="Preface_nn3"></A>1.2 Special Introduction for Version 1.3</H2> +<P> Since SWIG was released in 1996, its user base and applicability has + continued to grow. Although its rate of development has varied, an + active development effort has continued to make improvements to the + system. Today, nearly a dozen developers are working to create + SWIG-2.0---a system that aims to provide wrapping support for nearly + all of the ANSI C++ standard and approximately ten target languages + including Guile, Java, Mzscheme, Ocaml, Perl, Pike, PHP, Python, Ruby, + and Tcl.</P> +<H2><A name="Preface_nn4"></A>1.3 SWIG Versions</H2> +<P> For several years, the most stable version of SWIG has been release + 1.1p5. Starting with version 1.3, a new version numbering scheme has + been adopted. Odd version numbers (1.3, 1.5, etc.) represent + development versions of SWIG. Even version numbers (1.4, 1.6, etc.) + represent stable releases. Currently, developers are working to create + a stable SWIG-2.0 release. Don't let the development status of SWIG-1.3 + scare you---it is much more stable (and capable) than SWIG-1.1p5.</P> +<H2><A name="Preface_nn5"></A>1.4 SWIG resources</H2> +<P> The official location of SWIG related material is</P> +<DIV class="shell"> +<PRE> +<A href="http://www.swig.org">http://www.swig.org</A> +</PRE> +</DIV> +<P> This site contains the latest version of the software, users guide, + and information regarding bugs, installation problems, and + implementation tricks.</P> +<P> You can also subscribe to the swig-user mailing list by visiting the + page</P> +<DIV class="shell"> +<PRE> +<A href="http://www.swig.org/mail.html">http://www.swig.org/mail.html</A> +</PRE> +</DIV> +<P> The mailing list often discusses some of the more technical aspects + of SWIG along with information about beta releases and future work.</P> +<P> SVN access to the latest version of SWIG is also available. More + information about this can be obtained at:</P> +<DIV class="shell"> +<PRE> +<A href="http://www.swig.org/svn.html">http://www.swig.org/svn.html</A> +</PRE> +</DIV> +<H2><A name="Preface_nn6"></A>1.5 Prerequisites</H2> +<P> This manual assumes that you know how to write C/C++ programs and + that you have at least heard of scripting languages such as Tcl, + Python, and Perl. A detailed knowledge of these scripting languages is + not required although some familiarity won't hurt. No prior experience + with building C extensions to these languages is required---after all, + this is what SWIG does automatically. However, you should be reasonably + familiar with the use of compilers, linkers, and makefiles since making + scripting language extensions is somewhat more complicated than writing + a normal C program.</P> +<P> Recent SWIG releases have become significantly more capable in their + C++ handling--especially support for advanced features like namespaces, + overloaded operators, and templates. Whenever possible, this manual + tries to cover the technicalities of this interface. However, this + isn't meant to be a tutorial on C++ programming. For many of the gory + details, you will almost certainly want to consult a good C++ + reference. If you don't program in C++, you may just want to skip those + parts of the manual.</P> +<H2><A name="Preface_nn7"></A>1.6 Organization of this manual</H2> +<P> The first few chapters of this manual describe SWIG in general and + provide an overview of its capabilities. The remaining chapters are + devoted to specific SWIG language modules and are self contained. Thus, + if you are using SWIG to build Python interfaces, you can probably skip + to that chapter and find almost everything you need to know. Caveat: we + are currently working on a documentation rewrite and many of the older + language module chapters are still somewhat out of date.</P> +<H2><A name="Preface_nn8"></A>1.7 How to avoid reading the manual</H2> +<P> If you hate reading manuals, glance at the "Introduction" which + contains a few simple examples. These examples contain about 95% of + everything you need to know to use SWIG. After that, simply use the + language-specific chapters as a reference. The SWIG distribution also + comes with a large directory of examples that illustrate different + topics.</P> +<H2><A name="Preface_nn9"></A>1.8 Backwards Compatibility</H2> +<P> If you are a previous user of SWIG, don't expect recent versions of + SWIG to provide backwards compatibility. In fact, backwards + compatibility issues may arise even between successive 1.3.x releases. + Although these incompatibilities are regrettable, SWIG-1.3 is an active + development project. The primary goal of this effort is to make SWIG + better---a process that would simply be impossible if the developers + are constantly bogged down with backwards compatibility issues.</P> +<P> On a positive note, a few incompatibilities are a small price to pay + for the large number of new features that have been added---namespaces, + templates, smart pointers, overloaded methods, operators, and more.</P> +<P> If you need to work with different versions of SWIG and backwards + compatibility is an issue, you can use the SWIG_VERSION preprocessor + symbol which holds the version of SWIG being executed. SWIG_VERSION is + a hexadecimal integer such as 0x010311 (corresponding to SWIG-1.3.11). + This can be used in an interface file to define different typemaps, + take advantage of different features etc:</P> +<DIV class="code"> +<PRE> +#if SWIG_VERSION >= 0x010311 +/* Use some fancy new feature */ +#endif +</PRE> +</DIV> +<P> Note: The version symbol is not defined in the generated SWIG + wrapper file. The SWIG preprocessor has defined SWIG_VERSION since + SWIG-1.3.11.</P> +<H2><A name="Preface_nn10"></A>1.9 Credits</H2> +<P> SWIG is an unfunded project that would not be possible without the + contributions of many people. Most recent SWIG development has been + supported by Matthias Köppe, William Fulton, Lyle Johnson, Richard + Palmer, Thien-Thi Nguyen, Jason Stewart, Loic Dachary, Masaki + Fukushima, Luigi Ballabio, Sam Liddicott, Art Yerkes, Marcelo Matus, + Harco de Hilster, John Lenz, and Surendra Singhi.</P> +<P> Historically, the following people contributed to early versions of + SWIG. Peter Lomdahl, Brad Holian, Shujia Zhou, Niels Jensen, and Tim + Germann at Los Alamos National Laboratory were the first users. Patrick + Tullmann at the University of Utah suggested the idea of automatic + documentation generation. John Schmidt and Kurtis Bleeker at the + University of Utah tested out the early versions. Chris Johnson + supported SWIG's developed at the University of Utah. John Buckman, + Larry Virden, and Tom Schwaller provided valuable input on the first + releases and improving the portability of SWIG. David Fletcher and Gary + Holt have provided a great deal of input on improving SWIG's Perl5 + implementation. Kevin Butler contributed the first Windows NT port.</P> +<H2><A name="Preface_nn11"></A>1.10 Bug reports</H2> +<P> Although every attempt has been made to make SWIG bug-free, we are + also trying to make feature improvements that may introduce bugs. To + report a bug, either send mail to the SWIG developer list at the <A href="http://www.swig.org/mail.html"> +swig-devel mailing list</A> or report a bug at the <A href="http://www.swig.org/bugs.html"> +SWIG bug tracker</A>. In your report, be as specific as possible, + including (if applicable), error messages, tracebacks (if a core dump + occurred), corresponding portions of the SWIG interface file used, and + any important pieces of the SWIG generated wrapper code. We can only + fix bugs if we know about them.</P> +<HR NOSHADE> +<H1><A name="Introduction"></A>2 Introduction</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Introduction_nn2">What is SWIG?</A></LI> +<LI><A href="#Introduction_nn3">Why use SWIG?</A></LI> +<LI><A href="#Introduction_nn4">A SWIG example</A> +<UL> +<LI><A href="#Introduction_nn5">SWIG interface file</A></LI> +<LI><A href="#Introduction_nn6">The swig command</A></LI> +<LI><A href="#Introduction_nn7">Building a Perl5 module</A></LI> +<LI><A href="#Introduction_nn8">Building a Python module</A></LI> +<LI><A href="#Introduction_nn9">Shortcuts</A></LI> +</UL> +</LI> +<LI><A href="#Introduction_nn10">Supported C/C++ language features</A></LI> +<LI><A href="#Introduction_nn11">Non-intrusive interface building</A></LI> +<LI><A href="#Introduction_build_system">Incorporating SWIG into a build + system</A></LI> +<LI><A href="#Introduction_nn12">Hands off code generation</A></LI> +<LI><A href="#Introduction_nn13">SWIG and freedom</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<H2><A name="Introduction_nn2"></A>2.1 What is SWIG?</H2> +<P> SWIG is a software development tool that simplifies the task of + interfacing different languages to C and C++ programs. In a nutshell, + SWIG is a compiler that takes C declarations and creates the wrappers + needed to access those declarations from other languages including + including Perl, Python, Tcl, Ruby, Guile, and Java. SWIG normally + requires no modifications to existing code and can often be used to + build a usable interface in only a few minutes. Possible applications + of SWIG include:</P> +<UL> +<LI>Building interpreted interfaces to existing C programs.</LI> +<LI>Rapid prototyping and application development.</LI> +<LI>Interactive debugging.</LI> +<LI>Reengineering or refactoring of legacy software into a scripting + language components.</LI> +<LI>Making a graphical user interface (using Tk for example).</LI> +<LI>Testing of C libraries and programs (using scripts).</LI> +<LI>Building high performance C modules for scripting languages.</LI> +<LI>Making C programming more enjoyable (or tolerable depending on your + point of view).</LI> +<LI>Impressing your friends.</LI> +<LI>Obtaining vast sums of research funding (although obviously not + applicable to the author).</LI> +</UL> +<P> SWIG was originally designed to make it extremely easy for + scientists and engineers to build extensible scientific software + without having to get a degree in software engineering. Because of + this, the use of SWIG tends to be somewhat informal and ad-hoc (e.g., + SWIG does not require users to provide formal interface specifications + as you would find in a dedicated IDL compiler). Although this style of + development isn't appropriate for every project, it is particularly + well suited to software development in the small; especially the + research and development work that is commonly found in scientific and + engineering projects.</P> +<H2><A name="Introduction_nn3"></A>2.2 Why use SWIG?</H2> +<P> As stated in the previous section, the primary purpose of SWIG is to + simplify the task of integrating C/C++ with other programming + languages. However, why would anyone want to do that? To answer that + question, it is useful to list a few strengths of C/C++ programming:</P> +<UL> +<LI>Excellent support for writing programming libraries.</LI> +<LI>High performance (number crunching, data processing, graphics, + etc.).</LI> +<LI>Systems programming and systems integration.</LI> +<LI>Large user community and software base.</LI> +</UL> +<P> Next, let's list a few problems with C/C++ programming</P> +<UL> +<LI>Writing a user interface is rather painful (i.e., consider + programming with MFC, X11, GTK, or any number of other libraries).</LI> +<LI>Testing is time consuming (the compile/debug cycle).</LI> +<LI>Not easy to reconfigure or customize without recompilation.</LI> +<LI>Modularization can be tricky.</LI> +<LI>Security concerns (buffer overflow for instance).</LI> +</UL> +<P> To address these limitations, many programmers have arrived at the + conclusion that it is much easier to use different programming + languages for different tasks. For instance, writing a graphical user + interface may be significantly easier in a scripting language like + Python or Tcl (consider the reasons why millions of programmers have + used languages like Visual Basic if you need more proof). An + interactive interpreter might also serve as a useful debugging and + testing tool. Other languages like Java might greatly simplify the task + of writing distributed computing software. The key point is that + different programming languages offer different strengths and + weaknesses. Moreover, it is extremely unlikely that any programming is + ever going to be perfect. Therefore, by combining languages together, + you can utilize the best features of each language and greatly simplify + certain aspects of software development.</P> +<P> From the standpoint of C/C++, a lot of people use SWIG because they + want to break out of the traditional monolithic C programming model + which usually results in programs that resemble this:</P> +<UL> +<LI>A collection of functions and variables that do something useful.</LI> +<LI>A <TT>main()</TT> program that starts everything.</LI> +<LI>A horrible collection of hacks that form some kind of user interface + (but which no-one really wants to touch).</LI> +</UL> +<P> Instead of going down that route, incorporating C/C++ into a higher + level language often results in a more modular design, less code, + better flexibility, and increased programmer productivity.</P> +<P> SWIG tries to make the problem of C/C++ integration as painless as + possible. This allows you to focus on the underlying C program and + using the high-level language interface, but not the tedious and + complex chore of making the two languages talk to each other. At the + same time, SWIG recognizes that all applications are different. + Therefore, it provides a wide variety of customization features that + let you change almost every aspect of the language bindings. This is + the main reason why SWIG has such a large user manual ;-).</P> +<H2><A name="Introduction_nn4"></A>2.3 A SWIG example</H2> +<P> The best way to illustrate SWIG is with a simple example. Consider + the following C code:</P> +<DIV class="code"> +<PRE> +/* File : example.c */ + +double My_variable = 3.0; + +/* Compute factorial of n */ +int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); +} + +/* Compute n mod m */ +int my_mod(int n, int m) { + return(n % m); +} +</PRE> +</DIV> +<P> Suppose that you wanted to access these functions and the global + variable <TT>My_variable</TT> from Tcl. You start by making a SWIG + interface file as shown below (by convention, these files carry a .i + suffix) :</P> +<H3><A name="Introduction_nn5"></A>2.3.1 SWIG interface file</H3> +<DIV class="code"> +<PRE> +/* File : example.i */ +%module example +%{ +/* Put headers and other declarations here */ +extern double My_variable; +extern int fact(int); +extern int my_mod(int n, int m); +%} + +extern double My_variable; +extern int fact(int); +extern int my_mod(int n, int m); +</PRE> +</DIV> +<P> The interface file contains ANSI C function prototypes and variable + declarations. The <TT>%module</TT> directive defines the name of the + module that will be created by SWIG. The <TT>%{,%}</TT> block provides + a location for inserting additional code such as C header files or + additional C declarations.</P> +<H3><A name="Introduction_nn6"></A>2.3.2 The swig command</H3> +<P> SWIG is invoked using the <TT>swig</TT> command. We can use this to + build a Tcl module (under Linux) as follows :</P> +<DIV class="shell"> +<PRE> +unix > <B>swig -tcl example.i</B> +unix > <B>gcc -c -fpic example.c example_wrap.c -I/usr/local/include</B> +unix > <B>gcc -shared example.o example_wrap.o -o example.so</B> +unix > <B>tclsh</B> +% <B>load ./example.so</B> +% <B>fact 4</B> +24 +% <B>my_mod 23 7</B> +2 +% <B>expr $My_variable + 4.5</B> +7.5 +% +</PRE> +</DIV> +<P> The <TT>swig</TT> command produced a new file called <TT> +example_wrap.c</TT> that should be compiled along with the <TT>example.c</TT> + file. Most operating systems and scripting languages now support + dynamic loading of modules. In our example, our Tcl module has been + compiled into a shared library that can be loaded into Tcl. When + loaded, Tcl can now access the functions and variables declared in the + SWIG interface. A look at the file <TT>example_wrap.c</TT> reveals a + hideous mess. However, you almost never need to worry about it.</P> +<H3><A name="Introduction_nn7"></A>2.3.3 Building a Perl5 module</H3> +<P> Now, let's turn these functions into a Perl5 module. Without making + any changes type the following (shown for Solaris):</P> +<DIV class="shell"> +<PRE> +unix > <B>swig -perl5 example.i</B> +unix > <B>gcc -c example.c example_wrap.c \ + -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</B> +unix > <B>ld -G example.o example_wrap.o -o example.so</B> # This is for Solaris +unix > <B>perl5.003 +use example; +print example::fact(4), "\n"; +print example::my_mod(23,7), "\n"; +print $example::My_variable + 4.5, "\n"; +<ctrl-d></B> +24 +2 +7.5 +unix > +</PRE> +</DIV> +<H3><A name="Introduction_nn8"></A>2.3.4 Building a Python module</H3> +<P> Finally, let's build a module for Python (shown for Irix).</P> +<DIV class="shell"> +<PRE> +unix > <B>swig -python example.i</B> +unix > <B>gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0</B> +unix > <B>gcc -shared example.o example_wrap.o -o _example.so</B> +unix > <B>python</B> +Python 2.0 (#6, Feb 21 2001, 13:29:45) +[GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2 +Type "copyright", "credits" or "license" for more information. +>>> <B>import example</B> +>>> <B>example.fact(4)</B> +24 +>>> <B>example.my_mod(23,7)</B> +2 +>>> <B>example.cvar.My_variable + 4.5</B> +7.5 +</PRE> +</DIV> +<H3><A name="Introduction_nn9"></A>2.3.5 Shortcuts</H3> +<P> To the truly lazy programmer, one may wonder why we needed the extra + interface file at all. As it turns out, you can often do without it. + For example, you could also build a Perl5 module by just running SWIG + on the C header file and specifying a module name as follows</P> +<DIV class="shell"> +<PRE> +unix > <B>swig -perl5 -module example example.h</B> +unix > <B>gcc -c example.c example_wrap.c \ + -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</B> +unix > <B>ld -G example.o example_wrap.o -o example.so</B> +unix > <B>perl5.003 +use example; +print example::fact(4), "\n"; +print example::my_mod(23,7), "\n"; +print $example::My_variable + 4.5, "\n"; +<ctrl-d></B> +24 +2 +7.5 +</PRE> +</DIV> +<H2><A name="Introduction_nn10"></A>2.4 Supported C/C++ language + features</H2> +<P> A primary goal of the SWIG project is to make the language binding + process extremely easy. Although a few simple examples have been shown, + SWIG is quite capable in supporting most of C++. Some of the major + features include:</P> +<UL> +<LI>Full C99 preprocessing.</LI> +<LI>All ANSI C and C++ datatypes.</LI> +<LI>Functions, variables, and constants.</LI> +<LI>Classes.</LI> +<LI>Single and multiple inheritance.</LI> +<LI>Overloaded functions and methods.</LI> +<LI>Overloaded operators.</LI> +<LI>C++ templates (including member templates, specialization, and + partial specialization).</LI> +<LI>Namespaces.</LI> +<LI>Variable length arguments.</LI> +<LI>C++ smart pointers.</LI> +</UL> +<P> Currently, the only major C++ feature not supported is nested + classes--a limitation that will be removed in a future release.</P> +<P> It is important to stress that SWIG is not a simplistic C++ lexing + tool like several apparently similar wrapper generation tools. SWIG not + only parses C++, it implements the full C++ type system and it is able + to understand C++ semantics. SWIG generates its wrappers with full + knowledge of this information. As a result, you will find SWIG to be + just as capable of dealing with nasty corner cases as it is in wrapping + simple C++ code. In fact, SWIG is able handle C++ code that stresses + the very limits of many C++ compilers.</P> +<H2><A name="Introduction_nn11"></A>2.5 Non-intrusive interface building</H2> +<P> When used as intended, SWIG requires minimal (if any) modification + to existing C or C++ code. This makes SWIG extremely easy to use with + existing packages and promotes software reuse and modularity. By making + the C/C++ code independent of the high level interface, you can change + the interface and reuse the code in other applications. It is also + possible to support different types of interfaces depending on the + application.</P> +<H2><A name="Introduction_build_system"></A>2.6 Incorporating SWIG into + a build system</H2> +<P> SWIG is a command line tool and as such can be incorporated into any + build system that supports invoking external tools/compilers. SWIG is + most commonly invoked from within a Makefile, but is also known to be + invoked from from popular IDEs such as Microsoft Visual Studio.</P> +<P> If you are using the GNU Autotools (<A href="http://www.gnu.org/software/autoconf"> +Autoconf</A>/ <A href="http://www.gnu.org/software/automake">Automake</A> +/ <A href="http://www.gnu.org/software/libtool">Libtool</A>) to + configure SWIG use in your project, the SWIG Autoconf macros can be + used. The primary macro is <TT>ac_pkg_swig</TT>, see <A href="http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html"> +http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html</A>. The + <TT>ac_python_devel</TT> macro is also helpful for generating Python + extensions. See the <A href="http://www.gnu.org/software/ac-archive/htmldoc/index.html"> +Autoconf Macro Archive</A> for further information on this and other + Autoconf macros.</P> +<P> There is growing support for SWIG in some build tools, for example <A +href="http://www.cmake.org">CMake</A> is a cross-platform, open-source + build manager with built in support for SWIG. CMake can detect the SWIG + executable and many of the target language libraries for linking + against. CMake knows how to build shared libraries and loadable modules + on many different operating systems. This allows easy cross platform + SWIG development. It also can generate the custom commands necessary + for driving SWIG from IDE's and makefiles. All of this can be done from + a single cross platform input file. The following example is a CMake + input file for creating a python wrapper for the SWIG interface file, + example.i:</P> +<DIV class="code"> +<PRE> + +# This is a CMake example for Python + +FIND_PACKAGE(SWIG REQUIRED) +INCLUDE(${SWIG_USE_FILE}) + +FIND_PACKAGE(PythonLibs) +INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) + +SET(CMAKE_SWIG_FLAGS "") + +SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall") +SWIG_ADD_MODULE(example python example.i example.cxx) +SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES}) + +</PRE> +</DIV> +<P> The above example will generate native build files such as + makefiles, nmake files and Visual Studio projects which will invoke + SWIG and compile the generated C++ files into _example.so (UNIX) or + _example.pyd (Windows). For other target languages on Windows a dll, + instead of a .pyd file, is usually generated.</P> +<H2><A name="Introduction_nn12"></A>2.7 Hands off code generation</H2> +<P> SWIG is designed to produce working code that needs no + hand-modification (in fact, if you look at the output, you probably + won't want to modify it). You should think of your target language + interface being defined entirely by the input to SWIG, not the + resulting output file. While this approach may limit flexibility for + hard-core hackers, it allows others to forget about the low-level + implementation details.</P> +<H2><A name="Introduction_nn13"></A>2.8 SWIG and freedom</H2> +<P> No, this isn't a special section on the sorry state of world + politics. However, it may be useful to know that SWIG was written with + a certain "philosophy" about programming---namely that programmers are + smart and that tools should just stay out of their way. Because of + that, you will find that SWIG is extremely permissive in what it lets + you get away with. In fact, you can use SWIG to go well beyond + "shooting yourself in the foot" if dangerous programming is your goal. + On the other hand, this kind of freedom may be exactly what is needed + to work with complicated and unusual C/C++ applications.</P> +<P> Ironically, the freedom that SWIG provides is countered by an + extremely conservative approach to code generation. At it's core, SWIG + tries to distill even the most advanced C++ code down to a small + well-defined set of interface building techniques based on ANSI C + programming. Because of this, you will find that SWIG interfaces can be + easily compiled by virtually every C/C++ compiler and that they can be + used on any platform. Again, this is an important part of staying out + of the programmer's way----the last thing any developer wants to do is + to spend their time debugging the output of a tool that relies on + non-portable or unreliable programming features.</P> +<HR NOSHADE> +<H1><A name="Windows"></A>3 Getting started on Windows</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Windows_installation">Installation on Windows</A> +<UL> +<LI><A href="#Windows_executable">Windows Executable</A></LI> +</UL> +</LI> +<LI><A href="#Windows_examples">SWIG Windows Examples</A> +<UL> +<LI><A href="#Windows_visual_studio">Instructions for using the Examples + with Visual Studio</A> +<UL> +<LI><A href="#Windows_csharp">C#</A></LI> +<LI><A href="#Windows_java">Java</A></LI> +<LI><A href="#Windows_perl">Perl</A></LI> +<LI><A href="#Windows_python">Python</A></LI> +<LI><A href="#Windows_tcl">TCL</A></LI> +<LI><A href="#Windows_r">R</A></LI> +<LI><A href="#Windows_ruby">Ruby</A></LI> +</UL> +</LI> +<LI><A href="#Windows_other_compilers">Instructions for using the + Examples with other compilers</A></LI> +</UL> +</LI> +<LI><A href="#Windows_cygwin_mingw">SWIG on Cygwin and MinGW</A> +<UL> +<LI><A href="#Windows_swig_exe">Building swig.exe on Windows</A> +<UL> +<LI><A href="#Windows_mingw_msys">Building swig.exe using MinGW and MSYS</A> +</LI> +<LI><A href="#Windows_cygwin">Building swig.exe using Cygwin</A></LI> +<LI><A href="#Windows_building_alternatives">Building swig.exe + alternatives</A></LI> +</UL> +</LI> +<LI><A href="#Windows_examples_cygwin">Running the examples on Windows + using Cygwin</A></LI> +</UL> +</LI> +<LI><A href="#Windows_interface_file">Microsoft extensions and other + Windows quirks</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes SWIG usage on Microsoft Windows. Installing + SWIG and running the examples is covered as well as building the SWIG + executable. Usage within the Unix like environments MinGW and Cygwin is + also detailed.</P> +<H2><A name="Windows_installation"></A>3.1 Installation on Windows</H2> +<P> SWIG does not come with the usual Windows type installation program, + however it is quite easy to get started. The main steps are:</P> +<UL> +<LI>Download the swigwin zip package from the <A href="http://www.swig.org"> +SWIG website</A> and unzip into a directory. This is all that needs + downloading for the Windows platform.</LI> +<LI>Set environment variables as described in the <A href="#Windows_examples"> +SWIG Windows Examples</A> section in order to run examples using Visual + C++.</LI> +</UL> +<H3><A name="Windows_executable"></A>3.1.1 Windows Executable</H3> +<P> The swigwin distribution contains the SWIG Windows executable, + swig.exe, which will run on 32 bit versions of Windows, ie Windows + 95/98/ME/NT/2000/XP. If you want to build your own swig.exe have a look + at <A href="#Windows_swig_exe">Building swig.exe on Windows</A>.</P> +<H2><A name="Windows_examples"></A>3.2 SWIG Windows Examples</H2> +<P> Using Microsoft Visual C++ is the most common approach to compiling + and linking SWIG's output. The Examples directory has a few Visual C++ + project files (.dsp files). These were produced by Visual C++ 6, + although they should also work in Visual C++ 5. Later versions of + Visual Studio should also be able to open and convert these project + files. The C# examples come with .NET 2003 solution (.sln) and project + files instead of Visual C++ 6 project files. The project files have + been set up to execute SWIG in a custom build rule for the SWIG + interface (.i) file. Alternatively run the <A href="#Windows_examples_cygwin"> +examples using Cygwin</A>.</P> +<P> More information on each of the examples is available with the + examples distributed with SWIG (Examples/index.html).</P> +<H3><A name="Windows_visual_studio"></A>3.2.1 Instructions for using the + Examples with Visual Studio</H3> +<P> Ensure the SWIG executable is as supplied in the SWIG root directory + in order for the examples to work. Most languages require some + environment variables to be set<B> before</B> running Visual C++. Note + that Visual C++ must be re-started to pick up any changes in + environment variables. Open up an example .dsp file, Visual C++ will + create a workspace for you (.dsw file). Ensure the Release build is + selected then do a Rebuild All from the Build menu. The required + environment variables are displayed with their current values.</P> +<P> The list of required environment variables for each module language + is also listed below. They are usually set from the Control Panel and + System properties, but this depends on which flavour of Windows you are + running. If you don't want to use environment variables then change all + occurrences of the environment variables in the .dsp files with hard + coded values. If you are interested in how the project files are set up + there is explanatory information in some of the language module's + documentation.</P> +<H4><A name="Windows_csharp"></A>3.2.1.1 C#</H4> +<P> The C# examples do not require any environment variables to be set + as a C# project file is included. Just open up the .sln solution file + in Visual Studio .NET 2003 or later, select Release Build, and do a + Rebuild All from the Build menu. The accompanying C# and C++ project + files are automatically used by the solution file.</P> +<H4><A name="Windows_java"></A>3.2.1.2 Java</H4> +<P><B> <TT>JAVA_INCLUDE</TT></B> : Set this to the directory containing + jni.h +<BR><B> <TT>JAVA_BIN</TT></B> : Set this to the bin directory containing + javac.exe</P> +<P> Example using JDK1.3: +<BR> <TT>JAVA_INCLUDE: D:\jdk1.3\include +<BR> JAVA_BIN: D:\jdk1.3\bin +<BR></TT></P> +<H4><A name="Windows_perl"></A>3.2.1.3 Perl</H4> +<P><B> <TT>PERL5_INCLUDE</TT></B> : Set this to the directory containing + perl.h +<BR><B> <TT>PERL5_LIB</TT></B> : Set this to the Perl library including + path for linking</P> +<P> Example using nsPerl 5.004_04:</P> +<P> <TT>PERL5_INCLUDE: D:\nsPerl5.004_04\lib\CORE +<BR> PERL5_LIB: D:\nsPerl5.004_04\lib\CORE\perl.lib +<BR></TT></P> +<H4><A name="Windows_python"></A>3.2.1.4 Python</H4> +<P><B> <TT>PYTHON_INCLUDE</TT></B> : Set this to the directory that + contains python.h +<BR><B> <TT>PYTHON_LIB</TT></B> : Set this to the python library + including path for linking</P> +<P> Example using Python 2.1.1: +<BR> <TT>PYTHON_INCLUDE: D:\python21\include +<BR> PYTHON_LIB: D:\python21\libs\python21.lib +<BR></TT></P> +<H4><A name="Windows_tcl"></A>3.2.1.5 TCL</H4> +<P><B> <TT>TCL_INCLUDE</TT></B> : Set this to the directory containing + tcl.h +<BR><B> <TT>TCL_LIB</TT></B> : Set this to the TCL library including + path for linking</P> +<P> Example using ActiveTcl 8.3.3.3 +<BR> <TT>TCL_INCLUDE: D:\tcl\include +<BR> TCL_LIB: D:\tcl\lib\tcl83.lib +<BR></TT></P> +<H4><A name="Windows_r"></A>3.2.1.6 R</H4> +<P><B> <TT>R_INCLUDE</TT></B> : Set this to the directory containing R.h +<BR><B> <TT>R_LIB</TT></B> : Set this to the R library (Rdll.lib) + including path for linking. The library needs to be built as described + in the R README.packages file (the pexports.exe approach is the + easiest).</P> +<P> Example using R 2.5.1: +<BR> <TT>R_INCLUDE: C:\Program Files\R\R-2.5.1\include +<BR> R_LIB: C:\Program Files\R\R-2.5.1\bin\Rdll.lib +<BR></TT></P> +<H4><A name="Windows_ruby"></A>3.2.1.7 Ruby</H4> +<P><B> <TT>RUBY_INCLUDE</TT></B> : Set this to the directory containing + ruby.h +<BR><B> <TT>RUBY_LIB</TT></B> : Set this to the ruby library including + path for linking</P> +<P> Example using Ruby 1.6.4: +<BR> <TT>RUBY_INCLUDE: D:\ruby\lib\ruby\1.6\i586-mswin32 +<BR> RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib +<BR></TT></P> +<H3><A name="Windows_other_compilers"></A>3.2.2 Instructions for using + the Examples with other compilers</H3> +<P> If you do not have access to Visual C++ you will have to set up + project files / Makefiles for your chosen compiler. There is a section + in each of the language modules detailing what needs setting up using + Visual C++ which may be of some guidance. Alternatively you may want to + use Cygwin as described in the following section.</P> +<H2><A name="Windows_cygwin_mingw"></A>3.3 SWIG on Cygwin and MinGW</H2> +<P> SWIG can also be compiled and run using <A href="http://www.cygwin.com"> +Cygwin</A> or <A href="http://www.mingw.org">MinGW</A> which provides a + Unix like front end to Windows and comes free with gcc, an ANSI C/C++ + compiler. However, this is not a recommended approach as the prebuilt + executable is supplied.</P> +<H3><A name="Windows_swig_exe"></A>3.3.1 Building swig.exe on Windows</H3> +<P> If you want to replicate the build of swig.exe that comes with the + download, follow the MinGW instructions below. This is not necessary to + use the supplied swig.exe. This information is provided for those that + want to modify the SWIG source code in a Windows environment. Normally + this is not needed, so most people will want to ignore this section.</P> +<H4><A name="Windows_mingw_msys"></A>3.3.1.1 Building swig.exe using + MinGW and MSYS</H4> +<P> The short abbreviated instructions follow...</P> +<UL> +<LI>Install MinGW and MSYS from the <A href="http://www.mingw.org">MinGW</A> + site. This provides a Unix environment on Windows.</LI> +<LI>Follow the usual Unix instructions in the README file in the SWIG + root directory to build swig.exe from the MinGW command prompt.</LI> +</UL> +<P> The step by step instructions to download and install MinGW and + MSYS, then download and build the latest version of SWIG from SVN + follow... Note that the instructions for obtaining SWIG from SVN are + also online at <A href="http://www.swig.org/svn.html">SWIG SVN</A>.</P> +<P><B> Pitfall note:</B> Execute the steps in the order shown and don't + use spaces in path names. In fact it is best to use the default + installation directories.</P> +<OL> +<LI> Download the following packages from the <A href="http://www.mingw.org/download.shtml"> +MinGW download page</A> or <A href="http://sourceforge.net/projects/mingw/files/"> +MinGW SourceForge download page</A>. Note that at the time of writing, + the majority of these are in the Current release list and some are in + the Snapshot or Previous release list. +<UL> +<LI>MinGW-3.1.0-1.exe</LI> +<LI>MSYS-1.0.11-2004.04.30-1.exe</LI> +<LI>msysDTK-1.0.1.exe</LI> +<LI>bison-2.0-MSYS.tar.gz</LI> +<LI>msys-autoconf-2.59.tar.bz2</LI> +<LI>msys-automake-1.8.2.tar.bz2</LI> +</UL> +</LI> +<LI> Install MinGW-3.1.0-1.exe (C:\MinGW is default location.)</LI> +<LI> Install MSYS-1.0.11-2004.04.30-1.exe. Make sure you install it on + the same windows drive letter as MinGW (C:\msys\1.0 is default). In the + post install script, +<UL> +<LI>Answer y to the "do you wish to continue with the post install?"</LI> +<LI>Answer y to the "do you have MinGW installed?"</LI> +<LI>Type in the the folder in which you installed MinGW (C:/MinGW is + default)</LI> +</UL> +</LI> +<LI> Install msysDTK-1.0.1.exe to the same folder that you installed + MSYS (C:\msys\1.0 is default).</LI> +<LI> Copy the following to the MSYS install folder (C:\msys\1.0 is + default): +<UL> +<LI>msys-automake-1.8.2.tar.bz2</LI> +<LI>msys-autoconf-2.59.tar.bz2</LI> +<LI>bison-2.0-MSYS.tar.gz</LI> +</UL> +</LI> +<LI> Start the MSYS command prompt and execute:<DIV class="shell"> +<PRE> +cd / +tar -jxf msys-automake-1.8.2.tar.bz2 +tar -jxf msys-autoconf-2.59.tar.bz2 +tar -zxf bison-2.0-MSYS.tar.gz +</PRE> +</DIV></LI> +<LI> To get the latest SWIG SVN (version from Subversion source + control), type in the following:<DIV class="shell"> +<PRE> +mkdir /usr/src +cd /usr/src +svn co https://swig.svn.sourceforge.net/svnroot/swig/trunk swig +</PRE> +</DIV><B> Pitfall note:</B> If you want to check out SWIG to a different + folder to the proposed /usr/src/swig, do not use MSYS emulated windows + drive letters, because the autotools will fail miserably on those.</LI> +<LI> You are now ready to build SWIG. Execute the following commands to + build swig.exe:<DIV class="shell"> +<PRE> +cd /usr/src/swig +./autogen.sh +./configure +make +</PRE> +</DIV></LI> +</OL> +<H4><A name="Windows_cygwin"></A>3.3.1.2 Building swig.exe using Cygwin</H4> +<P> Note that SWIG can also be built using Cygwin. However, SWIG will + then require the Cygwin DLL when executing. Follow the Unix + instructions in the README file in the SWIG root directory. Note that + the Cygwin environment will also allow one to regenerate the autotool + generated files which are supplied with the release distribution. These + files are generated using the <TT>autogen.sh</TT> script and will only + need regenerating in circumstances such as changing the build system.</P> +<H4><A name="Windows_building_alternatives"></A>3.3.1.3 Building + swig.exe alternatives</H4> +<P> If you don't want to install Cygwin or MinGW, use a different + compiler to build SWIG. For example, all the source code files can be + added to a Visual C++ project file in order to build swig.exe from the + Visual C++ IDE.</P> +<H3><A name="Windows_examples_cygwin"></A>3.3.2 Running the examples on + Windows using Cygwin</H3> +<P> The examples and test-suite work as successfully on Cygwin as on any + other Unix operating system. The modules which are known to work are + Python, Tcl, Perl, Ruby, Java and C#. Follow the Unix instructions in + the README file in the SWIG root directory to build the examples.</P> +<H2><A name="Windows_interface_file"></A>3.4 Microsoft extensions and + other Windows quirks</H2> +<P> A common problem when using SWIG on Windows are the Microsoft + function calling conventions which are not in the C++ standard. SWIG + parses ISO C/C++ so cannot deal with proprietary conventions such as <TT> +__declspec(dllimport)</TT>, <TT>__stdcall</TT> etc. There is a Windows + interface file, <TT>windows.i</TT>, to deal with these calling + conventions though. The file also contains typemaps for handling + commonly used Windows specific types such as <TT>__int64</TT>, <TT>BOOL</TT> +, <TT>DWORD</TT> etc. Include it like you would any other interface + file, for example:</P> +<DIV class="code"> +<PRE> +%include <windows.i> + +__declspec(dllexport) ULONG __stdcall foo(DWORD, __int32); +</PRE> +</DIV><HR NOSHADE> +<H1><A name="Scripting"></A>4 Scripting Languages</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Scripting_nn2">The two language view of the world</A></LI> +<LI><A href="#Scripting_nn3">How does a scripting language talk to C?</A> +<UL> +<LI><A href="#Scripting_nn4">Wrapper functions</A></LI> +<LI><A href="#Scripting_nn5">Variable linking</A></LI> +<LI><A href="#Scripting_nn6">Constants</A></LI> +<LI><A href="#Scripting_nn7">Structures and classes</A></LI> +<LI><A href="#Scripting_nn8">Proxy classes</A></LI> +</UL> +</LI> +<LI><A href="#Scripting_nn9">Building scripting language extensions</A> +<UL> +<LI><A href="#Scripting_nn10">Shared libraries and dynamic loading</A></LI> +<LI><A href="#Scripting_nn11">Linking with shared libraries</A></LI> +<LI><A href="#Scripting_nn12">Static linking</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter provides a brief overview of scripting language + extension programming and the mechanisms by which scripting language + interpreters access C and C++ code.</P> +<H2><A name="Scripting_nn2"></A>4.1 The two language view of the world</H2> +<P> When a scripting language is used to control a C program, the + resulting system tends to look as follows:</P> +<CENTER><IMG alt="Scripting language input - C/C++ functions output" HEIGHT="149" +src="ch2.1.png" WIDTH="377"></CENTER> +<P> In this programming model, the scripting language interpreter is + used for high level control whereas the underlying functionality of the + C/C++ program is accessed through special scripting language + "commands." If you have ever tried to write your own simple command + interpreter, you might view the scripting language approach to be a + highly advanced implementation of that. Likewise, If you have ever used + a package such as MATLAB or IDL, it is a very similar model--the + interpreter executes user commands and scripts. However, most of the + underlying functionality is written in a low-level language like C or + Fortran.</P> +<P> The two-language model of computing is extremely powerful because it + exploits the strengths of each language. C/C++ can be used for maximal + performance and complicated systems programming tasks. Scripting + languages can be used for rapid prototyping, interactive debugging, + scripting, and access to high-level data structures such associative + arrays.</P> +<H2><A name="Scripting_nn3"></A>4.2 How does a scripting language talk + to C?</H2> +<P> Scripting languages are built around a parser that knows how to + execute commands and scripts. Within this parser, there is a mechanism + for executing commands and accessing variables. Normally, this is used + to implement the builtin features of the language. However, by + extending the interpreter, it is usually possible to add new commands + and variables. To do this, most languages define a special API for + adding new commands. Furthermore, a special foreign function interface + defines how these new commands are supposed to hook into the + interpreter.</P> +<P> Typically, when you add a new command to a scripting interpreter you + need to do two things; first you need to write a special "wrapper" + function that serves as the glue between the interpreter and the + underlying C function. Then you need to give the interpreter + information about the wrapper by providing details about the name of + the function, arguments, and so forth. The next few sections illustrate + the process.</P> +<H3><A name="Scripting_nn4"></A>4.2.1 Wrapper functions</H3> +<P> Suppose you have an ordinary C function like this :</P> +<DIV class="code"> +<PRE> +int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); +} +</PRE> +</DIV> +<P> In order to access this function from a scripting language, it is + necessary to write a special "wrapper" function that serves as the glue + between the scripting language and the underlying C function. A wrapper + function must do three things :</P> +<UL> +<LI>Gather function arguments and make sure they are valid.</LI> +<LI>Call the C function.</LI> +<LI>Convert the return value into a form recognized by the scripting + language.</LI> +</UL> +<P> As an example, the Tcl wrapper function for the <TT>fact()</TT> + function above example might look like the following :</P> +<DIV class="code"> +<PRE> +int wrap_fact(ClientData clientData, Tcl_Interp *interp, + int argc, char *argv[]) { + int result; + int arg0; + if (argc != 2) { + interp->result = "wrong # args"; + return TCL_ERROR; + } + arg0 = atoi(argv[1]); + result = fact(arg0); + sprintf(interp->result,"%d", result); + return TCL_OK; +} + +</PRE> +</DIV> +<P> Once you have created a wrapper function, the final step is to tell + the scripting language about the new function. This is usually done in + an initialization function called by the language when the module is + loaded. For example, adding the above function to the Tcl interpreter + requires code like the following :</P> +<DIV class="code"> +<PRE> +int Wrap_Init(Tcl_Interp *interp) { + Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL, + (Tcl_CmdDeleteProc *) NULL); + return TCL_OK; +} +</PRE> +</DIV> +<P> When executed, Tcl will now have a new command called "<TT>fact</TT> +" that you can use like any other Tcl command.</P> +<P> Although the process of adding a new function to Tcl has been + illustrated, the procedure is almost identical for Perl and Python. + Both require special wrappers to be written and both need additional + initialization code. Only the specific details are different.</P> +<H3><A name="Scripting_nn5"></A>4.2.2 Variable linking</H3> +<P> Variable linking refers to the problem of mapping a C/C++ global + variable to a variable in the scripting language interpreter. For + example, suppose you had the following variable:</P> +<DIV class="code"> +<PRE> +double Foo = 3.5; +</PRE> +</DIV> +<P> It might be nice to access it from a script as follows (shown for + Perl):</P> +<DIV class="targetlang"> +<PRE> +$a = $Foo * 2.3; # Evaluation +$Foo = $a + 2.0; # Assignment +</PRE> +</DIV> +<P> To provide such access, variables are commonly manipulated using a + pair of get/set functions. For example, whenever the value of a + variable is read, a "get" function is invoked. Similarly, whenever the + value of a variable is changed, a "set" function is called.</P> +<P> In many languages, calls to the get/set functions can be attached to + evaluation and assignment operators. Therefore, evaluating a variable + such as <TT>$Foo</TT> might implicitly call the get function. + Similarly, typing <TT>$Foo = 4</TT> would call the underlying set + function to change the value.</P> +<H3><A name="Scripting_nn6"></A>4.2.3 Constants</H3> +<P> In many cases, a C program or library may define a large collection + of constants. For example:</P> +<DIV class="code"> +<PRE> +#define RED 0xff0000 +#define BLUE 0x0000ff +#define GREEN 0x00ff00 +</PRE> +</DIV> +<P> To make constants available, their values can be stored in scripting + language variables such as <TT>$RED</TT>, <TT>$BLUE</TT>, and <TT> +$GREEN</TT>. Virtually all scripting languages provide C functions for + creating variables so installing constants is usually a trivial + exercise.</P> +<H3><A name="Scripting_nn7"></A>4.2.4 Structures and classes</H3> +<P> Although scripting languages have no trouble accessing simple + functions and variables, accessing C/C++ structures and classes present + a different problem. This is because the implementation of structures + is largely related to the problem of data representation and layout. + Furthermore, certain language features are difficult to map to an + interpreter. For instance, what does C++ inheritance mean in a Perl + interface?</P> +<P> The most straightforward technique for handling structures is to + implement a collection of accessor functions that hide the underlying + representation of a structure. For example,</P> +<DIV class="code"> +<PRE> +struct Vector { + Vector(); + ~Vector(); + double x,y,z; +}; + +</PRE> +</DIV> +<P> can be transformed into the following set of functions :</P> +<DIV class="code"> +<PRE> +Vector *new_Vector(); +void delete_Vector(Vector *v); +double Vector_x_get(Vector *v); +double Vector_y_get(Vector *v); +double Vector_z_get(Vector *v); +void Vector_x_set(Vector *v, double x); +void Vector_y_set(Vector *v, double y); +void Vector_z_set(Vector *v, double z); + +</PRE> +</DIV> +<P> Now, from an interpreter these function might be used as follows:</P> +<DIV class="targetlang"> +<PRE> +% set v [new_Vector] +% Vector_x_set $v 3.5 +% Vector_y_get $v +% delete_Vector $v +% ... +</PRE> +</DIV> +<P> Since accessor functions provide a mechanism for accessing the + internals of an object, the interpreter does not need to know anything + about the actual representation of a <TT>Vector</TT>.</P> +<H3><A name="Scripting_nn8"></A>4.2.5 Proxy classes</H3> +<P> In certain cases, it is possible to use the low-level accessor + functions to create a proxy class, also known as a shadow class. A + proxy class is a special kind of object that gets created in a + scripting language to access a C/C++ class (or struct) in a way that + looks like the original structure (that is, it proxies the real C++ + class). For example, if you have the following C definition :</P> +<DIV class="code"> +<PRE> +class Vector { +public: + Vector(); + ~Vector(); + double x,y,z; +}; +</PRE> +</DIV> +<P> A proxy classing mechanism would allow you to access the structure + in a more natural manner from the interpreter. For example, in Python, + you might want to do this:</P> +<DIV class="targetlang"> +<PRE> +>>> v = Vector() +>>> v.x = 3 +>>> v.y = 4 +>>> v.z = -13 +>>> ... +>>> del v +</PRE> +</DIV> +<P> Similarly, in Perl5 you may want the interface to work like this:</P> +<DIV class="targetlang"> +<PRE> +$v = new Vector; +$v->{x} = 3; +$v->{y} = 4; +$v->{z} = -13; + +</PRE> +</DIV> +<P> Finally, in Tcl :</P> +<DIV class="targetlang"> +<PRE> +Vector v +v configure -x 3 -y 4 -z 13 + +</PRE> +</DIV> +<P> When proxy classes are used, two objects are at really work--one in + the scripting language, and an underlying C/C++ object. Operations + affect both objects equally and for all practical purposes, it appears + as if you are simply manipulating a C/C++ object.</P> +<H2><A name="Scripting_nn9"></A>4.3 Building scripting language + extensions</H2> +<P> The final step in using a scripting language with your C/C++ + application is adding your extensions to the scripting language itself. + There are two primary approaches for doing this. The preferred + technique is to build a dynamically loadable extension in the form a + shared library. Alternatively, you can recompile the scripting language + interpreter with your extensions added to it.</P> +<H3><A name="Scripting_nn10"></A>4.3.1 Shared libraries and dynamic + loading</H3> +<P> To create a shared library or DLL, you often need to look at the + manual pages for your compiler and linker. However, the procedure for a + few common machines is shown below:</P> +<DIV class="shell"> +<PRE> +# Build a shared library for Solaris +gcc -c example.c example_wrap.c -I/usr/local/include +ld -G example.o example_wrap.o -o example.so + +# Build a shared library for Linux +gcc -fpic -c example.c example_wrap.c -I/usr/local/include +gcc -shared example.o example_wrap.o -o example.so + +# Build a shared library for Irix +gcc -c example.c example_wrap.c -I/usr/local/include +ld -shared example.o example_wrap.o -o example.so + +</PRE> +</DIV> +<P> To use your shared library, you simply use the corresponding command + in the scripting language (load, import, use, etc...). This will import + your module and allow you to start using it. For example:</P> +<DIV class="targetlang"> +<PRE> +% load ./example.so +% fact 4 +24 +% +</PRE> +</DIV> +<P> When working with C++ codes, the process of building shared + libraries may be more complicated--primarily due to the fact that C++ + modules may need additional code in order to operate correctly. On many + machines, you can build a shared C++ module by following the above + procedures, but changing the link line to the following :</P> +<DIV class="shell"> +<PRE> +c++ -shared example.o example_wrap.o -o example.so +</PRE> +</DIV> +<H3><A name="Scripting_nn11"></A>4.3.2 Linking with shared libraries</H3> +<P> When building extensions as shared libraries, it is not uncommon for + your extension to rely upon other shared libraries on your machine. In + order for the extension to work, it needs to be able to find all of + these libraries at run-time. Otherwise, you may get an error such as + the following :</P> +<DIV class="targetlang"> +<PRE> +>>> import graph +Traceback (innermost last): + File "<stdin>", line 1, in ? + File "/home/sci/data1/beazley/graph/graph.py", line 2, in ? + import graphc +ImportError: 1101:/home/sci/data1/beazley/bin/python: rld: Fatal Error: cannot +successfully map soname 'libgraph.so' under any of the filenames /usr/lib/libgraph.so:/ +lib/libgraph.so:/lib/cmplrs/cc/libgraph.so:/usr/lib/cmplrs/cc/libgraph.so: +>>> +</PRE> +</DIV> +<P> What this error means is that the extension module created by SWIG + depends upon a shared library called "<TT>libgraph.so</TT>" that the + system was unable to locate. To fix this problem, there are a few + approaches you can take.</P> +<UL> +<LI>Link your extension and explicitly tell the linker where the + required libraries are located. Often times, this can be done with a + special linker flag such as <TT>-R</TT>, <TT>-rpath</TT>, etc. This is + not implemented in a standard manner so read the man pages for your + linker to find out more about how to set the search path for shared + libraries.</LI> +<LI>Put shared libraries in the same directory as the executable. This + technique is sometimes required for correct operation on non-Unix + platforms.</LI> +<LI>Set the UNIX environment variable <TT>LD_LIBRARY_PATH</TT> to the + directory where shared libraries are located before running Python. + Although this is an easy solution, it is not recommended. Consider + setting the path using linker options instead.</LI> +</UL> +<H3><A name="Scripting_nn12"></A>4.3.3 Static linking</H3> +<P> With static linking, you rebuild the scripting language interpreter + with extensions. The process usually involves compiling a short main + program that adds your customized commands to the language and starts + the interpreter. You then link your program with a library to produce a + new scripting language executable.</P> +<P> Although static linking is supported on all platforms, this is not + the preferred technique for building scripting language extensions. In + fact, there are very few practical reasons for doing this--consider + using shared libraries instead.</P> +<HR NOSHADE> +<H1><A name="SWIG"></A>5 SWIG Basics</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#SWIG_nn2">Running SWIG</A> +<UL> +<LI><A href="#SWIG_nn3">Input format</A></LI> +<LI><A href="#output">SWIG Output</A></LI> +<LI><A href="#SWIG_nn5">Comments</A></LI> +<LI><A href="#SWIG_nn6">C Preprocessor</A></LI> +<LI><A href="#SWIG_nn7">SWIG Directives</A></LI> +<LI><A href="#SWIG_nn8">Parser Limitations</A></LI> +</UL> +</LI> +<LI><A href="#SWIG_nn9">Wrapping Simple C Declarations</A> +<UL> +<LI><A href="#SWIG_nn10">Basic Type Handling</A></LI> +<LI><A href="#SWIG_nn11">Global Variables</A></LI> +<LI><A href="#SWIG_nn12">Constants</A></LI> +<LI><A href="#SWIG_nn13">A brief word about <TT>const</TT></A></LI> +<LI><A href="#SWIG_nn14">A cautionary tale of <TT>char *</TT></A></LI> +</UL> +</LI> +<LI><A href="#SWIG_nn15">Pointers and complex objects</A> +<UL> +<LI><A href="#SWIG_nn16">Simple pointers</A></LI> +<LI><A href="#SWIG_nn17">Run time pointer type checking</A></LI> +<LI><A href="#SWIG_nn18">Derived types, structs, and classes</A></LI> +<LI><A href="#SWIG_nn19">Undefined datatypes</A></LI> +<LI><A href="#SWIG_nn20">Typedef</A></LI> +</UL> +</LI> +<LI><A href="#SWIG_nn21">Other Practicalities</A> +<UL> +<LI><A href="#SWIG_nn22">Passing structures by value</A></LI> +<LI><A href="#SWIG_nn23">Return by value</A></LI> +<LI><A href="#SWIG_nn24">Linking to structure variables</A></LI> +<LI><A href="#SWIG_nn25">Linking to <TT>char *</TT></A></LI> +<LI><A href="#SWIG_nn26">Arrays</A></LI> +<LI><A href="#SWIG_readonly_variables">Creating read-only variables</A></LI> +<LI><A href="#SWIG_rename_ignore">Renaming and ignoring declarations</A></LI> +<LI><A href="#SWIG_default_args">Default/optional arguments</A></LI> +<LI><A href="#SWIG_nn30">Pointers to functions and callbacks</A></LI> +</UL> +</LI> +<LI><A href="#SWIG_nn31">Structures and unions</A> +<UL> +<LI><A href="#SWIG_nn32">Typedef and structures</A></LI> +<LI><A href="#SWIG_nn33">Character strings and structures</A></LI> +<LI><A href="#SWIG_nn34">Array members</A></LI> +<LI><A href="#SWIG_structure_data_members">Structure data members</A></LI> +<LI><A href="#SWIG_nn36">C constructors and destructors</A></LI> +<LI><A href="#SWIG_adding_member_functions">Adding member functions to C + structures</A></LI> +<LI><A href="#SWIG_nested_structs">Nested structures</A></LI> +<LI><A href="#SWIG_nn39">Other things to note about structure wrapping</A> +</LI> +</UL> +</LI> +<LI><A href="#SWIG_nn40">Code Insertion</A> +<UL> +<LI><A href="#SWIG_nn41">The output of SWIG</A></LI> +<LI><A href="#SWIG_nn42">Code insertion blocks</A></LI> +<LI><A href="#SWIG_nn43">Inlined code blocks</A></LI> +<LI><A href="#SWIG_nn44">Initialization blocks</A></LI> +</UL> +</LI> +<LI><A href="#SWIG_nn45">An Interface Building Strategy</A> +<UL> +<LI><A href="#SWIG_nn46">Preparing a C program for SWIG</A></LI> +<LI><A href="#SWIG_nn47">The SWIG interface file</A></LI> +<LI><A href="#SWIG_nn48">Why use separate interface files?</A></LI> +<LI><A href="#SWIG_nn49">Getting the right header files</A></LI> +<LI><A href="#SWIG_nn50">What to do with main()</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes the basic operation of SWIG, the structure of + its input files, and how it handles standard ANSI C declarations. C++ + support is described in the next chapter. However, C++ programmers + should still read this chapter to understand the basics. Specific + details about each target language are described in later chapters.</P> +<H2><A name="SWIG_nn2"></A>5.1 Running SWIG</H2> +<P> To run SWIG, use the <TT>swig</TT> command with options options and + a filename like this:</P> +<DIV class="shell"> +<PRE> +swig [ <EM>options</EM> ] filename +</PRE> +</DIV> +<P> where <TT>filename</TT> is a SWIG interface file or a C/C++ header + file. Below is a subset of<EM> options</EM> that can be used. + Additional options are also defined for each target language. A full + list can be obtained by typing <TT>swig -help</TT> or <TT>swig -<EM> +lang</EM> -help</TT>.</P> +<DIV class="shell"> +<PRE> +-allegrocl Generate ALLEGROCL wrappers +-chicken Generate CHICKEN wrappers +-clisp Generate CLISP wrappers +-cffi Generate CFFI wrappers +-csharp Generate C# wrappers +-guile Generate Guile wrappers +-java Generate Java wrappers +-lua Generate Lua wrappers +-modula3 Generate Modula 3 wrappers +-mzscheme Generate Mzscheme wrappers +-ocaml Generate Ocaml wrappers +-perl Generate Perl wrappers +-php Generate PHP wrappers +-pike Generate Pike wrappers +-python Generate Python wrappers +-r Generate R (aka GNU S) wrappers +-ruby Generate Ruby wrappers +-sexp Generate Lisp S-Expressions wrappers +-tcl Generate Tcl wrappers +-uffi Generate Common Lisp / UFFI wrappers +-xml Generate XML wrappers + +-c++ Enable C++ parsing +-D<EM>symbol</EM> Define a preprocessor symbol +-Fstandard Display error/warning messages in commonly used format +-Fmicrosoft Display error/warning messages in Microsoft format +-help Display all options +-I<EM>dir</EM> Add a directory to the file include path +-l<EM>file</EM> Include a SWIG library file. +-module <EM>name</EM> Set the name of the SWIG module +-o <EM>outfile</EM> Name of output file +-outcurrentdir Set default output dir to current dir instead of input file's path +-outdir <EM>dir</EM> Set language specific files output directory +-swiglib Show location of SWIG library +-version Show SWIG version number + +</PRE> +</DIV> +<H3><A name="SWIG_nn3"></A>5.1.1 Input format</H3> +<P> As input, SWIG expects a file containing ANSI C/C++ declarations and + special SWIG directives. More often than not, this is a special SWIG + interface file which is usually denoted with a special <TT>.i</TT> or <TT> +.swg</TT> suffix. In certain cases, SWIG can be used directly on raw + header files or source files. However, this is not the most typical + case and there are several reasons why you might not want to do this + (described later).</P> +<P> The most common format of a SWIG interface is as follows:</P> +<DIV class="code"> +<PRE> +%module mymodule +%{ +#include "myheader.h" +%} +// Now list ANSI C/C++ declarations +int foo; +int bar(int x); +... +</PRE> +</DIV> +<P> The module name is supplied using the special <TT>%module</TT> + directive. Modules are described further in the <A href="#Modules_introduction"> +Modules Introduction</A> section.</P> +<P> Everything in the <TT>%{ ... %}</TT> block is simply copied verbatim + to the resulting wrapper file created by SWIG. This section is almost + always used to include header files and other declarations that are + required to make the generated wrapper code compile. It is important to + emphasize that just because you include a declaration in a SWIG input + file, that declaration does<EM> not</EM> automatically appear in the + generated wrapper code---therefore you need to make sure you include + the proper header files in the <TT>%{ ... %}</TT> section. It should be + noted that the text enclosed in <TT>%{ ... %}</TT> is not parsed or + interpreted by SWIG. The <TT>%{...%}</TT> syntax and semantics in SWIG + is analogous to that of the declarations section used in input files to + parser generation tools such as yacc or bison.</P> +<H3><A name="output"></A>5.1.2 SWIG Output</H3> +<P> The output of SWIG is a C/C++ file that contains all of the wrapper + code needed to build an extension module. SWIG may generate some + additional files depending on the target language. By default, an input + file with the name <TT>file.i</TT> is transformed into a file <TT> +file_wrap.c</TT> or <TT>file_wrap.cxx</TT> (depending on whether or not + the <TT>-c++</TT> option has been used). The name of the output file + can be changed using the <TT>-o</TT> option. In certain cases, file + suffixes are used by the compiler to determine the source language (C, + C++, etc.). Therefore, you have to use the <TT>-o</TT> option to change + the suffix of the SWIG-generated wrapper file if you want something + different than the default. For example:</P> +<DIV class="shell"> +<PRE> +$ swig -c++ -python -o example_wrap.cpp example.i +</PRE> +</DIV> +<P> The C/C++ output file created by SWIG often contains everything that + is needed to construct a extension module for the target scripting + language. SWIG is not a stub compiler nor is it usually necessary to + edit the output file (and if you look at the output, you probably won't + want to). To build the final extension module, the SWIG output file is + compiled and linked with the rest of your C/C++ program to create a + shared library.</P> +<P> Many target languages will also generate proxy class files in the + target language. The default output directory for these language + specific files is the same directory as the generated C/C++ file. This + can be modified using the <TT>-outdir</TT> option. For example:</P> +<DIV class="shell"> +<PRE> +$ swig -c++ -python -outdir pyfiles -o cppfiles/example_wrap.cpp example.i +</PRE> +</DIV> +<P> If the directories <TT>cppfiles</TT> and <TT>pyfiles</TT> exist, the + following will be generated:</P> +<DIV class="shell"> +<PRE> +cppfiles/example_wrap.cpp +pyfiles/example.py +</PRE> +</DIV> +<P> If the <TT>-outcurrentdir</TT> option is used (without <TT>-o</TT>) + then SWIG behaves like a typical C/C++ compiler and the default output + directory is then the current directory. Without this option the + default output directory is the path to the input file. If <TT>-o</TT> + and <TT>-outcurrentdir</TT> are used together, <TT>-outcurrentdir</TT> + is effectively ignored as the output directory for the language files + is the same directory as the generated C/C++ file if not overidden with + <TT>-outdir</TT>.</P> +<H3><A name="SWIG_nn5"></A>5.1.3 Comments</H3> +<P> C and C++ style comments may appear anywhere in interface files. In + previous versions of SWIG, comments were used to generate documentation + files. However, this feature is currently under repair and will + reappear in a later SWIG release.</P> +<H3><A name="SWIG_nn6"></A>5.1.4 C Preprocessor</H3> +<P> Like C, SWIG preprocesses all input files through an enhanced + version of the C preprocessor. All standard preprocessor features are + supported including file inclusion, conditional compilation and macros. + However, <TT>#include</TT> statements are ignored unless the <TT> +-includeall</TT> command line option has been supplied. The reason for + disabling includes is that SWIG is sometimes used to process raw C + header files. In this case, you usually only want the extension module + to include functions in the supplied header file rather than everything + that might be included by that header file (i.e., system headers, C + library functions, etc.).</P> +<P> It should also be noted that the SWIG preprocessor skips all text + enclosed inside a <TT>%{...%}</TT> block. In addition, the preprocessor + includes a number of macro handling enhancements that make it more + powerful than the normal C preprocessor. These extensions are described + in the "<A href="#Preprocessor">Preprocessor</A>" chapter.</P> +<H3><A name="SWIG_nn7"></A>5.1.5 SWIG Directives</H3> +<P> Most of SWIG's operation is controlled by special directives that + are always preceded by a "<TT>%</TT>" to distinguish them from normal C + declarations. These directives are used to give SWIG hints or to alter + SWIG's parsing behavior in some manner.</P> +<P> Since SWIG directives are not legal C syntax, it is generally not + possible to include them in header files. However, SWIG directives can + be included in C header files using conditional compilation like this:</P> +<DIV class="code"> +<PRE> +/* header.h --- Some header file */ + +/* SWIG directives -- only seen if SWIG is running */ +#ifdef SWIG +%module foo +#endif +</PRE> +</DIV> +<P> <TT>SWIG</TT> is a special preprocessing symbol defined by SWIG when + it is parsing an input file.</P> +<H3><A name="SWIG_nn8"></A>5.1.6 Parser Limitations</H3> +<P> Although SWIG can parse most C/C++ declarations, it does not provide + a complete C/C++ parser implementation. Most of these limitations + pertain to very complicated type declarations and certain advanced C++ + features. Specifically, the following features are not currently + supported:</P> +<UL> +<LI>Non-conventional type declarations. For example, SWIG does not + support declarations such as the following (even though this is legal + C):<DIV class="code"> +<PRE> +/* Non-conventional placement of storage specifier (extern) */ +const int extern Number; + +/* Extra declarator grouping */ +Matrix (foo); // A global variable + +/* Extra declarator grouping in parameters */ +void bar(Spam (Grok)(Doh)); + +</PRE> +</DIV> +<P> In practice, few (if any) C programmers actually write code like + this since this style is never featured in programming books. However, + if you're feeling particularly obfuscated, you can certainly break SWIG + (although why would you want to?).</P> +</LI> +<LI>Running SWIG on C++ source files (what would appear in a .C or .cxx + file) is not recommended. Even though SWIG can parse C++ class + declarations, it ignores declarations that are decoupled from their + original class definition (the declarations are parsed, but a lot of + warning messages may be generated). For example:<DIV class="code"> +<PRE> +/* Not supported by SWIG */ +int foo::bar(int) { + ... whatever ... +} +</PRE> +</DIV></LI> +<LI>Certain advanced features of C++ such as nested classes are not yet + supported. Please see the section on using SWIG with C++ for more + information.</LI> +</UL> +<P> In the event of a parsing error, conditional compilation can be used + to skip offending code. For example:</P> +<DIV class="code"> +<PRE> +#ifndef SWIG +... some bad declarations ... +#endif +</PRE> +</DIV> +<P> Alternatively, you can just delete the offending code from the + interface file.</P> +<P> One of the reasons why SWIG does not provide a full C++ parser + implementation is that it has been designed to work with incomplete + specifications and to be very permissive in its handling of C/C++ + datatypes (e.g., SWIG can generate interfaces even when there are + missing class declarations or opaque datatypes). Unfortunately, this + approach makes it extremely difficult to implement certain parts of a + C/C++ parser as most compilers use type information to assist in the + parsing of more complex declarations (for the truly curious, the + primary complication in the implementation is that the SWIG parser does + not utilize a separate<EM> typedef-name</EM> terminal symbol as + described on p. 234 of K&R).</P> +<H2><A name="SWIG_nn9"></A>5.2 Wrapping Simple C Declarations</H2> +<P> SWIG wraps simple C declarations by creating an interface that + closely matches the way in which the declarations would be used in a C + program. For example, consider the following interface file:</P> +<DIV class="code"> +<PRE> +%module example + +%inline %{ +extern double sin(double x); +extern int strcmp(const char *, const char *); +extern int Foo; +%} +#define STATUS 50 +#define VERSION "1.1" +</PRE> +</DIV> +<P> In this file, there are two functions <TT>sin()</TT> and <TT> +strcmp()</TT>, a global variable <TT>Foo</TT>, and two constants <TT> +STATUS</TT> and <TT>VERSION</TT>. When SWIG creates an extension module, + these declarations are accessible as scripting language functions, + variables, and constants respectively. For example, in Tcl:</P> +<DIV class="targetlang"> +<PRE> +% sin 3 +5.2335956 +% strcmp Dave Mike +-1 +% puts $Foo +42 +% puts $STATUS +50 +% puts $VERSION +1.1 +</PRE> +</DIV> +<P> Or in Python:</P> +<DIV class="targetlang"> +<PRE> +>>> example.sin(3) +5.2335956 +>>> example.strcmp('Dave','Mike') +-1 +>>> print example.cvar.Foo +42 +>>> print example.STATUS +50 +>>> print example.VERSION +1.1 +</PRE> +</DIV> +<P> Whenever possible, SWIG creates an interface that closely matches + the underlying C/C++ code. However, due to subtle differences between + languages, run-time environments, and semantics, it is not always + possible to do so. The next few sections describes various aspects of + this mapping.</P> +<H3><A name="SWIG_nn10"></A>5.2.1 Basic Type Handling</H3> +<P> In order to build an interface, SWIG has to convert C/C++ datatypes + to equivalent types in the target language. Generally, scripting + languages provide a more limited set of primitive types than C. + Therefore, this conversion process involves a certain amount of type + coercion.</P> +<P> Most scripting languages provide a single integer type that is + implemented using the <TT>int</TT> or <TT>long</TT> datatype in C. The + following list shows all of the C datatypes that SWIG will convert to + and from integers in the target language:</P> +<DIV class="code"> +<PRE> +int +short +long +unsigned +signed +unsigned short +unsigned long +unsigned char +signed char +bool +</PRE> +</DIV> +<P> When an integral value is converted from C, a cast is used to + convert it to the representation in the target language. Thus, a 16 bit + short in C may be promoted to a 32 bit integer. When integers are + converted in the other direction, the value is cast back into the + original C type. If the value is too large to fit, it is silently + truncated. +<!-- Dave: Maybe we should fix this --> +</P> +<P> <TT>unsigned char</TT> and <TT>signed char</TT> are special cases + that are handled as small 8-bit integers. Normally, the <TT>char</TT> + datatype is mapped as a one-character ASCII string.</P> +<P> The <TT>bool</TT> datatype is cast to and from an integer value of 0 + and 1 unless the target language provides a special boolean type.</P> +<P> Some care is required when working with large integer values. Most + scripting languages use 32-bit integers so mapping a 64-bit long + integer may lead to truncation errors. Similar problems may arise with + 32 bit unsigned integers (which may appear as large negative numbers). + As a rule of thumb, the <TT>int</TT> datatype and all variations of <TT> +char</TT> and <TT>short</TT> datatypes are safe to use. For <TT>unsigned + int</TT> and <TT>long</TT> datatypes, you will need to carefully check + the correct operation of your program after it has been wrapped with + SWIG.</P> +<P> Although the SWIG parser supports the <TT>long long</TT> datatype, + not all language modules support it. This is because <TT>long long</TT> + usually exceeds the integer precision available in the target language. + In certain modules such as Tcl and Perl5, <TT>long long</TT> integers + are encoded as strings. This allows the full range of these numbers to + be represented. However, it does not allow <TT>long long</TT> values to + be used in arithmetic expressions. It should also be noted that + although <TT>long long</TT> is part of the ISO C99 standard, it is not + universally supported by all C compilers. Make sure you are using a + compiler that supports <TT>long long</TT> before trying to use this + type with SWIG.</P> +<P> SWIG recognizes the following floating point types :</P> +<DIV class="code"> +<PRE> +float +double +</PRE> +</DIV> +<P> Floating point numbers are mapped to and from the natural + representation of floats in the target language. This is almost always + a C <TT>double</TT>. The rarely used datatype of <TT>long double</TT> + is not supported by SWIG.</P> +<P> The <TT>char</TT> datatype is mapped into a NULL terminated ASCII + string with a single character. When used in a scripting language it + shows up as a tiny string containing the character value. When + converting the value back into C, SWIG takes a character string from + the scripting language and strips off the first character as the char + value. Thus if the value "foo" is assigned to a <TT>char</TT> datatype, + it gets the value `f'.</P> +<P> The <TT>char *</TT> datatype is handled as a NULL-terminated ASCII + string. SWIG maps this into a 8-bit character string in the target + scripting language. SWIG converts character strings in the target + language to NULL terminated strings before passing them into C/C++. The + default handling of these strings does not allow them to have embedded + NULL bytes. Therefore, the <TT>char *</TT> datatype is not generally + suitable for passing binary data. However, it is possible to change + this behavior by defining a SWIG typemap. See the chapter on <A href="#Typemaps"> +Typemaps</A> for details about this.</P> +<P> At this time, SWIG provides limited support for Unicode and + wide-character strings (the C <TT>wchar_t</TT> type). Some languages + provide typemaps for wchar_t, but bear in mind these might not be + portable across different operating systems. This is a delicate topic + that is poorly understood by many programmers and not implemented in a + consistent manner across languages. For those scripting languages that + provide Unicode support, Unicode strings are often available in an + 8-bit representation such as UTF-8 that can be mapped to the <TT>char *</TT> + type (in which case the SWIG interface will probably work). If the + program you are wrapping uses Unicode, there is no guarantee that + Unicode characters in the target language will use the same internal + representation (e.g., UCS-2 vs. UCS-4). You may need to write some + special conversion functions.</P> +<H3><A name="SWIG_nn11"></A>5.2.2 Global Variables</H3> +<P> Whenever possible, SWIG maps C/C++ global variables into scripting + language variables. For example,</P> +<DIV class="code"> +<PRE> +%module example +double foo; + +</PRE> +</DIV> +<P> results in a scripting language variable like this:</P> +<DIV class="code"> +<PRE> +# Tcl +set foo [3.5] ;# Set foo to 3.5 +puts $foo ;# Print the value of foo + +# Python +cvar.foo = 3.5 # Set foo to 3.5 +print cvar.foo # Print value of foo + +# Perl +$foo = 3.5; # Set foo to 3.5 +print $foo,"\n"; # Print value of foo + +# Ruby +Module.foo = 3.5 # Set foo to 3.5 +print Module.foo, "\n" # Print value of foo +</PRE> +</DIV> +<P> Whenever the scripting language variable is used, the underlying C + global variable is accessed. Although SWIG makes every attempt to make + global variables work like scripting language variables, it is not + always possible to do so. For instance, in Python, all global variables + must be accessed through a special variable object known as <TT>cvar</TT> + (shown above). In Ruby, variables are accessed as attributes of the + module. Other languages may convert variables to a pair of accessor + functions. For example, the Java module generates a pair of functions <TT> +double get_foo()</TT> and <TT>set_foo(double val)</TT> that are used to + manipulate the value.</P> +<P> Finally, if a global variable has been declared as <TT>const</TT>, + it only supports read-only access. Note: this behavior is new to + SWIG-1.3. Earlier versions of SWIG incorrectly handled <TT>const</TT> + and created constants instead.</P> +<H3><A name="SWIG_nn12"></A>5.2.3 Constants</H3> +<P> Constants can be created using <TT>#define</TT>, enumerations, or a + special <TT>%constant</TT> directive. The following interface file + shows a few valid constant declarations :</P> +<DIV class="code"> +<PRE> +#define I_CONST 5 // An integer constant +#define PI 3.14159 // A Floating point constant +#define S_CONST "hello world" // A string constant +#define NEWLINE '\n' // Character constant + +enum boolean {NO=0, YES=1}; +enum months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, + SEP, OCT, NOV, DEC}; +%constant double BLAH = 42.37; +#define PI_4 PI/4 +#define FLAGS 0x04 | 0x08 | 0x40 + +</PRE> +</DIV> +<P> In <TT>#define</TT> declarations, the type of a constant is inferred + by syntax. For example, a number with a decimal point is assumed to be + floating point. In addition, SWIG must be able to fully resolve all of + the symbols used in a <TT>#define</TT> in order for a constant to + actually be created. This restriction is necessary because <TT>#define</TT> + is also used to define preprocessor macros that are definitely not + meant to be part of the scripting language interface. For example:</P> +<DIV class="code"> +<PRE> +#define EXTERN extern + +EXTERN void foo(); +</PRE> +</DIV> +<P> In this case, you probably don't want to create a constant called <TT> +EXTERN</TT> (what would the value be?). In general, SWIG will not create + constants for macros unless the value can be completely determined by + the preprocessor. For instance, in the above example, the declaration</P> +<DIV class="code"> +<PRE> +#define PI_4 PI/4 +</PRE> +</DIV> +<P> defines a constant because <TT>PI</TT> was already defined as a + constant and the value is known. However, for the same conservative + reasons even a constant with a simple cast will be ignored, such as</P> +<DIV class="code"> +<PRE> +#define F_CONST (double) 5 // A floating pointer constant with cast +</PRE> +</DIV> +<P> The use of constant expressions is allowed, but SWIG does not + evaluate them. Rather, it passes them through to the output file and + lets the C compiler perform the final evaluation (SWIG does perform a + limited form of type-checking however).</P> +<P> For enumerations, it is critical that the original enum definition + be included somewhere in the interface file (either in a header file or + in the <TT>%{,%}</TT> block). SWIG only translates the enumeration into + code needed to add the constants to a scripting language. It needs the + original enumeration declaration in order to get the correct enum + values as assigned by the C compiler.</P> +<P> The <TT>%constant</TT> directive is used to more precisely create + constants corresponding to different C datatypes. Although it is not + usually not needed for simple values, it is more useful when working + with pointers and other more complex datatypes. Typically, <TT> +%constant</TT> is only used when you want to add constants to the + scripting language interface that are not defined in the original + header file.</P> +<H3><A name="SWIG_nn13"></A>5.2.4 A brief word about <TT>const</TT></H3> +<P> A common confusion with C programming is the semantic meaning of the + <TT>const</TT> qualifier in declarations--especially when it is mixed + with pointers and other type modifiers. In fact, previous versions of + SWIG handled <TT>const</TT> incorrectly--a situation that SWIG-1.3.7 + and newer releases have fixed.</P> +<P> Starting with SWIG-1.3, all variable declarations, regardless of any + use of <TT>const</TT>, are wrapped as global variables. If a + declaration happens to be declared as <TT>const</TT>, it is wrapped as + a read-only variable. To tell if a variable is <TT>const</TT> or not, + you need to look at the right-most occurrence of the <TT>const</TT> + qualifier (that appears before the variable name). If the right-most <TT> +const</TT> occurs after all other type modifiers (such as pointers), + then the variable is <TT>const</TT>. Otherwise, it is not.</P> +<P> Here are some examples of <TT>const</TT> declarations.</P> +<DIV class="code"> +<PRE> +const char a; // A constant character +char const b; // A constant character (the same) +char *const c; // A constant pointer to a character +const char *const d; // A constant pointer to a constant character +</PRE> +</DIV> +<P> Here is an example of a declaration that is not <TT>const</TT>:</P> +<DIV class="code"> +<PRE> +const char *e; // A pointer to a constant character. The pointer + // may be modified. +</PRE> +</DIV> +<P> In this case, the pointer <TT>e</TT> can change---it's only the + value being pointed to that is read-only.</P> +<P><B> Compatibility Note:</B> One reason for changing SWIG to handle <TT> +const</TT> declarations as read-only variables is that there are many + situations where the value of a <TT>const</TT> variable might change. + For example, a library might export a symbol as <TT>const</TT> in its + public API to discourage modification, but still allow the value to + change through some other kind of internal mechanism. Furthermore, + programmers often overlook the fact that with a constant declaration + like <TT>char *const</TT>, the underlying data being pointed to can be + modified--it's only the pointer itself that is constant. In an embedded + system, a <TT>const</TT> declaration might refer to a read-only memory + address such as the location of a memory-mapped I/O device port (where + the value changes, but writing to the port is not supported by the + hardware). Rather than trying to build a bunch of special cases into + the <TT>const</TT> qualifier, the new interpretation of <TT>const</TT> + as "read-only" is simple and exactly matches the actual semantics of <TT> +const</TT> in C/C++. If you really want to create a constant as in older + versions of SWIG, use the <TT>%constant</TT> directive instead. For + example:</P> +<DIV class="code"> +<PRE> +%constant double PI = 3.14159; +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +#ifdef SWIG +#define const %constant +#endif +const double foo = 3.4; +const double bar = 23.4; +const int spam = 42; +#ifdef SWIG +#undef const +#endif +... + +</PRE> +</DIV> +<H3><A name="SWIG_nn14"></A>5.2.5 A cautionary tale of <TT>char *</TT></H3> +<P> Before going any further, there is one bit of caution involving <TT> +char *</TT> that must now be mentioned. When strings are passed from a + scripting language to a C <TT>char *</TT>, the pointer usually points + to string data stored inside the interpreter. It is almost always a + really bad idea to modify this data. Furthermore, some languages may + explicitly disallow it. For instance, in Python, strings are supposed + be immutable. If you violate this, you will probably receive a vast + amount of wrath when you unleash your module on the world.</P> +<P> The primary source of problems are functions that might modify + string data in place. A classic example would be a function like this:</P> +<DIV class="code"> +<PRE> +char *strcat(char *s, const char *t) +</PRE> +</DIV> +<P> Although SWIG will certainly generate a wrapper for this, its + behavior will be undefined. In fact, it will probably cause your + application to crash with a segmentation fault or other memory related + problem. This is because <TT>s</TT> refers to some internal data in the + target language---data that you shouldn't be touching.</P> +<P> The bottom line: don't rely on <TT>char *</TT> for anything other + than read-only input values. However, it must be noted that you could + change the behavior of SWIG using <A href="#Typemaps">typemaps</A>.</P> +<H2><A name="SWIG_nn15"></A>5.3 Pointers and complex objects</H2> +<P> Most C programs manipulate arrays, structures, and other types of + objects. This section discusses the handling of these datatypes.</P> +<H3><A name="SWIG_nn16"></A>5.3.1 Simple pointers</H3> +<P> Pointers to primitive C datatypes such as</P> +<DIV class="code"> +<PRE> +int * +double *** +char ** +</PRE> +</DIV> +<P> are fully supported by SWIG. Rather than trying to convert the data + being pointed to into a scripting representation, SWIG simply encodes + the pointer itself into a representation that contains the actual value + of the pointer and a type-tag. Thus, the SWIG representation of the + above pointers (in Tcl), might look like this:</P> +<DIV class="targetlang"> +<PRE> +_10081012_p_int +_1008e124_ppp_double +_f8ac_pp_char +</PRE> +</DIV> +<P> A NULL pointer is represented by the string "NULL" or the value 0 + encoded with type information.</P> +<P> All pointers are treated as opaque objects by SWIG. Thus, a pointer + may be returned by a function and passed around to other C functions as + needed. For all practical purposes, the scripting language interface + works in exactly the same way as you would use the pointer in a C + program. The only difference is that there is no mechanism for + dereferencing the pointer since this would require the target language + to understand the memory layout of the underlying object.</P> +<P> The scripting language representation of a pointer value should + never be manipulated directly. Even though the values shown look like + hexadecimal addresses, the numbers used may differ from the actual + machine address (e.g., on little-endian machines, the digits may appear + in reverse order). Furthermore, SWIG does not normally map pointers + into high-level objects such as associative arrays or lists (for + example, converting an <TT>int *</TT> into an list of integers). There + are several reasons why SWIG does not do this:</P> +<UL> +<LI>There is not enough information in a C declaration to properly map + pointers into higher level constructs. For example, an <TT>int *</TT> + may indeed be an array of integers, but if it contains ten million + elements, converting it into a list object is probably a bad idea.</LI> +<LI>The underlying semantics associated with a pointer is not known by + SWIG. For instance, an <TT>int *</TT> might not be an array at + all--perhaps it is an output value!</LI> +<LI>By handling all pointers in a consistent manner, the implementation + of SWIG is greatly simplified and less prone to error.</LI> +</UL> +<H3><A name="SWIG_nn17"></A>5.3.2 Run time pointer type checking</H3> +<P> By allowing pointers to be manipulated from a scripting language, + extension modules effectively bypass compile-time type checking in the + C/C++ compiler. To prevent errors, a type signature is encoded into all + pointer values and is used to perform run-time type checking. This + type-checking process is an integral part of SWIG and can not be + disabled or modified without using typemaps (described in later + chapters).</P> +<P> Like C, <TT>void *</TT> matches any kind of pointer. Furthermore, <TT> +NULL</TT> pointers can be passed to any function that expects to receive + a pointer. Although this has the potential to cause a crash, <TT>NULL</TT> + pointers are also sometimes used as sentinel values or to denote a + missing/empty value. Therefore, SWIG leaves NULL pointer checking up to + the application.</P> +<H3><A name="SWIG_nn18"></A>5.3.3 Derived types, structs, and classes</H3> +<P> For everything else (structs, classes, arrays, etc...) SWIG applies + a very simple rule :</P> +<CENTER><B> Everything else is a pointer</B></CENTER> +<P> In other words, SWIG manipulates everything else by reference. This + model makes sense because most C/C++ programs make heavy use of + pointers and SWIG can use the type-checked pointer mechanism already + present for handling pointers to basic datatypes.</P> +<P> Although this probably sounds complicated, it's really quite simple. + Suppose you have an interface file like this :</P> +<DIV class="code"> +<PRE> +%module fileio +FILE *fopen(char *, char *); +int fclose(FILE *); +unsigned fread(void *ptr, unsigned size, unsigned nobj, FILE *); +unsigned fwrite(void *ptr, unsigned size, unsigned nobj, FILE *); +void *malloc(int nbytes); +void free(void *); + +</PRE> +</DIV> +<P> In this file, SWIG doesn't know what a <TT>FILE</TT> is, but since + it's used as a pointer, so it doesn't really matter what it is. If you + wrapped this module into Python, you can use the functions just like + you expect :</P> +<DIV class="targetlang"> +<PRE> +# Copy a file +def filecopy(source,target): + f1 = fopen(source,"r") + f2 = fopen(target,"w") + buffer = malloc(8192) + nbytes = fread(buffer,8192,1,f1) + while (nbytes > 0): + fwrite(buffer,8192,1,f2) + nbytes = fread(buffer,8192,1,f1) + free(buffer) + +</PRE> +</DIV> +<P> In this case <TT>f1</TT>, <TT>f2</TT>, and <TT>buffer</TT> are all + opaque objects containing C pointers. It doesn't matter what value they + contain--our program works just fine without this knowledge.</P> +<H3><A name="SWIG_nn19"></A>5.3.4 Undefined datatypes</H3> +<P> When SWIG encounters an undeclared datatype, it automatically + assumes that it is a structure or class. For example, suppose the + following function appeared in a SWIG input file:</P> +<DIV class="code"> +<PRE> +void matrix_multiply(Matrix *a, Matrix *b, Matrix *c); +</PRE> +</DIV> +<P> SWIG has no idea what a "<TT>Matrix</TT>" is. However, it is + obviously a pointer to something so SWIG generates a wrapper using its + generic pointer handling code.</P> +<P> Unlike C or C++, SWIG does not actually care whether <TT>Matrix</TT> + has been previously defined in the interface file or not. This allows + SWIG to generate interfaces from only partial or limited information. + In some cases, you may not care what a <TT>Matrix</TT> really is as + long as you can pass an opaque reference to one around in the scripting + language interface.</P> +<P> An important detail to mention is that SWIG will gladly generate + wrappers for an interface when there are unspecified type names. + However,<B> all unspecified types are internally handled as pointers to + structures or classes!</B> For example, consider the following + declaration:</P> +<DIV class="code"> +<PRE> +void foo(size_t num); +</PRE> +</DIV> +<P> If <TT>size_t</TT> is undeclared, SWIG generates wrappers that + expect to receive a type of <TT>size_t *</TT> (this mapping is + described shortly). As a result, the scripting interface might behave + strangely. For example:</P> +<DIV class="code"> +<PRE> +foo(40); +TypeError: expected a _p_size_t. +</PRE> +</DIV> +<P> The only way to fix this problem is to make sure you properly + declare type names using <TT>typedef</TT>.</P> + +<!-- We might want to add an error reporting flag to swig --> +<H3><A name="SWIG_nn20"></A>5.3.5 Typedef</H3> +<P> Like C, <TT>typedef</TT> can be used to define new type names in + SWIG. For example:</P> +<DIV class="code"> +<PRE> +typedef unsigned int size_t; +</PRE> +</DIV> +<P> <TT>typedef</TT> definitions appearing in a SWIG interface are not + propagated to the generated wrapper code. Therefore, they either need + to be defined in an included header file or placed in the declarations + section like this:</P> +<DIV class="code"> +<PRE> +%{ +/* Include in the generated wrapper file */ +typedef unsigned int size_t; +%} +/* Tell SWIG about it */ +typedef unsigned int size_t; +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +%inline %{ +typedef unsigned int size_t; +%} +</PRE> +</DIV> +<P> In certain cases, you might be able to include other header files to + collect type information. For example:</P> +<DIV class="code"> +<PRE> +%module example +%import "sys/types.h" +</PRE> +</DIV> +<P> In this case, you might run SWIG as follows:</P> +<DIV class="shell"> +<PRE> +$ swig -I/usr/include -includeall example.i +</PRE> +</DIV> +<P> It should be noted that your mileage will vary greatly here. System + headers are notoriously complicated and may rely upon a variety of + non-standard C coding extensions (e.g., such as special directives to + GCC). Unless you exactly specify the right include directories and + preprocessor symbols, this may not work correctly (you will have to + experiment).</P> +<P> SWIG tracks <TT>typedef</TT> declarations and uses this information + for run-time type checking. For instance, if you use the above <TT> +typedef</TT> and had the following function declaration:</P> +<DIV class="code"> +<PRE> +void foo(unsigned int *ptr); +</PRE> +</DIV> +<P> The corresponding wrapper function will accept arguments of type <TT> +unsigned int *</TT> or <TT>size_t *</TT>.</P> +<H2><A name="SWIG_nn21"></A>5.4 Other Practicalities</H2> +<P> So far, this chapter has presented almost everything you need to + know to use SWIG for simple interfaces. However, some C programs use + idioms that are somewhat more difficult to map to a scripting language + interface. This section describes some of these issues.</P> +<H3><A name="SWIG_nn22"></A>5.4.1 Passing structures by value</H3> +<P> Sometimes a C function takes structure parameters that are passed by + value. For example, consider the following function:</P> +<DIV class="code"> +<PRE> +double dot_product(Vector a, Vector b); +</PRE> +</DIV> +<P> To deal with this, SWIG transforms the function to use pointers by + creating a wrapper equivalent to the following:</P> +<DIV class="code"> +<PRE> +double wrap_dot_product(Vector *a, Vector *b) { + Vector x = *a; + Vector y = *b; + return dot_product(x,y); +} +</PRE> +</DIV> +<P> In the target language, the <TT>dot_product()</TT> function now + accepts pointers to Vectors instead of Vectors. For the most part, this + transformation is transparent so you might not notice.</P> +<H3><A name="SWIG_nn23"></A>5.4.2 Return by value</H3> +<P> C functions that return structures or classes datatypes by value are + more difficult to handle. Consider the following function:</P> +<DIV class="code"> +<PRE> +Vector cross_product(Vector v1, Vector v2); +</PRE> +</DIV> +<P> This function wants to return <TT>Vector</TT>, but SWIG only really + supports pointers. As a result, SWIG creates a wrapper like this:</P> +<DIV class="code"> +<PRE> +Vector *wrap_cross_product(Vector *v1, Vector *v2) { + Vector x = *v1; + Vector y = *v2; + Vector *result; + result = (Vector *) malloc(sizeof(Vector)); + *(result) = cross(x,y); + return result; +} +</PRE> +</DIV> +<P> or if SWIG was run with the <TT>-c++</TT> option:</P> +<DIV class="code"> +<PRE> +Vector *wrap_cross(Vector *v1, Vector *v2) { + Vector x = *v1; + Vector y = *v2; + Vector *result = new Vector(cross(x,y)); // Uses default copy constructor + return result; +} +</PRE> +</DIV> +<P> In both cases, SWIG allocates a new object and returns a reference + to it. It is up to the user to delete the returned object when it is no + longer in use. Clearly, this will leak memory if you are unaware of the + implicit memory allocation and don't take steps to free the result. + That said, it should be noted that some language modules can now + automatically track newly created objects and reclaim memory for you. + Consult the documentation for each language module for more details.</P> +<P> It should also be noted that the handling of pass/return by value in + C++ has some special cases. For example, the above code fragments don't + work correctly if <TT>Vector</TT> doesn't define a default constructor. + The section on SWIG and C++ has more information about this case.</P> +<H3><A name="SWIG_nn24"></A>5.4.3 Linking to structure variables</H3> +<P> When global variables or class members involving structures are + encountered, SWIG handles them as pointers. For example, a global + variable like this</P> +<DIV class="code"> +<PRE> +Vector unit_i; +</PRE> +</DIV> +<P> gets mapped to an underlying pair of set/get functions like this :</P> +<DIV class="code"> +<PRE> +Vector *unit_i_get() { + return &unit_i; +} +void unit_i_set(Vector *value) { + unit_i = *value; +} +</PRE> +</DIV> +<P> Again some caution is in order. A global variable created in this + manner will show up as a pointer in the target scripting language. It + would be an extremely bad idea to free or destroy such a pointer. Also, + C++ classes must supply a properly defined copy constructor in order + for assignment to work correctly.</P> +<H3><A name="SWIG_nn25"></A>5.4.4 Linking to <TT>char *</TT></H3> +<P> When a global variable of type <TT>char *</TT> appears, SWIG uses <TT> +malloc()</TT> or <TT>new</TT> to allocate memory for the new value. + Specifically, if you have a variable like this</P> +<DIV class="code"> +<PRE> +char *foo; +</PRE> +</DIV> +<P> SWIG generates the following code:</P> +<DIV class="code"> +<PRE> +/* C mode */ +void foo_set(char *value) { + if (foo) free(foo); + foo = (char *) malloc(strlen(value)+1); + strcpy(foo,value); +} + +/* C++ mode. When -c++ option is used */ +void foo_set(char *value) { + if (foo) delete [] foo; + foo = new char[strlen(value)+1]; + strcpy(foo,value); +} +</PRE> +</DIV> +<P> If this is not the behavior that you want, consider making the + variable read-only using the <TT>%immutable</TT> directive. + Alternatively, you might write a short assist-function to set the value + exactly like you want. For example:</P> +<DIV class="code"> +<PRE> +%inline %{ + void set_foo(char *value) { + strncpy(foo,value, 50); + } +%} +</PRE> +</DIV> +<P> Note: If you write an assist function like this, you will have to + call it as a function from the target scripting language (it does not + work like a variable). For example, in Python you will have to write:</P> +<DIV class="targetlang"> +<PRE> +>>> set_foo("Hello World") +</PRE> +</DIV> +<P> A common mistake with <TT>char *</TT> variables is to link to a + variable declared like this:</P> +<DIV class="code"> +<PRE> +char *VERSION = "1.0"; +</PRE> +</DIV> +<P> In this case, the variable will be readable, but any attempt to + change the value results in a segmentation or general protection fault. + This is due to the fact that SWIG is trying to release the old value + using <TT>free</TT> or <TT>delete</TT> when the string literal value + currently assigned to the variable wasn't allocated using <TT>malloc()</TT> + or <TT>new</TT>. To fix this behavior, you can either mark the variable + as read-only, write a typemap (as described in Chapter 6), or write a + special set function as shown. Another alternative is to declare the + variable as an array:</P> +<DIV class="code"> +<PRE> +char VERSION[64] = "1.0"; +</PRE> +</DIV> +<P> When variables of type <TT>const char *</TT> are declared, SWIG + still generates functions for setting and getting the value. However, + the default behavior does<EM> not</EM> release the previous contents + (resulting in a possible memory leak). In fact, you may get a warning + message such as this when wrapping such a variable:</P> +<DIV class="shell"> +<PRE> +example.i:20. Typemap warning. Setting const char * variable may leak memory +</PRE> +</DIV> +<P> The reason for this behavior is that <TT>const char *</TT> variables + are often used to point to string literals. For example:</P> +<DIV class="code"> +<PRE> +const char *foo = "Hello World\n"; +</PRE> +</DIV> +<P> Therefore, it's a really bad idea to call <TT>free()</TT> on such a + pointer. On the other hand, it<EM> is</EM> legal to change the pointer + to point to some other value. When setting a variable of this type, + SWIG allocates a new string (using malloc or new) and changes the + pointer to point to the new value. However, repeated modifications of + the value will result in a memory leak since the old value is not + released.</P> +<H3><A name="SWIG_nn26"></A>5.4.5 Arrays</H3> +<P> Arrays are fully supported by SWIG, but they are always handled as + pointers instead of mapping them to a special array object or list in + the target language. Thus, the following declarations :</P> +<DIV class="code"> +<PRE> +int foobar(int a[40]); +void grok(char *argv[]); +void transpose(double a[20][20]); +</PRE> +</DIV> +<P> are processed as if they were really declared like this:</P> +<DIV class="code"> +<PRE> +int foobar(int *a); +void grok(char **argv); +void transpose(double (*a)[20]); +</PRE> +</DIV> +<P> Like C, SWIG does not perform array bounds checking. It is up to the + user to make sure the pointer points a suitably allocated region of + memory.</P> +<P> Multi-dimensional arrays are transformed into a pointer to an array + of one less dimension. For example:</P> +<DIV class="code"> +<PRE> +int [10]; // Maps to int * +int [10][20]; // Maps to int (*)[20] +int [10][20][30]; // Maps to int (*)[20][30] +</PRE> +</DIV> +<P> It is important to note that in the C type system, a + multidimensional array <TT>a[][]</TT> is<B> NOT</B> equivalent to a + single pointer <TT>*a</TT> or a double pointer such as <TT>**a</TT>. + Instead, a pointer to an array is used (as shown above) where the + actual value of the pointer is the starting memory location of the + array. The reader is strongly advised to dust off their C book and + re-read the section on arrays before using them with SWIG.</P> +<P> Array variables are supported, but are read-only by default. For + example:</P> +<DIV class="code"> +<PRE> +int a[100][200]; +</PRE> +</DIV> +<P> In this case, reading the variable 'a' returns a pointer of type <TT> +int (*)[200]</TT> that points to the first element of the array <TT> +&a[0][0]</TT>. Trying to modify 'a' results in an error. This is because + SWIG does not know how to copy data from the target language into the + array. To work around this limitation, you may want to write a few + simple assist functions like this:</P> +<DIV class="code"> +<PRE> +%inline %{ +void a_set(int i, int j, int val) { + a[i][j] = val; +} +int a_get(int i, int j) { + return a[i][j]; +} +%} +</PRE> +</DIV> +<P> To dynamically create arrays of various sizes and shapes, it may be + useful to write some helper functions in your interface. For example:</P> +<DIV class="code"> +<PRE> +// Some array helpers +%inline %{ + /* Create any sort of [size] array */ + int *int_array(int size) { + return (int *) malloc(size*sizeof(int)); + } + /* Create a two-dimension array [size][10] */ + int (*int_array_10(int size))[10] { + return (int (*)[10]) malloc(size*10*sizeof(int)); + } +%} +</PRE> +</DIV> +<P> Arrays of <TT>char</TT> are handled as a special case by SWIG. In + this case, strings in the target language can be stored in the array. + For example, if you have a declaration like this,</P> +<DIV class="code"> +<PRE> +char pathname[256]; +</PRE> +</DIV> +<P> SWIG generates functions for both getting and setting the value that + are equivalent to the following code:</P> +<DIV class="code"> +<PRE> +char *pathname_get() { + return pathname; +} +void pathname_set(char *value) { + strncpy(pathname,value,256); +} +</PRE> +</DIV> +<P> In the target language, the value can be set like a normal variable.</P> +<H3><A name="SWIG_readonly_variables"></A>5.4.6 Creating read-only + variables</H3> +<P> A read-only variable can be created by using the <TT>%immutable</TT> + directive as shown :</P> +<DIV class="code"> +<PRE> +// File : interface.i + +int a; // Can read/write +%immutable; +int b,c,d // Read only variables +%mutable; +double x,y // read/write +</PRE> +</DIV> +<P> The <TT>%immutable</TT> directive enables read-only mode until it is + explicitly disabled using the <TT>%mutable</TT> directive. As an + alternative to turning read-only mode off and on like this, individual + declarations can also be tagged as immutable. For example:</P> +<DIV class="code"> +<PRE> +%immutable x; // Make x read-only +... +double x; // Read-only (from earlier %immutable directive) +double y; // Read-write +... +</PRE> +</DIV> +<P> The <TT>%mutable</TT> and <TT>%immutable</TT> directives are + actually <A href="#features">%feature directives</A> defined like this:</P> +<DIV class="code"> +<PRE> +#define %immutable %feature("immutable") +#define %mutable %feature("immutable","") +</PRE> +</DIV> +<P> If you wanted to make all wrapped variables read-only, barring one + or two, it might be easier to take this approach:</P> +<DIV class="code"> +<PRE> +%immutable; // Make all variables read-only +%feature("immutable","0") x; // except, make x read/write +... +double x; +double y; +double z; +... +</PRE> +</DIV> +<P> Read-only variables are also created when declarations are declared + as <TT>const</TT>. For example:</P> +<DIV class="code"> +<PRE> +const int foo; /* Read only variable */ +char * const version="1.0"; /* Read only variable */ +</PRE> +</DIV> +<P><B> Compatibility note:</B> Read-only access used to be controlled by + a pair of directives <TT>%readonly</TT> and <TT>%readwrite</TT>. + Although these directives still work, they generate a warning message. + Simply change the directives to <TT>%immutable;</TT> and <TT>%mutable;</TT> + to silence the warning. Don't forget the extra semicolon!</P> +<H3><A name="SWIG_rename_ignore"></A>5.4.7 Renaming and ignoring + declarations</H3> +<P> Normally, the name of a C declaration is used when that declaration + is wrapped into the target language. However, this may generate a + conflict with a keyword or already existing function in the scripting + language. To resolve a name conflict, you can use the <TT>%rename</TT> + directive as shown :</P> +<DIV class="code"> +<PRE> +// interface.i + +%rename(my_print) print; +extern void print(char *); + +%rename(foo) a_really_long_and_annoying_name; +extern int a_really_long_and_annoying_name; + +</PRE> +</DIV> +<P> SWIG still calls the correct C function, but in this case the + function <TT>print()</TT> will really be called "<TT>my_print()</TT>" + in the target language.</P> +<P> The placement of the <TT>%rename</TT> directive is arbitrary as long + as it appears before the declarations to be renamed. A common technique + is to write code for wrapping a header file like this:</P> +<DIV class="code"> +<PRE> +// interface.i + +%rename(my_print) print; +%rename(foo) a_really_long_and_annoying_name; + +%include "header.h" +</PRE> +</DIV> +<P> <TT>%rename</TT> applies a renaming operation to all future + occurrences of a name. The renaming applies to functions, variables, + class and structure names, member functions, and member data. For + example, if you had two-dozen C++ classes, all with a member function + named `print' (which is a keyword in Python), you could rename them all + to `output' by specifying :</P> +<DIV class="code"> +<PRE> +%rename(output) print; // Rename all `print' functions to `output' +</PRE> +</DIV> +<P> SWIG does not normally perform any checks to see if the functions it + wraps are already defined in the target scripting language. However, if + you are careful about namespaces and your use of modules, you can + usually avoid these problems.</P> +<P> Closely related to <TT>%rename</TT> is the <TT>%ignore</TT> + directive. <TT>%ignore</TT> instructs SWIG to ignore declarations that + match a given identifier. For example:</P> +<DIV class="code"> +<PRE> +%ignore print; // Ignore all declarations named print +%ignore _HAVE_FOO_H; // Ignore an include guard constant +... +%include "foo.h" // Grab a header file +... +</PRE> +</DIV> +<P> Any function, variable etc which matches <TT>%ignore</TT> will not + be wrapped and therefore will not be available from the target + language. A common usage of <TT>%ignore</TT> is to selectively remove + certain declarations from a header file without having to add + conditional compilation to the header. However, it should be stressed + that this only works for simple declarations. If you need to remove a + whole section of problematic code, the SWIG preprocessor should be used + instead.</P> +<P> More powerful variants of <TT>%rename</TT> and <TT>%ignore</TT> + directives can be used to help wrap C++ overloaded functions and + methods or C++ methods which use default arguments. This is described + in the <A href="#ambiguity_resolution_renaming">Ambiguity resolution + and renaming</A> section in the C++ chapter.</P> +<P><B> Compatibility note:</B> Older versions of SWIG provided a special + <TT>%name</TT> directive for renaming declarations. For example:</P> +<DIV class="code"> +<PRE> +%name(output) extern void print(char *); +</PRE> +</DIV> +<P> This directive is still supported, but it is deprecated and should + probably be avoided. The <TT>%rename</TT> directive is more powerful + and better supports wrapping of raw header file information.</P> +<H3><A name="SWIG_default_args"></A>5.4.8 Default/optional arguments</H3> +<P> SWIG supports default arguments in both C and C++ code. For example:</P> +<DIV class="code"> +<PRE> +int plot(double x, double y, int color=WHITE); +</PRE> +</DIV> +<P> In this case, SWIG generates wrapper code where the default + arguments are optional in the target language. For example, this + function could be used in Tcl as follows :</P> +<DIV class="targetlang"> +<PRE> +% plot -3.4 7.5 # Use default value +% plot -3.4 7.5 10 # set color to 10 instead + +</PRE> +</DIV> +<P> Although the ANSI C standard does not allow default arguments, + default arguments specified in a SWIG interface work with both C and + C++.</P> +<P><B> Note:</B> There is a subtle semantic issue concerning the use of + default arguments and the SWIG generated wrapper code. When default + arguments are used in C code, the default values are emitted into the + wrappers and the function is invoked with a full set of arguments. This + is different to when wrapping C++ where an overloaded wrapper method is + generated for each defaulted argument. Please refer to the section on <A +href="#SWIGPlus_default_args">default arguments</A> in the C++ chapter + for further details.</P> +<H3><A name="SWIG_nn30"></A>5.4.9 Pointers to functions and callbacks</H3> +<P> Occasionally, a C library may include functions that expect to + receive pointers to functions--possibly to serve as callbacks. SWIG + provides full support for function pointers provided that the callback + functions are defined in C and not in the target language. For example, + consider a function like this:</P> +<DIV class="code"> +<PRE> +int binary_op(int a, int b, int (*op)(int,int)); +</PRE> +</DIV> +<P> When you first wrap something like this into an extension module, + you may find the function to be impossible to use. For instance, in + Python:</P> +<DIV class="targetlang"> +<PRE> +>>> def add(x,y): +... return x+y +... +>>> binary_op(3,4,add) +Traceback (most recent call last): + File "<stdin>", line 1, in ? +TypeError: Type error. Expected _p_f_int_int__int +>>> +</PRE> +</DIV> +<P> The reason for this error is that SWIG doesn't know how to map a + scripting language function into a C callback. However, existing C + functions can be used as arguments provided you install them as + constants. One way to do this is to use the <TT>%constant</TT> + directive like this:</P> +<DIV class="code"> +<PRE> +/* Function with a callback */ +int binary_op(int a, int b, int (*op)(int,int)); + +/* Some callback functions */ +%constant int add(int,int); +%constant int sub(int,int); +%constant int mul(int,int); +</PRE> +</DIV> +<P> In this case, <TT>add</TT>, <TT>sub</TT>, and <TT>mul</TT> become + function pointer constants in the target scripting language. This + allows you to use them as follows:</P> +<DIV class="targetlang"> +<PRE> +>>> binary_op(3,4,add) +7 +>>> binary_op(3,4,mul) +12 +>>> +</PRE> +</DIV> +<P> Unfortunately, by declaring the callback functions as constants, + they are no longer accessible as functions. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> add(3,4) +Traceback (most recent call last): + File "<stdin>", line 1, in ? +TypeError: object is not callable: '_ff020efc_p_f_int_int__int' +>>> +</PRE> +</DIV> +<P> If you want to make a function available as both a callback function + and a function, you can use the <TT>%callback</TT> and <TT>%nocallback</TT> + directives like this:</P> +<DIV class="code"> +<PRE> +/* Function with a callback */ +int binary_op(int a, int b, int (*op)(int,int)); + +/* Some callback functions */ +%callback("%s_cb"); +int add(int,int); +int sub(int,int); +int mul(int,int); +%nocallback; +</PRE> +</DIV> +<P> The argument to <TT>%callback</TT> is a printf-style format string + that specifies the naming convention for the callback constants (<TT>%s</TT> + gets replaced by the function name). The callback mode remains in + effect until it is explicitly disabled using <TT>%nocallback</TT>. When + you do this, the interface now works as follows:</P> +<DIV class="targetlang"> +<PRE> +>>> binary_op(3,4,add_cb) +7 +>>> binary_op(3,4,mul_cb) +12 +>>> add(3,4) +7 +>>> mul(3,4) +12 +</PRE> +</DIV> +<P> Notice that when the function is used as a callback, special names + such as <TT>add_cb</TT> is used instead. To call the function normally, + just use the original function name such as <TT>add()</TT>.</P> +<P> SWIG provides a number of extensions to standard C printf formatting + that may be useful in this context. For instance, the following + variation installs the callbacks as all upper-case constants such as <TT> +ADD</TT>, <TT>SUB</TT>, and <TT>MUL</TT>:</P> +<DIV class="code"> +<PRE> +/* Some callback functions */ +%callback("%(upper)s"); +int add(int,int); +int sub(int,int); +int mul(int,int); +%nocallback; +</PRE> +</DIV> +<P> A format string of <TT>"%(lower)s"</TT> converts all characters to + lower-case. A string of <TT>"%(title)s"</TT> capitalizes the first + character and converts the rest to lower case.</P> +<P> And now, a final note about function pointer support. Although SWIG + does not normally allow callback functions to be written in the target + language, this can be accomplished with the use of typemaps and other + advanced SWIG features. This is described in a later chapter.</P> +<H2><A name="SWIG_nn31"></A>5.5 Structures and unions</H2> +<P> This section describes the behavior of SWIG when processing ANSI C + structures and union declarations. Extensions to handle C++ are + described in the next section.</P> +<P> If SWIG encounters the definition of a structure or union, it + creates a set of accessor functions. Although SWIG does not need + structure definitions to build an interface, providing definitions make + it possible to access structure members. The accessor functions + generated by SWIG simply take a pointer to an object and allow access + to an individual member. For example, the declaration :</P> +<DIV class="code"> +<PRE> +struct Vector { + double x,y,z; +} + +</PRE> +</DIV> +<P> gets transformed into the following set of accessor functions :</P> +<DIV class="code"> +<PRE> +double Vector_x_get(struct Vector *obj) { + return obj->x; +} +double Vector_y_get(struct Vector *obj) { + return obj->y; +} +double Vector_z_get(struct Vector *obj) { + return obj->z; +} +void Vector_x_set(struct Vector *obj, double value) { + obj->x = value; +} +void Vector_y_set(struct Vector *obj, double value) { + obj->y = value; +} +void Vector_z_set(struct Vector *obj, double value) { + obj->z = value; +} +</PRE> +</DIV> +<P> In addition, SWIG creates default constructor and destructor + functions if none are defined in the interface. For example:</P> +<DIV class="code"> +<PRE> +struct Vector *new_Vector() { + return (Vector *) calloc(1,sizeof(struct Vector)); +} +void delete_Vector(struct Vector *obj) { + free(obj); +} +</PRE> +</DIV> +<P> Using these low-level accessor functions, an object can be minimally + manipulated from the target language using code like this:</P> +<DIV class="code"> +<PRE> +v = new_Vector() +Vector_x_set(v,2) +Vector_y_set(v,10) +Vector_z_set(v,-5) +... +delete_Vector(v) +</PRE> +</DIV> +<P> However, most of SWIG's language modules also provide a high-level + interface that is more convenient. Keep reading.</P> +<H3><A name="SWIG_nn32"></A>5.5.1 Typedef and structures</H3> +<P> SWIG supports the following construct which is quite common in C + programs :</P> +<DIV class="code"> +<PRE> +typedef struct { + double x,y,z; +} Vector; + +</PRE> +</DIV> +<P> When encountered, SWIG assumes that the name of the object is + `Vector' and creates accessor functions like before. The only + difference is that the use of <TT>typedef</TT> allows SWIG to drop the <TT> +struct</TT> keyword on its generated code. For example:</P> +<DIV class="code"> +<PRE> +double Vector_x_get(Vector *obj) { + return obj->x; +} +</PRE> +</DIV> +<P> If two different names are used like this :</P> +<DIV class="code"> +<PRE> +typedef struct vector_struct { + double x,y,z; +} Vector; + +</PRE> +</DIV> +<P> the name <TT>Vector</TT> is used instead of <TT>vector_struct</TT> + since this is more typical C programming style. If declarations defined + later in the interface use the type <TT>struct vector_struct</TT>, SWIG + knows that this is the same as <TT>Vector</TT> and it generates the + appropriate type-checking code.</P> +<H3><A name="SWIG_nn33"></A>5.5.2 Character strings and structures</H3> +<P> Structures involving character strings require some care. SWIG + assumes that all members of type <TT>char *</TT> have been dynamically + allocated using <TT>malloc()</TT> and that they are NULL-terminated + ASCII strings. When such a member is modified, the previously contents + will be released, and the new contents allocated. For example :</P> +<DIV class="code"> +<PRE> +%module mymodule +... +struct Foo { + char *name; + ... +} + +</PRE> +</DIV> +<P> This results in the following accessor functions :</P> +<DIV class="code"> +<PRE> +char *Foo_name_get(Foo *obj) { + return Foo->name; +} + +char *Foo_name_set(Foo *obj, char *c) { + if (obj->name) free(obj->name); + obj->name = (char *) malloc(strlen(c)+1); + strcpy(obj->name,c); + return obj->name; +} +</PRE> +</DIV> +<P> If this behavior differs from what you need in your applications, + the SWIG "memberin" typemap can be used to change it. See the typemaps + chapter for further details.</P> +<P> Note: If the <TT>-c++</TT> option is used, <TT>new</TT> and <TT> +delete</TT> are used to perform memory allocation.</P> +<H3><A name="SWIG_nn34"></A>5.5.3 Array members</H3> +<P> Arrays may appear as the members of structures, but they will be + read-only. SWIG will write an accessor function that returns the + pointer to the first element of the array, but will not write a + function to change the contents of the array itself. When this + situation is detected, SWIG may generate a warning message such as the + following :</P> +<DIV class="shell"> +<PRE> +interface.i:116. Warning. Array member will be read-only +</PRE> +</DIV> +<P> To eliminate the warning message, typemaps can be used, but this is + discussed in a later chapter. In many cases, the warning message is + harmless.</P> +<H3><A name="SWIG_structure_data_members"></A>5.5.4 Structure data + members</H3> +<P> Occasionally, a structure will contain data members that are + themselves structures. For example:</P> +<DIV class="code"> +<PRE> +typedef struct Foo { + int x; +} Foo; + +typedef struct Bar { + int y; + Foo f; /* struct member */ +} Bar; +</PRE> +</DIV> +<P> When a structure member is wrapped, it is handled as a pointer, + unless the <TT>%naturalvar</TT> directive is used where it is handled + more like a C++ reference (see <A href="#SWIGPlus_member_data">C++ + Member data</A>). The accessors to the member variable as a pointer is + effectively wrapped as follows:</P> +<DIV class="code"> +<PRE> +Foo *Bar_f_get(Bar *b) { + return &b->f; +} +void Bar_f_set(Bar *b, Foo *value) { + b->f = *value; +} +</PRE> +</DIV> +<P> The reasons for this are somewhat subtle but have to do with the + problem of modifying and accessing data inside the data member. For + example, suppose you wanted to modify the value of <TT>f.x</TT> of a <TT> +Bar</TT> object like this:</P> +<DIV class="code"> +<PRE> +Bar *b; +b->f.x = 37; +</PRE> +</DIV> +<P> Translating this assignment to function calls (as would be used + inside the scripting language interface) results in the following code:</P> +<DIV class="code"> +<PRE> +Bar *b; +Foo_x_set(Bar_f_get(b),37); +</PRE> +</DIV> +<P> In this code, if the <TT>Bar_f_get()</TT> function were to return a <TT> +Foo</TT> instead of a <TT>Foo *</TT>, then the resulting modification + would be applied to a<EM> copy</EM> of <TT>f</TT> and not the data + member <TT>f</TT> itself. Clearly that's not what you want!</P> +<P> It should be noted that this transformation to pointers only occurs + if SWIG knows that a data member is a structure or class. For instance, + if you had a structure like this,</P> +<DIV class="code"> +<PRE> +struct Foo { + WORD w; +}; +</PRE> +</DIV> +<P> and nothing was known about <TT>WORD</TT>, then SWIG will generate + more normal accessor functions like this:</P> +<DIV class="code"> +<PRE> +WORD Foo_w_get(Foo *f) { + return f->w; +} +void Foo_w_set(FOO *f, WORD value) { + f->w = value; +} +</PRE> +</DIV> +<P><B> Compatibility Note:</B> SWIG-1.3.11 and earlier releases + transformed all non-primitive member datatypes to pointers. Starting in + SWIG-1.3.12, this transformation<EM> only</EM> occurs if a datatype is + known to be a structure, class, or union. This is unlikely to break + existing code. However, if you need to tell SWIG that an undeclared + datatype is really a struct, simply use a forward struct declaration + such as <TT>"struct Foo;"</TT>.</P> +<H3><A name="SWIG_nn36"></A>5.5.5 C constructors and destructors</H3> +<P> When wrapping structures, it is generally useful to have a mechanism + for creating and destroying objects. If you don't do anything, SWIG + will automatically generate functions for creating and destroying + objects using <TT>malloc()</TT> and <TT>free()</TT>. Note: the use of <TT> +malloc()</TT> only applies when SWIG is used on C code (i.e., when the <TT> +-c++</TT> option is<EM> not</EM> supplied on the command line). C++ is + handled differently.</P> +<P> If you don't want SWIG to generate default constructors for your + interfaces, you can use the <TT>%nodefaultctor</TT> directive or the <TT> +-nodefaultctor</TT> command line option. For example:</P> +<DIV class="shell"> +<PRE> +swig -nodefaultctor example.i +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +%module foo +... +%nodefaultctor; // Don't create default constructors +... declarations ... +%clearnodefaultctor; // Re-enable default constructors +</PRE> +</DIV> +<P> If you need more precise control, <TT>%nodefaultctor</TT> can + selectively target individual structure definitions. For example:</P> +<DIV class="code"> +<PRE> +%nodefaultctor Foo; // No default constructor for Foo +... +struct Foo { // No default constructor generated. +}; + +struct Bar { // Default constructor generated. +}; +</PRE> +</DIV> +<P> Since ignoring the implicit or default destructors most of the times + produce memory leaks, SWIG will always try to generate them. If needed, + however, you can selectively disable the generation of the + default/implicit destructor by using <TT>%nodefaultdtor</TT></P> +<DIV class="code"> +<PRE> +%nodefaultdtor Foo; // No default/implicit destructor for Foo +... +struct Foo { // No default destructor is generated. +}; + +struct Bar { // Default destructor generated. +}; +</PRE> +</DIV> +<P><B> Compatibility note:</B> Prior to SWIG-1.3.7, SWIG did not + generate default constructors or destructors unless you explicitly + turned them on using <TT>-make_default</TT>. However, it appears that + most users want to have constructor and destructor functions so it has + now been enabled as the default behavior.</P> +<P><B> Note:</B> There are also the <TT>-nodefault</TT> option and <TT> +%nodefault</TT> directive, which disable both the default or implicit + destructor generation. This could lead to memory leaks across the + target languages, and is highly recommended you don't use them.</P> +<H3><A name="SWIG_adding_member_functions"></A>5.5.6 Adding member + functions to C structures</H3> +<P> Most languages provide a mechanism for creating classes and + supporting object oriented programming. From a C standpoint, object + oriented programming really just boils down to the process of attaching + functions to structures. These functions normally operate on an + instance of the structure (or object). Although there is a natural + mapping of C++ to such a scheme, there is no direct mechanism for + utilizing it with C code. However, SWIG provides a special <TT>%extend</TT> + directive that makes it possible to attach methods to C structures for + purposes of building an object oriented interface. Suppose you have a C + header file with the following declaration :</P> +<DIV class="code"> +<PRE> +/* file : vector.h */ +... +typedef struct { + double x,y,z; +} Vector; + +</PRE> +</DIV> +<P> You can make a <TT>Vector</TT> look a lot like a class by writing a + SWIG interface like this:</P> +<DIV class="code"> +<PRE> +// file : vector.i +%module mymodule +%{ +#include "vector.h" +%} + +%include "vector.h" // Just grab original C header file +%extend Vector { // Attach these functions to struct Vector + Vector(double x, double y, double z) { + Vector *v; + v = (Vector *) malloc(sizeof(Vector)); + v->x = x; + v->y = y; + v->z = z; + return v; + } + ~Vector() { + free($self); + } + double magnitude() { + return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z); + } + void print() { + printf("Vector [%g, %g, %g]\n", $self->x,$self->y,$self->z); + } +}; + +</PRE> +</DIV> +<P> Note the usage of the <TT>$self</TT> special variable. Its usage is + identical to a C++ 'this' pointer and should be used whenever access to + the struct instance is required. Also note that C++ constructor and + destructor syntax has been used to simulate a constructor and + destructor, even for C code. There is one subtle difference to a normal + C++ constructor implementation though and that is although the + constructor declaration is as per a normal C++ constructor, the newly + constructed object must be returned<B> as if</B> the constructor + declaration had a return value, a <TT>Vector *</TT> in this case.</P> +<P> Now, when used with proxy classes in Python, you can do things like + this :</P> +<DIV class="targetlang"> +<PRE> +>>> v = Vector(3,4,0) # Create a new vector +>>> print v.magnitude() # Print magnitude +5.0 +>>> v.print() # Print it out +[ 3, 4, 0 ] +>>> del v # Destroy it +</PRE> +</DIV> +<P> The <TT>%extend</TT> directive can also be used inside the + definition of the Vector structure. For example:</P> +<DIV class="code"> +<PRE> +// file : vector.i +%module mymodule +%{ +#include "vector.h" +%} + +typedef struct { + double x,y,z; + %extend { + Vector(double x, double y, double z) { ... } + ~Vector() { ... } + ... + } +} Vector; +</PRE> +</DIV> +<P> Finally, <TT>%extend</TT> can be used to access externally written + functions provided they follow the naming convention used in this + example :</P> +<DIV class="code"> +<PRE> +/* File : vector.c */ +/* Vector methods */ +#include "vector.h" +Vector *new_Vector(double x, double y, double z) { + Vector *v; + v = (Vector *) malloc(sizeof(Vector)); + v->x = x; + v->y = y; + v->z = z; + return v; +} +void delete_Vector(Vector *v) { + free(v); +} + +double Vector_magnitude(Vector *v) { + return sqrt(v->x*v->x+v->y*v->y+v->z*v->z); +} + +// File : vector.i +// Interface file +%module mymodule +%{ +#include "vector.h" +%} + +typedef struct { + double x,y,z; + %extend { + Vector(int,int,int); // This calls new_Vector() + ~Vector(); // This calls delete_Vector() + double magnitude(); // This will call Vector_magnitude() + ... + } +} Vector; +</PRE> +</DIV> +<P> A little known feature of the <TT>%extend</TT> directive is that it + can also be used to add synthesized attributes or to modify the + behavior of existing data attributes. For example, suppose you wanted + to make <TT>magnitude</TT> a read-only attribute of <TT>Vector</TT> + instead of a method. To do this, you might write some code like this:</P> +<DIV class="code"> +<PRE> +// Add a new attribute to Vector +%extend Vector { + const double magnitude; +} +// Now supply the implementation of the Vector_magnitude_get function +%{ +const double Vector_magnitude_get(Vector *v) { + return (const double) return sqrt(v->x*v->x+v->y*v->y+v->z*v->z); +} +%} + +</PRE> +</DIV> +<P> Now, for all practical purposes, <TT>magnitude</TT> will appear like + an attribute of the object.</P> +<P> A similar technique can also be used to work with problematic data + members. For example, consider this interface:</P> +<DIV class="code"> +<PRE> +struct Person { + char name[50]; + ... +} +</PRE> +</DIV> +<P> By default, the <TT>name</TT> attribute is read-only because SWIG + does not normally know how to modify arrays. However, you can rewrite + the interface as follows to change this:</P> +<DIV class="code"> +<PRE> +struct Person { + %extend { + char *name; + } +... +} + +// Specific implementation of set/get functions +%{ +char *Person_name_get(Person *p) { + return p->name; +} +void Person_name_set(Person *p, char *val) { + strncpy(p->name,val,50); +} +%} +</PRE> +</DIV> +<P> Finally, it should be stressed that even though <TT>%extend</TT> can + be used to add new data members, these new members can not require the + allocation of additional storage in the object (e.g., their values must + be entirely synthesized from existing attributes of the structure).</P> +<P><B> Compatibility note:</B> The <TT>%extend</TT> directive is a new + name for the <TT>%addmethods</TT> directive. Since <TT>%addmethods</TT> + could be used to extend a structure with more than just methods, a more + suitable directive name has been chosen.</P> +<H3><A name="SWIG_nested_structs"></A>5.5.7 Nested structures</H3> +<P> Occasionally, a C program will involve structures like this :</P> +<DIV class="code"> +<PRE> +typedef struct Object { + int objtype; + union { + int ivalue; + double dvalue; + char *strvalue; + void *ptrvalue; + } intRep; +} Object; + +</PRE> +</DIV> +<P> When SWIG encounters this, it performs a structure splitting + operation that transforms the declaration into the equivalent of the + following:</P> +<DIV class="code"> +<PRE> +typedef union { + int ivalue; + double dvalue; + char *strvalue; + void *ptrvalue; +} Object_intRep; + +typedef struct Object { + int objType; + Object_intRep intRep; +} Object; + +</PRE> +</DIV> +<P> SWIG will then create an <TT>Object_intRep</TT> structure for use + inside the interface file. Accessor functions will be created for both + structures. In this case, functions like this would be created :</P> +<DIV class="code"> +<PRE> +Object_intRep *Object_intRep_get(Object *o) { + return (Object_intRep *) &o->intRep; +} +int Object_intRep_ivalue_get(Object_intRep *o) { + return o->ivalue; +} +int Object_intRep_ivalue_set(Object_intRep *o, int value) { + return (o->ivalue = value); +} +double Object_intRep_dvalue_get(Object_intRep *o) { + return o->dvalue; +} +... etc ... + +</PRE> +</DIV> +<P> Although this process is a little hairy, it works like you would + expect in the target scripting language--especially when proxy classes + are used. For instance, in Perl:</P> +<DIV class="targetlang"> +<PRE> +# Perl5 script for accessing nested member +$o = CreateObject(); # Create an object somehow +$o->{intRep}->{ivalue} = 7 # Change value of o.intRep.ivalue +</PRE> +</DIV> +<P> If you have a lot nested structure declarations, it is advisable to + double-check them after running SWIG. Although, there is a good chance + that they will work, you may have to modify the interface file in + certain cases.</P> +<H3><A name="SWIG_nn39"></A>5.5.8 Other things to note about structure + wrapping</H3> +<P> SWIG doesn't care if the declaration of a structure in a <TT>.i</TT> + file exactly matches that used in the underlying C code (except in the + case of nested structures). For this reason, there are no problems + omitting problematic members or simply omitting the structure + definition altogether. If you are happy passing pointers around, this + can be done without ever giving SWIG a structure definition.</P> +<P> Starting with SWIG1.3, a number of improvements have been made to + SWIG's code generator. Specifically, even though structure access has + been described in terms of high-level accessor functions such as this,</P> +<DIV class="code"> +<PRE> +double Vector_x_get(Vector *v) { + return v->x; +} +</PRE> +</DIV> +<P> most of the generated code is actually inlined directly into wrapper + functions. Therefore, no function <TT>Vector_x_get()</TT> actually + exists in the generated wrapper file. For example, when creating a Tcl + module, the following function is generated instead:</P> +<DIV class="code"> +<PRE> +static int +_wrap_Vector_x_get(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) { + struct Vector *arg1 ; + double result ; + + if (SWIG_GetArgs(interp, objc, objv,"p:Vector_x_get self ",&arg0, + SWIGTYPE_p_Vector) == TCL_ERROR) + return TCL_ERROR; + result = (double ) (arg1->x); + Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result)); + return TCL_OK; +} +</PRE> +</DIV> +<P> The only exception to this rule are methods defined with <TT>%extend</TT> +. In this case, the added code is contained in a separate function.</P> +<P> Finally, it is important to note that most language modules may + choose to build a more advanced interface. Although you may never use + the low-level interface described here, most of SWIG's language modules + use it in some way or another.</P> +<H2><A name="SWIG_nn40"></A>5.6 Code Insertion</H2> +<P> Sometimes it is necessary to insert special code into the resulting + wrapper file generated by SWIG. For example, you may want to include + additional C code to perform initialization or other operations. There + are four common ways to insert code, but it's useful to know how the + output of SWIG is structured first.</P> +<H3><A name="SWIG_nn41"></A>5.6.1 The output of SWIG</H3> +<P> When SWIG creates its output file, it is broken up into four + sections corresponding to runtime code, headers, wrapper functions, and + module initialization code (in that order).</P> +<UL> +<LI><B>Begin section</B>. +<BR> A placeholder to put code at the beginning of the C/C++ wrapper + file.</LI> +<LI><B>Runtime code</B>. +<BR> This code is internal to SWIG and is used to include type-checking + and other support functions that are used by the rest of the module.</LI> +<LI><B>Header section</B>. +<BR> This is user-defined support code that has been included by the <TT> +%{ ... %}</TT> directive. Usually this consists of header files and + other helper functions.</LI> +<LI><B>Wrapper code</B>. +<BR> These are the wrappers generated automatically by SWIG.</LI> +<LI><B>Module initialization</B>. +<BR> The function generated by SWIG to initialize the module upon + loading.</LI> +</UL> +<H3><A name="SWIG_nn42"></A>5.6.2 Code insertion blocks</H3> +<P> Code is inserted into the appropriate code section by using one of + the code insertion directives listed below. The order of the sections + in the wrapper file is as shown:</P> +<DIV class="code"> +<PRE> +%begin %{ + ... code in begin section ... +%} + +%runtime %{ + ... code in runtime section ... +%} + +%header %{ + ... code in header section ... +%} + +%wrapper %{ + ... code in wrapper section ... +%} + +%init %{ + ... code in init section ... +%} +</PRE> +</DIV> +<P> The bare <TT>%{ ... %}</TT> directive is a shortcut that is the same + as <TT>%header %{ ... %}</TT>.</P> +<P> The <TT>%begin</TT> section is effectively empty as it just contains + the SWIG banner by default. This section is provided as a way for users + to insert code at the top of the wrapper file before any other code is + generated. Everything in a code insertion block is copied verbatim into + the output file and is not parsed by SWIG. Most SWIG input files have + at least one such block to include header files and support C code. + Additional code blocks may be placed anywhere in a SWIG file as needed.</P> +<DIV class="code"> +<PRE> +%module mymodule +%{ +#include "my_header.h" +%} +... Declare functions here +%{ + +void some_extra_function() { + ... +} +%} +</PRE> +</DIV> +<P> A common use for code blocks is to write "helper" functions. These + are functions that are used specifically for the purpose of building an + interface, but which are generally not visible to the normal C program. + For example :</P> +<DIV class="code"> +<PRE> +%{ +/* Create a new vector */ +static Vector *new_Vector() { + return (Vector *) malloc(sizeof(Vector)); +} + +%} +// Now wrap it +Vector *new_Vector(); +</PRE> +</DIV> +<H3><A name="SWIG_nn43"></A>5.6.3 Inlined code blocks</H3> +<P> Since the process of writing helper functions is fairly common, + there is a special inlined form of code block that is used as follows :</P> +<DIV class="code"> +<PRE> +%inline %{ +/* Create a new vector */ +Vector *new_Vector() { + return (Vector *) malloc(sizeof(Vector)); +} +%} + +</PRE> +</DIV> +<P> The <TT>%inline</TT> directive inserts all of the code that follows + verbatim into the header portion of an interface file. The code is then + parsed by both the SWIG preprocessor and parser. Thus, the above + example creates a new command <TT>new_Vector</TT> using only one + declaration. Since the code inside an <TT>%inline %{ ... %}</TT> block + is given to both the C compiler and SWIG, it is illegal to include any + SWIG directives inside a <TT>%{ ... %}</TT> block.</P> +<H3><A name="SWIG_nn44"></A>5.6.4 Initialization blocks</H3> +<P> When code is included in the <TT>%init</TT> section, it is copied + directly into the module initialization function. For example, if you + needed to perform some extra initialization on module loading, you + could write this:</P> +<DIV class="code"> +<PRE> +%init %{ + init_variables(); +%} +</PRE> +</DIV> +<H2><A name="SWIG_nn45"></A>5.7 An Interface Building Strategy</H2> +<P> This section describes the general approach for building interface + with SWIG. The specifics related to a particular scripting language are + found in later chapters.</P> +<H3><A name="SWIG_nn46"></A>5.7.1 Preparing a C program for SWIG</H3> +<P> SWIG doesn't require modifications to your C code, but if you feed + it a collection of raw C header files or source code, the results might + not be what you expect---in fact, they might be awful. Here's a series + of steps you can follow to make an interface for a C program :</P> +<UL> +<LI>Identify the functions that you want to wrap. It's probably not + necessary to access every single function in a C program--thus, a + little forethought can dramatically simplify the resulting scripting + language interface. C header files are particularly good source for + finding things to wrap.</LI> +<LI>Create a new interface file to describe the scripting language + interface to your program.</LI> +<LI>Copy the appropriate declarations into the interface file or use + SWIG's <TT>%include</TT> directive to process an entire C source/header + file.</LI> +<LI>Make sure everything in the interface file uses ANSI C/C++ syntax.</LI> +<LI>Make sure all necessary `<TT>typedef</TT>' declarations and + type-information is available in the interface file. In particular, + ensure that the type information is specified in the correct order as + required by a C/C++ compiler. Most importantly, define a type before it + is used! A C compiler will tell you if the full type information is not + available if it is needed, whereas SWIG will usually not warn or error + out as it is designed to work without full type information. However, + if type information is not specified correctly, the wrappers can be + sub-optimal and even result in uncompileable C/C++ code.</LI> +<LI>If your program has a main() function, you may need to rename it + (read on).</LI> +<LI>Run SWIG and compile.</LI> +</UL> +<P> Although this may sound complicated, the process turns out to be + fairly easy once you get the hang of it.</P> +<P> In the process of building an interface, SWIG may encounter syntax + errors or other problems. The best way to deal with this is to simply + copy the offending code into a separate interface file and edit it. + However, the SWIG developers have worked very hard to improve the SWIG + parser--you should report parsing errors to the <A href="http://www.swig.org/mail.html"> +swig-devel mailing list</A> or to the <A href="http://www.swig.org/bugs.html"> +SWIG bug tracker</A>.</P> +<H3><A name="SWIG_nn47"></A>5.7.2 The SWIG interface file</H3> +<P> The preferred method of using SWIG is to generate separate interface + file. Suppose you have the following C header file :</P> +<DIV class="code"> +<PRE> +/* File : header.h */ + +#include <stdio.h> +#include <math.h> + +extern int foo(double); +extern double bar(int, int); +extern void dump(FILE *f); + +</PRE> +</DIV> +<P> A typical SWIG interface file for this header file would look like + the following :</P> +<DIV class="code"> +<PRE> +/* File : interface.i */ +%module mymodule +%{ +#include "header.h" +%} +extern int foo(double); +extern double bar(int, int); +extern void dump(FILE *f); + +</PRE> +</DIV> +<P> Of course, in this case, our header file is pretty simple so we + could use a simpler approach and use an interface file like this:</P> +<DIV class="code"> +<PRE> +/* File : interface.i */ +%module mymodule +%{ +#include "header.h" +%} +%include "header.h" +</PRE> +</DIV> +<P> The main advantage of this approach is minimal maintenance of an + interface file for when the header file changes in the future. In more + complex projects, an interface file containing numerous <TT>%include</TT> + and <TT>#include</TT> statements like this is one of the most common + approaches to interface file design due to lower maintenance overhead.</P> +<H3><A name="SWIG_nn48"></A>5.7.3 Why use separate interface files?</H3> +<P> Although SWIG can parse many header files, it is more common to + write a special <TT>.i</TT> file defining the interface to a package. + There are several reasons why you might want to do this:</P> +<UL> +<LI>It is rarely necessary to access every single function in a large + package. Many C functions might have little or no use in a scripted + environment. Therefore, why wrap them?</LI> +<LI>Separate interface files provide an opportunity to provide more + precise rules about how an interface is to be constructed.</LI> +<LI>Interface files can provide more structure and organization.</LI> +<LI>SWIG can't parse certain definitions that appear in header files. + Having a separate file allows you to eliminate or work around these + problems.</LI> +<LI>Interface files provide a more precise definition of what the + interface is. Users wanting to extend the system can go to the + interface file and immediately see what is available without having to + dig it out of header files.</LI> +</UL> +<H3><A name="SWIG_nn49"></A>5.7.4 Getting the right header files</H3> +<P> Sometimes, it is necessary to use certain header files in order for + the code generated by SWIG to compile properly. Make sure you include + certain header files by using a <TT>%{,%}</TT> block like this:</P> +<DIV class="code"> +<PRE> +%module graphics +%{ +#include <GL/gl.h> +#include <GL/glu.h> +%} + +// Put rest of declarations here +... +</PRE> +</DIV> +<H3><A name="SWIG_nn50"></A>5.7.5 What to do with main()</H3> +<P> If your program defines a <TT>main()</TT> function, you may need to + get rid of it or rename it in order to use a scripting language. Most + scripting languages define their own <TT>main()</TT> procedure that is + called instead. <TT>main()</TT> also makes no sense when working with + dynamic loading. There are a few approaches to solving the <TT>main()</TT> + conflict :</P> +<UL> +<LI>Get rid of <TT>main()</TT> entirely.</LI> +<LI>Rename <TT>main()</TT> to something else. You can do this by + compiling your C program with an option like <TT>-Dmain=oldmain</TT>.</LI> +<LI>Use conditional compilation to only include <TT>main()</TT> when not + using a scripting language.</LI> +</UL> +<P> Getting rid of <TT>main()</TT> may cause potential initialization + problems of a program. To handle this problem, you may consider writing + a special function called <TT>program_init()</TT> that initializes your + program upon startup. This function could then be called either from + the scripting language as the first operation, or when the SWIG + generated module is loaded.</P> +<P> As a general note, many C programs only use the <TT>main()</TT> + function to parse command line options and to set parameters. However, + by using a scripting language, you are probably trying to create a + program that is more interactive. In many cases, the old <TT>main()</TT> + program can be completely replaced by a Perl, Python, or Tcl script.</P> +<P><B> Note:</B> If some cases, you might be inclined to create a + scripting language wrapper for <TT>main()</TT>. If you do this, the + compilation will probably work and your module might even load + correctly. The only trouble is that when you call your <TT>main()</TT> + wrapper, you will find that it actually invokes the <TT>main()</TT> of + the scripting language interpreter itself! This behavior is a side + effect of the symbol binding mechanism used in the dynamic linker. The + bottom line: don't do this.</P> +<HR NOSHADE> +<H1><A name="SWIGPlus"></A>6 SWIG and C++</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#SWIGPlus_nn2">Comments on C++ Wrapping</A></LI> +<LI><A href="#SWIGPlus_nn3">Approach</A></LI> +<LI><A href="#SWIGPlus_nn4">Supported C++ features</A></LI> +<LI><A href="#SWIGPlus_nn5">Command line options and compilation</A></LI> +<LI><A href="#SWIGPlus_nn38">Proxy classes</A> +<UL> +<LI><A href="#SWIGPlus_nn39">Construction of proxy classes</A></LI> +<LI><A href="#SWIGPlus_nn40">Resource management in proxies</A></LI> +<LI><A href="#SWIGPlus_nn41">Language specific details</A></LI> +</UL> +</LI> +<LI><A href="#SWIGPlus_nn6">Simple C++ wrapping</A> +<UL> +<LI><A href="#SWIGPlus_nn7">Constructors and destructors</A></LI> +<LI><A href="#SWIGPlus_nn8">Default constructors, copy constructors and + implicit destructors</A></LI> +<LI><A href="#SWIGPlus_nn9">When constructor wrappers aren't created</A></LI> +<LI><A href="#SWIGPlus_nn10">Copy constructors</A></LI> +<LI><A href="#SWIGPlus_nn11">Member functions</A></LI> +<LI><A href="#SWIGPlus_nn12">Static members</A></LI> +<LI><A href="#SWIGPlus_member_data">Member data</A></LI> +</UL> +</LI> +<LI><A href="#SWIGPlus_default_args">Default arguments</A></LI> +<LI><A href="#SWIGPlus_nn15">Protection</A></LI> +<LI><A href="#SWIGPlus_nn16">Enums and constants</A></LI> +<LI><A href="#SWIGPlus_nn17">Friends</A></LI> +<LI><A href="#SWIGPlus_nn18">References and pointers</A></LI> +<LI><A href="#SWIGPlus_nn19">Pass and return by value</A></LI> +<LI><A href="#SWIGPlus_nn20">Inheritance</A></LI> +<LI><A href="#SWIGPlus_nn21">A brief discussion of multiple inheritance, + pointers, and type checking</A></LI> +<LI><A href="#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions + and Methods</A> +<UL> +<LI><A href="#SWIGPlus_nn24">Dispatch function generation</A></LI> +<LI><A href="#SWIGPlus_nn25">Ambiguity in Overloading</A></LI> +<LI><A href="#ambiguity_resolution_renaming">Ambiguity resolution and + renaming</A></LI> +<LI><A href="#SWIGPlus_nn27">Comments on overloading</A></LI> +</UL> +</LI> +<LI><A href="#SWIGPlus_nn28">Wrapping overloaded operators</A></LI> +<LI><A href="#SWIGPlus_class_extension">Class extension</A></LI> +<LI><A href="#SWIGPlus_nn30">Templates</A></LI> +<LI><A href="#SWIGPlus_nn31">Namespaces</A></LI> +<LI><A href="#SWIGPlus_renaming_templated_types_namespaces">Renaming + templated types in namespaces</A></LI> +<LI><A href="#SWIGPlus_exception_specifications">Exception + specifications</A></LI> +<LI><A href="#SWIGPlus_catches">Exception handling with %catches</A></LI> +<LI><A href="#SWIGPlus_nn33">Pointers to Members</A></LI> +<LI><A href="#SWIGPlus_nn34">Smart pointers and operator->()</A></LI> +<LI><A href="#SWIGPlus_nn35">Using declarations and inheritance</A></LI> +<LI><A href="#SWIGPlus_nested_classes">Nested classes</A></LI> +<LI><A href="#SWIGPlus_nn37">A brief rant about const-correctness</A></LI> +<LI><A href="#SWIGPlus_nn42">Where to go for more information</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes SWIG's support for wrapping C++. As a + prerequisite, you should first read the chapter <A href="#SWIG">SWIG + Basics</A> to see how SWIG wraps ANSI C. Support for C++ builds upon + ANSI C wrapping and that material will be useful in understanding this + chapter.</P> +<H2><A name="SWIGPlus_nn2"></A>6.1 Comments on C++ Wrapping</H2> +<P> Because of its complexity and the fact that C++ can be difficult to + integrate with itself let alone other languages, SWIG only provides + support for a subset of C++ features. Fortunately, this is now a rather + large subset.</P> +<P> In part, the problem with C++ wrapping is that there is no + semantically obvious (or automatic ) way to map many of its advanced + features into other languages. As a simple example, consider the + problem of wrapping C++ multiple inheritance to a target language with + no such support. Similarly, the use of overloaded operators and + overloaded functions can be problematic when no such capability exists + in a target language.</P> +<P> A more subtle issue with C++ has to do with the way that some C++ + programmers think about programming libraries. In the world of SWIG, + you are really trying to create binary-level software components for + use in other languages. In order for this to work, a "component" has to + contain real executable instructions and there has to be some kind of + binary linking mechanism for accessing its functionality. In contrast, + C++ has increasingly relied upon generic programming and templates for + much of its functionality. Although templates are a powerful feature, + they are largely orthogonal to the whole notion of binary components + and libraries. For example, an STL <TT>vector</TT> does not define any + kind of binary object for which SWIG can just create a wrapper. To + further complicate matters, these libraries often utilize a lot of + behind the scenes magic in which the semantics of seemingly basic + operations (e.g., pointer dereferencing, procedure call, etc.) can be + changed in dramatic and sometimes non-obvious ways. Although this + "magic" may present few problems in a C++-only universe, it greatly + complicates the problem of crossing language boundaries and provides + many opportunities to shoot yourself in the foot. You will just have to + be careful.</P> +<H2><A name="SWIGPlus_nn3"></A>6.2 Approach</H2> +<P> To wrap C++, SWIG uses a layered approach to code generation. At the + lowest level, SWIG generates a collection of procedural ANSI-C style + wrappers. These wrappers take care of basic type conversion, type + checking, error handling, and other low-level details of the C++ + binding. These wrappers are also sufficient to bind C++ into any target + language that supports built-in procedures. In some sense, you might + view this layer of wrapping as providing a C library interface to C++. + On top of the low-level procedural (flattened) interface, SWIG + generates proxy classes that provide a natural object-oriented (OO) + interface to the underlying code. The proxy classes are typically + written in the target language itself. For instance, in Python, a real + Python class is used to provide a wrapper around the underlying C++ + object.</P> +<P> It is important to emphasize that SWIG takes a deliberately + conservative and non-intrusive approach to C++ wrapping. SWIG does not + encapsulate C++ classes inside a special C++ adaptor, it does not rely + upon templates, nor does it add in additional C++ inheritance when + generating wrappers. The last thing that most C++ programs need is even + more compiler magic. Therefore, SWIG tries to maintain a very strict + and clean separation between the implementation of your C++ application + and the resulting wrapper code. You might say that SWIG has been + written to follow the principle of least surprise--it does not play + sneaky tricks with the C++ type system, it doesn't mess with your class + hierarchies, and it doesn't introduce new semantics. Although this + approach might not provide the most seamless integration with C++, it + is safe, simple, portable, and debuggable.</P> +<P> Some of this chapter focuses on the low-level procedural interface + to C++ that is used as the foundation for all language modules. Keep in + mind that the target languages also provide the high-level OO interface + via proxy classes. More detailed coverage can be found in the + documentation for each target language.</P> +<H2><A name="SWIGPlus_nn4"></A>6.3 Supported C++ features</H2> +<P> SWIG currently supports most C++ features including the following:</P> +<UL> +<LI>Classes</LI> +<LI>Constructors and destructors</LI> +<LI>Virtual functions</LI> +<LI>Public inheritance (including multiple inheritance)</LI> +<LI>Static functions</LI> +<LI>Function and method overloading</LI> +<LI>Operator overloading for many standard operators</LI> +<LI>References</LI> +<LI>Templates (including specialization and member templates)</LI> +<LI>Pointers to members</LI> +<LI>Namespaces</LI> +<LI>Default parameters</LI> +<LI>Smart pointers</LI> +</UL> +<P> The following C++ features are not currently supported:</P> +<UL> +<LI>Overloaded versions of certain operators (new, delete, etc.)</LI> +<LI>Nested classes, see <A href="#SWIGPlus_nested_classes">Nested + classes</A> for workarounds.</LI> +</UL> +<P> As a rule of thumb, SWIG should not be used on raw C++ source files, + use header files only.</P> +<P> SWIG's C++ support is an ongoing project so some of these + limitations may be lifted in future releases. However, we make no + promises. Also, submitting a bug report is a very good way to get + problems fixed (wink).</P> +<H2><A name="SWIGPlus_nn5"></A>6.4 Command line options and compilation</H2> +<P> When wrapping C++ code, it is critical that SWIG be called with the + `<TT>-c++</TT>' option. This changes the way a number of critical + features such as memory management are handled. It also enables the + recognition of C++ keywords. Without the <TT>-c++</TT> flag, SWIG will + either issue a warning or a large number of syntax errors if it + encounters C++ code in an interface file.</P> +<P> When compiling and linking the resulting wrapper file, it is normal + to use the C++ compiler. For example:</P> +<DIV class="shell"> +<PRE> +$ swig -c++ -tcl example.i +$ c++ -c example_wrap.cxx +$ c++ example_wrap.o $(OBJS) -o example.so +</PRE> +</DIV> +<P> Unfortunately, the process varies slightly on each platform. Make + sure you refer to the documentation on each target language for further + details. The SWIG Wiki also has further details.</P> +<B> Compatibility Note:</B> Early versions of SWIG generated just a + flattened low-level C style API to C++ classes by default. The <TT> +-noproxy</TT> commandline option is recognised by many target languages + and will generate just this interface as in earlier versions. +<H2><A name="SWIGPlus_nn38"></A>6.5 Proxy classes</H2> +<P> In order to provide a natural mapping from C++ classes to the target + language classes, SWIG's target languages mostly wrap C++ classes with + special proxy classes. These proxy classes are typically implemented in + the target language itself. For example, if you're building a Python + module, each C++ class is wrapped by a Python proxy class. Or if you're + building a Java module, each C++ class is wrapped by a Java proxy + class.</P> +<H3><A name="SWIGPlus_nn39"></A>6.5.1 Construction of proxy classes</H3> +<P> Proxy classes are always constructed as an extra layer of wrapping + that uses low-level accessor functions. To illustrate, suppose you had + a C++ class like this:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + ~Foo(); + int bar(int x); + int x; +}; +</PRE> +</DIV> +<P> Using C++ as pseudocode, a proxy class looks something like this:</P> +<DIV class="code"> +<PRE> +class FooProxy { +private: + Foo *self; +public: + FooProxy() { + self = new_Foo(); + } + ~FooProxy() { + delete_Foo(self); + } + int bar(int x) { + return Foo_bar(self,x); + } + int x_get() { + return Foo_x_get(self); + } + void x_set(int x) { + Foo_x_set(self,x); + } +}; +</PRE> +</DIV> +<P> Of course, always keep in mind that the real proxy class is written + in the target language. For example, in Python, the proxy might look + roughly like this:</P> +<DIV class="targetlang"> +<PRE> +class Foo: + def __init__(self): + self.this = new_Foo() + def __del__(self): + delete_Foo(self.this) + def bar(self,x): + return Foo_bar(self.this,x) + def __getattr__(self,name): + if name == 'x': + return Foo_x_get(self.this) + ... + def __setattr__(self,name,value): + if name == 'x': + Foo_x_set(self.this,value) + ... +</PRE> +</DIV> +<P> Again, it's important to emphasize that the low-level accessor + functions are always used by the proxy classes. Whenever possible, + proxies try to take advantage of language features that are similar to + C++. This might include operator overloading, exception handling, and + other features.</P> +<H3><A name="SWIGPlus_nn40"></A>6.5.2 Resource management in proxies</H3> +<P> A major issue with proxies concerns the memory management of wrapped + objects. Consider the following C++ code:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + ~Foo(); + int bar(int x); + int x; +}; + +class Spam { +public: + Foo *value; + ... +}; +</PRE> +</DIV> +<P> Consider some script code that uses these classes:</P> +<DIV class="targetlang"> +<PRE> +f = Foo() # Creates a new Foo +s = Spam() # Creates a new Spam +s.value = f # Stores a reference to f inside s +g = s.value # Returns stored reference +g = 4 # Reassign g to some other value +del f # Destroy f +</PRE> +</DIV> +<P> Now, ponder the resulting memory management issues. When objects are + created in the script, the objects are wrapped by newly created proxy + classes. That is, there is both a new proxy class instance and a new + instance of the underlying C++ class. In this example, both <TT>f</TT> + and <TT>s</TT> are created in this way. However, the statement <TT> +s.value</TT> is rather curious---when executed, a pointer to <TT>f</TT> + is stored inside another object. This means that the scripting proxy + class<EM> AND</EM> another C++ class share a reference to the same + object. To make matters even more interesting, consider the statement <TT> +g = s.value</TT>. When executed, this creates a new proxy class <TT>g</TT> + that provides a wrapper around the C++ object stored in <TT>s.value</TT> +. In general, there is no way to know where this object came from---it + could have been created by the script, but it could also have been + generated internally. In this particular example, the assignment of <TT> +g</TT> results in a second proxy class for <TT>f</TT>. In other words, a + reference to <TT>f</TT> is now shared by two proxy classes<EM> and</EM> + a C++ class.</P> +<P> Finally, consider what happens when objects are destroyed. In the + statement, <TT>g=4</TT>, the variable <TT>g</TT> is reassigned. In many + languages, this makes the old value of <TT>g</TT> available for garbage + collection. Therefore, this causes one of the proxy classes to be + destroyed. Later on, the statement <TT>del f</TT> destroys the other + proxy class. Of course, there is still a reference to the original + object stored inside another C++ object. What happens to it? Is the + object still valid?</P> +<P> To deal with memory management problems, proxy classes provide an + API for controlling ownership. In C++ pseudocode, ownership control + might look roughly like this:</P> +<DIV class="code"> +<PRE> +class FooProxy { +public: + Foo *self; + int thisown; + + FooProxy() { + self = new_Foo(); + thisown = 1; // Newly created object + } + ~FooProxy() { + if (thisown) delete_Foo(self); + } + ... + // Ownership control API + void disown() { + thisown = 0; + } + void acquire() { + thisown = 1; + } +}; + +class FooPtrProxy: public FooProxy { +public: + FooPtrProxy(Foo *s) { + self = s; + thisown = 0; + } +}; + +class SpamProxy { + ... + FooProxy *value_get() { + return FooPtrProxy(Spam_value_get(self)); + } + void value_set(FooProxy *v) { + Spam_value_set(self,v->self); + v->disown(); + } + ... +}; +</PRE> +</DIV> +<P> Looking at this code, there are a few central features:</P> +<UL> +<LI>Each proxy class keeps an extra flag to indicate ownership. C++ + objects are only destroyed if the ownership flag is set.</LI> +<LI>When new objects are created in the target language, the ownership + flag is set.</LI> +<LI>When a reference to an internal C++ object is returned, it is + wrapped by a proxy class, but the proxy class does not have ownership.</LI> +<LI>In certain cases, ownership is adjusted. For instance, when a value + is assigned to the member of a class, ownership is lost.</LI> +<LI>Manual ownership control is provided by special <TT>disown()</TT> + and <TT>acquire()</TT> methods.</LI> +</UL> +<P> Given the tricky nature of C++ memory management, it is impossible + for proxy classes to automatically handle every possible memory + management problem. However, proxies do provide a mechanism for manual + control that can be used (if necessary) to address some of the more + tricky memory management problems.</P> +<H3><A name="SWIGPlus_nn41"></A>6.5.3 Language specific details</H3> +<P> Language specific details on proxy classes are contained in the + chapters describing each target language. This chapter has merely + introduced the topic in a very general way.</P> +<H2><A name="SWIGPlus_nn6"></A>6.6 Simple C++ wrapping</H2> +<P> The following code shows a SWIG interface file for a simple C++ + class.</P> +<DIV class="code"> +<PRE> +%module list +%{ +#include "list.h" +%} + +// Very simple C++ example for linked list + +class List { +public: + List(); + ~List(); + int search(char *value); + void insert(char *); + void remove(char *); + char *get(int n); + int length; +static void print(List *l); +}; +</PRE> +</DIV> +<P> To generate wrappers for this class, SWIG first reduces the class to + a collection of low-level C-style accessor functions which are then + used by the proxy classes.</P> +<H3><A name="SWIGPlus_nn7"></A>6.6.1 Constructors and destructors</H3> +<P> C++ constructors and destructors are translated into accessor + functions such as the following :</P> +<DIV class="code"> +<PRE> +List * new_List(void) { + return new List; +} +void delete_List(List *l) { + delete l; +} + +</PRE> +</DIV> +<H3><A name="SWIGPlus_nn8"></A>6.6.2 Default constructors, copy + constructors and implicit destructors</H3> +<P> Following the C++ rules for implicit constructor and destructors, + SWIG will automatically assume there is one even when they are not + explicitly declared in the class interface.</P> +<P> In general then:</P> +<UL> +<LI> If a C++ class does not declare any explicit constructor, SWIG will + automatically generate a wrapper for one.</LI> +<LI> If a C++ class does not declare an explicit copy constructor, SWIG + will automatically generate a wrapper for one if the <TT>%copyctor</TT> + is used.</LI> +<LI> If a C++ class does not declare an explicit destructor, SWIG will + automatically generate a wrapper for one.</LI> +</UL> +<P> And as in C++, a few rules that alters the previous behavior:</P> +<UL> +<LI>A default constructor is not created if a class already defines a + constructor with arguments.</LI> +<LI>Default constructors are not generated for classes with pure virtual + methods or for classes that inherit from an abstract class, but don't + provide definitions for all of the pure methods.</LI> +<LI>A default constructor is not created unless all base classes support + a default constructor.</LI> +<LI>Default constructors and implicit destructors are not created if a + class defines them in a <TT>private</TT> or <TT>protected</TT> section.</LI> +<LI>Default constructors and implicit destructors are not created if any + base class defines a non-public default constructor or destructor.</LI> +</UL> +<P> SWIG should never generate a default constructor, copy constructor + or default destructor wrapper for a class in which it is illegal to do + so. In some cases, however, it could be necessary (if the complete + class declaration is not visible from SWIG, and one of the above rules + is violated) or desired (to reduce the size of the final interface) by + manually disabling the implicit constructor/destructor generation.</P> +<P> To manually disable these, the <TT>%nodefaultctor</TT> and <TT> +%nodefaultdtor</TT> <A href="#Customization_feature_flags">feature flag</A> + directives can be used. Note that these directives only affects the + implicit generation, and they have no effect if the default/copy + constructors or destructor are explicitly declared in the class + interface.</P> +<P> For example:</P> +<DIV class="code"> +<PRE> +%nodefaultctor Foo; // Disable the default constructor for class Foo. +class Foo { // No default constructor is generated, unless one is declared +... +}; +class Bar { // A default constructor is generated, if possible +... +}; +</PRE> +</DIV> +<P> The directive <TT>%nodefaultctor</TT> can also be applied + "globally", as in:</P> +<DIV class="code"> +<PRE> +%nodefaultctor; // Disable creation of default constructors +class Foo { // No default constructor is generated, unless one is declared +... +}; +class Bar { +public: + Bar(); // The default constructor is generated, since one is declared +}; +%clearnodefaultctor; // Enable the creation of default constructors again +</PRE> +</DIV> +<P> The corresponding <TT>%nodefaultdtor</TT> directive can be used to + disable the generation of the default or implicit destructor, if + needed. Be aware, however, that this could lead to memory leaks in the + target language. Hence, it is recommended to use this directive only in + well known cases. For example:</P> +<DIV class="code"> +<PRE> +%nodefaultdtor Foo; // Disable the implicit/default destructor for class Foo. +class Foo { // No destructor is generated, unless one is declared +... +}; +</PRE> +</DIV> +<P><B> Compatibility Note:</B> The generation of default + constructors/implicit destructors was made the default behavior in SWIG + 1.3.7. This may break certain older modules, but the old behavior can + be easily restored using <TT>%nodefault</TT> or the <TT>-nodefault</TT> + command line option. Furthermore, in order for SWIG to properly + generate (or not generate) default constructors, it must be able to + gather information from both the <TT>private</TT> and <TT>protected</TT> + sections (specifically, it needs to know if a private or protected + constructor/destructor is defined). In older versions of SWIG, it was + fairly common to simply remove or comment out the private and protected + sections of a class due to parser limitations. However, this removal + may now cause SWIG to erroneously generate constructors for classes + that define a constructor in those sections. Consider restoring those + sections in the interface or using <TT>%nodefault</TT> to fix the + problem.</P> +<P><B> Note:</B> The <TT>%nodefault</TT> directive/<TT>-nodefault</TT> + options described above, which disable both the default constructor and + the implicit destructors, could lead to memory leaks, and so it is + strongly recommended to not use them.</P> +<H3><A name="SWIGPlus_nn9"></A>6.6.3 When constructor wrappers aren't + created</H3> +<P> If a class defines a constructor, SWIG normally tries to generate a + wrapper for it. However, SWIG will not generate a constructor wrapper + if it thinks that it will result in illegal wrapper code. There are + really two cases where this might show up.</P> +<P> First, SWIG won't generate wrappers for protected or private + constructors. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +protected: + Foo(); // Not wrapped. +public: + ... +}; +</PRE> +</DIV> +<P> Next, SWIG won't generate wrappers for a class if it appears to be + abstract--that is, it has undefined pure virtual methods. Here are some + examples:</P> +<DIV class="code"> +<PRE> +class Bar { +public: + Bar(); // Not wrapped. Bar is abstract. + virtual void spam(void) = 0; +}; + +class Grok : public Bar { +public: + Grok(); // Not wrapped. No implementation of abstract spam(). +}; +</PRE> +</DIV> +<P> Some users are surprised (or confused) to find missing constructor + wrappers in their interfaces. In almost all cases, this is caused when + classes are determined to be abstract. To see if this is the case, run + SWIG with all of its warnings turned on:</P> +<DIV class="shell"> +<PRE> +% swig -Wall -python module.i +</PRE> +</DIV> +<P> In this mode, SWIG will issue a warning for all abstract classes. It + is possible to force a class to be non-abstract using this:</P> +<DIV class="code"> +<PRE> +%feature("notabstract") Foo; + +class Foo : public Bar { +public: + Foo(); // Generated no matter what---not abstract. + ... +}; +</PRE> +</DIV> +<P> More information about <TT>%feature</TT> can be found in the <A href="#Customization"> +Customization features</A> chapter.</P> +<H3><A name="SWIGPlus_nn10"></A>6.6.4 Copy constructors</H3> +<P> If a class defines more than one constructor, its behavior depends + on the capabilities of the target language. If overloading is + supported, the copy constructor is accessible using the normal + constructor function. For example, if you have this:</P> +<DIV class="code"> +<PRE> +class List { +public: + List(); + List(const List &); // Copy constructor + ... +}; +</PRE> +</DIV> +<P> then the copy constructor can be used as follows:</P> +<DIV class="targetlang"> +<PRE> +x = List() # Create a list +y = List(x) # Copy list x +</PRE> +</DIV> +<P> If the target language does not support overloading, then the copy + constructor is available through a special function like this:</P> +<DIV class="code"> +<PRE> +List *copy_List(List *f) { + return new List(*f); +} +</PRE> +</DIV> +<P><B> Note:</B> For a class <TT>X</TT>, SWIG only treats a constructor + as a copy constructor if it can be applied to an object of type <TT>X</TT> + or <TT>X *</TT>. If more than one copy constructor is defined, only the + first definition that appears is used as the copy constructor--other + definitions will result in a name-clash. Constructors such as <TT> +X(const X &)</TT>, <TT>X(X &)</TT>, and <TT>X(X *)</TT> are handled as + copy constructors in SWIG.</P> +<P><B> Note:</B> SWIG does<EM> not</EM> generate a copy constructor + wrapper unless one is explicitly declared in the class. This differs + from the treatment of default constructors and destructors. However, + copy constructor wrappers can be generated if using the <TT>copyctor</TT> + <A href="#Customization_feature_flags">feature flag</A>. For example:</P> +<DIV class="code"> +<PRE> +%copyctor List; + +class List { +public: + List(); +}; +</PRE> +</DIV> +<P> Will generate a copy constructor wrapper for <TT>List</TT>.</P> +<P><B> Compatibility note:</B> Special support for copy constructors was + not added until SWIG-1.3.12. In previous versions, copy constructors + could be wrapped, but they had to be renamed. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + %name(CopyFoo) Foo(const Foo &); + ... +}; +</PRE> +</DIV> +<P> For backwards compatibility, SWIG does not perform any special + copy-constructor handling if the constructor has been manually renamed. + For instance, in the above example, the name of the constructor is set + to <TT>new_CopyFoo()</TT>. This is the same as in older versions.</P> +<H3><A name="SWIGPlus_nn11"></A>6.6.5 Member functions</H3> +<P> All member functions are roughly translated into accessor functions + like this :</P> +<DIV class="code"> +<PRE> +int List_search(List *obj, char *value) { + return obj->search(value); +} + +</PRE> +</DIV> +<P> This translation is the same even if the member function has been + declared as <TT>virtual</TT>.</P> +<P> It should be noted that SWIG does not<EM> actually</EM> create a C + accessor function in the code it generates. Instead, member access such + as <TT>obj->search(value)</TT> is directly inlined into the generated + wrapper functions. However, the name and calling convention of the + low-level procedural wrappers match the accessor function prototype + described above.</P> +<H3><A name="SWIGPlus_nn12"></A>6.6.6 Static members</H3> +<P> Static member functions are called directly without making any + special transformations. For example, the static member function <TT> +print(List *l)</TT> directly invokes <TT>List::print(List *l)</TT> in + the generated wrapper code.</P> +<H3><A name="SWIGPlus_member_data"></A>6.6.7 Member data</H3> +<P> Member data is handled in exactly the same manner as for C + structures. A pair of accessor functions are effectively created. For + example :</P> +<DIV class="code"> +<PRE> +int List_length_get(List *obj) { + return obj->length; +} +int List_length_set(List *obj, int value) { + obj->length = value; + return value; +} + +</PRE> +</DIV> +<P> A read-only member can be created using the <TT>%immutable</TT> and <TT> +%mutable</TT> <A href="#Customization_feature_flags">feature flag</A> + directive. For example, we probably wouldn't want the user to change + the length of a list so we could do the following to make the value + available, but read-only.</P> +<DIV class="code"> +<PRE> +class List { +public: +... +%immutable; + int length; +%mutable; +... +}; +</PRE> +</DIV> +<P> Alternatively, you can specify an immutable member in advance like + this:</P> +<DIV class="code"> +<PRE> +%immutable List::length; +... +class List { + ... + int length; // Immutable by above directive + ... +}; +</PRE> +</DIV> +<P> Similarly, all data attributes declared as <TT>const</TT> are + wrapped as read-only members.</P> +<P> There are some subtle issues when wrapping data members that are + themselves classes. For instance, if you had another class like this,</P> +<DIV class="code"> +<PRE> +class Foo { +public: + List items; + ... +</PRE> +</DIV> +<P> then the low-level accessor to the <TT>items</TT> member actually + uses pointers. For example:</P> +<DIV class="code"> +<PRE> +List *Foo_items_get(Foo *self) { + return &self->items; +} +void Foo_items_set(Foo *self, List *value) { + self->items = *value; +} +</PRE> +</DIV> +<P> More information about this can be found in the SWIG Basics chapter, + <A href="#SWIG_structure_data_members">Structure data members</A> + section.</P> +<P> The wrapper code to generate the accessors for classes comes from + the pointer typemaps. This can be somewhat unnatural for some types. + For example, a user would expect the STL std::string class member + variables to be wrapped as a string in the target language, rather than + a pointer to this class. The const reference typemaps offer this type + of marshalling, so there is a feature to tell SWIG to use the const + reference typemaps rather than the pointer typemaps. It is the <TT> +%naturalvar</TT> directive and is used as follows:</P> +<DIV class="code"> +<PRE> +// All List variables will use const List& typemaps +%naturalvar List; + +// Only Foo::myList will use const List& typemaps +%naturalvar Foo::myList; +struct Foo { + List myList; +}; + +// All variables will use const reference typemaps +%naturalvar; +</PRE> +</DIV> +<P> The observant reader will notice that <TT>%naturalvar</TT> works + like any other <A href="#Customization_feature_flags">feature flag</A> + directive, except it can also be attached to class types. The first of + the example usages above show <TT>%naturalvar</TT> attaching to the <TT> +List</TT> class. Effectively this feature changes the way accessors are + generated to the following:</P> +<DIV class="code"> +<PRE> +const List &Foo_items_get(Foo *self) { + return self->items; +} +void Foo_items_set(Foo *self, const List &value) { + self->items = value; +} +</PRE> +</DIV> +<P> In fact it is generally a good idea to use this feature globally as + the reference typemaps have extra NULL checking compared to the pointer + typemaps. A pointer can be NULL, whereas a reference cannot, so the + extra checking ensures that the target language user does not pass in a + value that translates to a NULL pointer and thereby preventing any + potential NULL pointer dereferences. The <TT>%naturalvar</TT> feature + will apply to global variables in addition to member variables in some + language modules, eg C# and Java.</P> +<P> Other alternatives for turning this feature on globally are to use + the <TT>swig -naturalvar</TT> commandline option or the module mode + option, <TT>%module(naturalvar=1)</TT></P> +<P><B> Compatibility note:</B> The <TT>%naturalvar</TT> feature was + introduced in SWIG-1.3.28, prior to which it was necessary to manually + apply the const reference typemaps, eg <TT>%apply const std::string & { + std::string * }</TT>, but this example would also apply the typemaps to + methods taking a <TT>std::string</TT> pointer.</P> +<P><B> Compatibility note:</B> Read-only access used to be controlled by + a pair of directives <TT>%readonly</TT> and <TT>%readwrite</TT>. + Although these directives still work, they generate a warning message. + Simply change the directives to <TT>%immutable;</TT> and <TT>%mutable;</TT> + to silence the warning. Don't forget the extra semicolon!</P> +<P><B> Compatibility note:</B> Prior to SWIG-1.3.12, all members of + unknown type were wrapped into accessor functions using pointers. For + example, if you had a structure like this</P> +<DIV class="code"> +<PRE> +struct Foo { + size_t len; +}; +</PRE> +</DIV> +<P> and nothing was known about <TT>size_t</TT>, then accessors would be + written to work with <TT>size_t *</TT>. Starting in SWIG-1.3.12, this + behavior has been modified. Specifically, pointers will<EM> only</EM> + be used if SWIG knows that a datatype corresponds to a structure or + class. Therefore, the above code would be wrapped into accessors + involving <TT>size_t</TT>. This change is subtle, but it smooths over a + few problems related to structure wrapping and some of SWIG's + customization features.</P> +<H2><A name="SWIGPlus_default_args"></A>6.7 Default arguments</H2> +<P> SWIG will wrap all types of functions that have default arguments. + For example member functions:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + void bar(int x, int y = 3, int z = 4); +}; +</PRE> +</DIV> +<P> SWIG handles default arguments by generating an extra overloaded + method for each defaulted argument. SWIG is effectively handling + methods with default arguments as if it was wrapping the equivalent + overloaded methods. Thus for the example above, it is as if we had + instead given the following to SWIG:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + void bar(int x, int y, int z); + void bar(int x, int y); + void bar(int x); +}; +</PRE> +</DIV> +<P> The wrappers produced are exactly the same as if the above code was + instead fed into SWIG. Details of this are covered later in the <A href="#SWIGPlus_overloaded_methods"> +Wrapping Overloaded Functions and Methods</A> section. This approach + allows SWIG to wrap all possible default arguments, but can be verbose. + For example if a method has ten default arguments, then eleven wrapper + methods are generated.</P> +<P> Please see the <A href="#Customization_features_default_args"> +Features and default arguments</A> section for more information on using + <TT>%feature</TT> with functions with default arguments. The <A href="#ambiguity_resolution_renaming"> +Ambiguity resolution and renaming</A> section also deals with using <TT> +%rename</TT> and <TT>%ignore</TT> on methods with default arguments. If + you are writing your own typemaps for types used in methods with + default arguments, you may also need to write a <TT>typecheck</TT> + typemap. See the <A href="#Typemaps_overloading">Typemaps and + overloading</A> section for details or otherwise use the <TT> +compactdefaultargs</TT> feature flag as mentioned below.</P> +<P><B> Compatibility note:</B> Versions of SWIG prior to SWIG-1.3.23 + wrapped default arguments slightly differently. Instead a single + wrapper method was generated and the default values were copied into + the C++ wrappers so that the method being wrapped was then called with + all the arguments specified. If the size of the wrappers are a concern + then this approach to wrapping methods with default arguments can be + re-activated by using the <TT>compactdefaultargs</TT> <A href="#Customization_feature_flags"> +feature flag</A>.</P> +<DIV class="code"> +<PRE> +%feature("compactdefaultargs") Foo::bar; +class Foo { +public: + void bar(int x, int y = 3, int z = 4); +}; +</PRE> +</DIV> +<P> This is great for reducing the size of the wrappers, but the caveat + is it does not work for the statically typed languages, such as C# and + Java, which don't have optional arguments in the language, Another + restriction of this feature is that it cannot handle default arguments + that are not public. The following example illustrates this:</P> +<DIV class="code"> +<PRE> +class Foo { +private: + static const int spam; +public: + void bar(int x, int y = spam); // Won't work with %feature("compactdefaultargs") - + // private default value +}; +</PRE> +</DIV> +<P> This produces uncompileable wrapper code because default values in + C++ are evaluated in the same scope as the member function whereas SWIG + evaluates them in the scope of a wrapper function (meaning that the + values have to be public).</P> +<P> This feature is automatically turned on when wrapping <A href="#SWIG_default_args"> +C code with default arguments</A> and whenever keyword arguments + (kwargs) are specified for either C or C++ code. Keyword arguments are + a language feature of some scripting languages, for example Ruby and + Python. SWIG is unable to support kwargs when wrapping overloaded + methods, so the default approach cannot be used.</P> +<H2><A name="SWIGPlus_nn15"></A>6.8 Protection</H2> +<P> SWIG wraps class members that are public following the C++ + conventions, i.e., by explicit public declaration or by the use of the <TT> +using</TT> directive. In general, anything specified in a private or + protected section will be ignored, although the internal code generator + sometimes looks at the contents of the private and protected sections + so that it can properly generate code for default constructors and + destructors. Directors could also modify the way non-public virtual + protected members are treated.</P> +<P> By default, members of a class definition are assumed to be private + until you explicitly give a `<TT>public:</TT>' declaration (This is the + same convention used by C++).</P> +<H2><A name="SWIGPlus_nn16"></A>6.9 Enums and constants</H2> +<P> Enumerations and constants are handled differently by the different + language modules and are described in detail in the appropriate + language chapter. However, many languages map enums and constants in a + class definition into constants with the classname as a prefix. For + example :</P> +<DIV class="code"> +<PRE> +class Swig { +public: + enum {ALE, LAGER, PORTER, STOUT}; +}; + +</PRE> +</DIV> +<P> Generates the following set of constants in the target scripting + language :</P> +<DIV class="targetlang"> +<PRE> +Swig_ALE = Swig::ALE +Swig_LAGER = Swig::LAGER +Swig_PORTER = Swig::PORTER +Swig_STOUT = Swig::STOUT + +</PRE> +</DIV> +<P> Members declared as <TT>const</TT> are wrapped as read-only members + and do not create constants.</P> +<H2><A name="SWIGPlus_nn17"></A>6.10 Friends</H2> +<P> Friend declarations are recognised by SWIG. For example, if you have + this code:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + ... + friend void blah(Foo *f); + ... +}; +</PRE> +</DIV> +<P> then the <TT>friend</TT> declaration does result in a wrapper code + equivalent to one generated for the following declaration</P> +<DIV class="code"> +<PRE> +class Foo { +public: + ... +}; + +void blah(Foo *f); +</PRE> +</DIV> +<P> A friend declaration, as in C++, is understood to be in the same + scope where the class is declared, hence, you can have</P> +<DIV class="code"> +<PRE> + +%ignore bar::blah(Foo *f); + +namespace bar { + + class Foo { + public: + ... + friend void blah(Foo *f); + ... + }; +} +</PRE> +</DIV> +<P> and a wrapper for the method 'blah' will not be generated.</P> +<H2><A name="SWIGPlus_nn18"></A>6.11 References and pointers</H2> +<P> C++ references are supported, but SWIG transforms them back into + pointers. For example, a declaration like this :</P> +<DIV class="code"> +<PRE> +class Foo { +public: + double bar(double &a); +} +</PRE> +</DIV> +<P> has a low-level accessor</P> +<DIV class="code"> +<PRE> +double Foo_bar(Foo *obj, double *a) { + obj->bar(*a); +} +</PRE> +</DIV> +<P> As a special case, most language modules pass <TT>const</TT> + references to primitive datatypes (<TT>int</TT>, <TT>short</TT>, <TT> +float</TT>, etc.) by value instead of pointers. For example, if you have + a function like this,</P> +<DIV class="code"> +<PRE> +void foo(const int &x); +</PRE> +</DIV> +<P> it is called from a script as follows:</P> +<DIV class="targetlang"> +<PRE> +foo(3) # Notice pass by value +</PRE> +</DIV> +<P> Functions that return a reference are remapped to return a pointer + instead. For example:</P> +<DIV class="code"> +<PRE> +class Bar { +public: + Foo &spam(); +}; +</PRE> +</DIV> +<P> Generates an accessor like this:</P> +<DIV class="code"> +<PRE> +Foo *Bar_spam(Bar *obj) { + Foo &result = obj->spam(); + return &result; +} +</PRE> +</DIV> +<P> However, functions that return <TT>const</TT> references to + primitive datatypes (<TT>int</TT>, <TT>short</TT>, etc.) normally + return the result as a value rather than a pointer. For example, a + function like this,</P> +<DIV class="code"> +<PRE> +const int &bar(); +</PRE> +</DIV> +<P> will return integers such as 37 or 42 in the target scripting + language rather than a pointer to an integer.</P> +<P> Don't return references to objects allocated as local variables on + the stack. SWIG doesn't make a copy of the objects so this will + probably cause your program to crash.</P> +<P><B> Note:</B> The special treatment for references to primitive + datatypes is necessary to provide more seamless integration with more + advanced C++ wrapping applications---especially related to templates + and the STL. This was first added in SWIG-1.3.12.</P> +<H2><A name="SWIGPlus_nn19"></A>6.12 Pass and return by value</H2> +<P> Occasionally, a C++ program will pass and return class objects by + value. For example, a function like this might appear:</P> +<DIV class="code"> +<PRE> +Vector cross_product(Vector a, Vector b); +</PRE> +</DIV> +<P> If no information is supplied about <TT>Vector</TT>, SWIG creates a + wrapper function similar to the following:</P> +<DIV class="code"> +<PRE> +Vector *wrap_cross_product(Vector *a, Vector *b) { + Vector x = *a; + Vector y = *b; + Vector r = cross_product(x,y); + return new Vector(r); +}</PRE> +</DIV> +<P> In order for the wrapper code to compile, <TT>Vector</TT> must + define a copy constructor and a default constructor.</P> +<P> If <TT>Vector</TT> is defined as a class in the interface, but it + does not support a default constructor, SWIG changes the wrapper code + by encapsulating the arguments inside a special C++ template wrapper + class, through a process called the "Fulton Transform". This produces a + wrapper that looks like this:</P> +<DIV class="code"> +<PRE> +Vector cross_product(Vector *a, Vector *b) { + SwigValueWrapper<Vector> x = *a; + SwigValueWrapper<Vector> y = *b; + SwigValueWrapper<Vector> r = cross_product(x,y); + return new Vector(r); +} +</PRE> +</DIV> +<P> This transformation is a little sneaky, but it provides support for + pass-by-value even when a class does not provide a default constructor + and it makes it possible to properly support a number of SWIG's + customization options. The definition of <TT>SwigValueWrapper</TT> can + be found by reading the SWIG wrapper code. This class is really nothing + more than a thin wrapper around a pointer.</P> +<P> Although SWIG usually detects the classes to which the Fulton + Transform should be applied, in some situations it's necessary to + override it. That's done with <TT>%feature("valuewrapper")</TT> to + ensure it is used and <TT>%feature("novaluewrapper")</TT> to ensure it + is not used:</P> +<DIV class="code"> +<PRE> +%feature("novaluewrapper") A; +class A; + +%feature("valuewrapper") B; +struct B { + B(); + // .... +}; +</PRE> +</DIV> +<P> It is well worth considering turning this feature on for classes + that do have a default constructor. It will remove a redundant + constructor call at the point of the variable declaration in the + wrapper, so will generate notably better performance for large objects + or for classes with expensive construction. Alternatively consider + returning a reference or a pointer.</P> +<P><B> Note:</B> this transformation has no effect on typemaps or any + other part of SWIG---it should be transparent except that you may see + this code when reading the SWIG output file.</P> +<P><B> Note:</B> This template transformation is new in SWIG-1.3.11 and + may be refined in future SWIG releases. In practice, it is only + absolutely necessary to do this for classes that don't define a default + constructor.</P> +<P><B> Note:</B> The use of this template only occurs when objects are + passed or returned by value. It is not used for C++ pointers or + references.</P> +<H2><A name="SWIGPlus_nn20"></A>6.13 Inheritance</H2> +<P> SWIG supports C++ inheritance of classes and allows both single and + multiple inheritance, as limited or allowed by the target language. The + SWIG type-checker knows about the relationship between base and derived + classes and allows pointers to any object of a derived class to be used + in functions of a base class. The type-checker properly casts pointer + values and is safe to use with multiple inheritance.</P> +<P> SWIG treats private or protected inheritance as close to the C++ + spirit, and target language capabilities, as possible. In most cases, + this means that SWIG will parse the non-public inheritance + declarations, but that will have no effect in the generated code, + besides the implicit policies derived for constructor and destructors.</P> +<P> The following example shows how SWIG handles inheritance. For + clarity, the full C++ code has been omitted.</P> +<DIV class="code"> +<PRE> +// shapes.i +%module shapes +%{ +#include "shapes.h" +%} + +class Shape { +public: + double x,y; + virtual double area() = 0; + virtual double perimeter() = 0; + void set_location(double x, double y); +}; +class Circle : public Shape { +public: + Circle(double radius); + ~Circle(); + double area(); + double perimeter(); +}; +class Square : public Shape { +public: + Square(double size); + ~Square(); + double area(); + double perimeter(); +} +</PRE> +</DIV> +<P> When wrapped into Python, we can perform the following operations + (shown using the low level Python accessors):</P> +<DIV class="targetlang"> +<PRE> +$ python +>>> import shapes +>>> circle = shapes.new_Circle(7) +>>> square = shapes.new_Square(10) +>>> print shapes.Circle_area(circle) +153.93804004599999757 +>>> print shapes.Shape_area(circle) +153.93804004599999757 +>>> print shapes.Shape_area(square) +100.00000000000000000 +>>> shapes.Shape_set_location(square,2,-3) +>>> print shapes.Shape_perimeter(square) +40.00000000000000000 +>>> +</PRE> +</DIV> +<P> In this example, Circle and Square objects have been created. Member + functions can be invoked on each object by making calls to <TT> +Circle_area</TT>, <TT>Square_area</TT>, and so on. However, the same + results can be accomplished by simply using the <TT>Shape_area</TT> + function on either object.</P> +<P> One important point concerning inheritance is that the low-level + accessor functions are only generated for classes in which they are + actually declared. For instance, in the above example, the method <TT> +set_location()</TT> is only accessible as <TT>Shape_set_location()</TT> + and not as <TT>Circle_set_location()</TT> or <TT>Square_set_location()</TT> +. Of course, the <TT>Shape_set_location()</TT> function will accept any + kind of object derived from Shape. Similarly, accessor functions for + the attributes <TT>x</TT> and <TT>y</TT> are generated as <TT> +Shape_x_get()</TT>, <TT>Shape_x_set()</TT>, <TT>Shape_y_get()</TT>, and <TT> +Shape_y_set()</TT>. Functions such as <TT>Circle_x_get()</TT> are not + available--instead you should use <TT>Shape_x_get()</TT>.</P> +<P> Note that there is a one to one correlation between the low-level + accessor functions and the proxy methods and therefore there is also a + one to one correlation between the C++ class methods and the generated + proxy class methods.</P> +<P><B> Note:</B> For the best results, SWIG requires all base classes to + be defined in an interface. Otherwise, you may get a warning message + like this:</P> +<DIV class="shell"> +<PRE> +example.i:18: Warning(401): Nothing known about base class 'Foo'. Ignored. +</PRE> +</DIV> +<P> If any base class is undefined, SWIG still generates correct type + relationships. For instance, a function accepting a <TT>Foo *</TT> will + accept any object derived from <TT>Foo</TT> regardless of whether or + not SWIG actually wrapped the <TT>Foo</TT> class. If you really don't + want to generate wrappers for the base class, but you want to silence + the warning, you might consider using the <TT>%import</TT> directive to + include the file that defines <TT>Foo</TT>. <TT>%import</TT> simply + gathers type information, but doesn't generate wrappers. Alternatively, + you could just define <TT>Foo</TT> as an empty class in the SWIG + interface or use <A href="#Warnings_suppression">warning suppression</A> +.</P> +<P><B> Note:</B> <TT>typedef</TT>-names<EM> can</EM> be used as base + classes. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +... +}; + +typedef Foo FooObj; +class Bar : public FooObj { // Ok. Base class is Foo +... +}; +</PRE> +</DIV> +<P> Similarly, <TT>typedef</TT> allows unnamed structures to be used as + base classes. For example:</P> +<DIV class="code"> +<PRE> +typedef struct { + ... +} Foo; + +class Bar : public Foo { // Ok. +... +}; +</PRE> +</DIV> +<P><B> Compatibility Note:</B> Starting in version 1.3.7, SWIG only + generates low-level accessor wrappers for the declarations that are + actually defined in each class. This differs from SWIG1.1 which used to + inherit all of the declarations defined in base classes and regenerate + specialized accessor functions such as <TT>Circle_x_get()</TT>, <TT> +Square_x_get()</TT>, <TT>Circle_set_location()</TT>, and <TT> +Square_set_location()</TT>. This behavior resulted in huge amounts of + replicated code for large class hierarchies and made it awkward to + build applications spread across multiple modules (since accessor + functions are duplicated in every single module). It is also + unnecessary to have such wrappers when advanced features like proxy + classes are used.<B> Note:</B> Further optimizations are enabled when + using the <TT>-fvirtual</TT> option, which avoids the regenerating of + wrapper functions for virtual members that are already defined in a + base class.</P> +<H2><A name="SWIGPlus_nn21"></A>6.14 A brief discussion of multiple + inheritance, pointers, and type checking</H2> +<P> When a target scripting language refers to a C++ object, it normally + uses a tagged pointer object that contains both the value of the + pointer and a type string. For example, in Tcl, a C++ pointer might be + encoded as a string like this:</P> +<DIV class="diagram"> +<PRE> +_808fea88_p_Circle +</PRE> +</DIV> +<P> A somewhat common question is whether or not the type-tag could be + safely removed from the pointer. For instance, to get better + performance, could you strip all type tags and just use simple integers + instead?</P> +<P> In general, the answer to this question is no. In the wrappers, all + pointers are converted into a common data representation in the target + language. Typically this is the equivalent of casting a pointer to <TT> +void *</TT>. This means that any C++ type information associated with + the pointer is lost in the conversion.</P> +<P> The problem with losing type information is that it is needed to + properly support many advanced C++ features--especially multiple + inheritance. For example, suppose you had code like this:</P> +<DIV class="code"> +<PRE> +class A { +public: + int x; +}; + +class B { +public: + int y; +}; + +class C : public A, public B { +}; + +int A_function(A *a) { + return a->x; +} + +int B_function(B *b) { + return b->y; +} +</PRE> +</DIV> +<P> Now, consider the following code that uses <TT>void *</TT>.</P> +<DIV class="code"> +<PRE> +C *c = new C(); +void *p = (void *) c; +... +int x = A_function((A *) p); +int y = B_function((B *) p); +</PRE> +</DIV> +<P> In this code, both <TT>A_function()</TT> and <TT>B_function()</TT> + may legally accept an object of type <TT>C *</TT> (via inheritance). + However, one of the functions will always return the wrong result when + used as shown. The reason for this is that even though <TT>p</TT> + points to an object of type <TT>C</TT>, the casting operation doesn't + work like you would expect. Internally, this has to do with the data + representation of <TT>C</TT>. With multiple inheritance, the data from + each base class is stacked together. For example:</P> +<DIV class="diagram"> +<PRE> + ------------ <--- (C *), (A *) + | A | + |------------| <--- (B *) + | B | + ------------ +</PRE> +</DIV> +<P> Because of this stacking, a pointer of type <TT>C *</TT> may change + value when it is converted to a <TT>A *</TT> or <TT>B *</TT>. However, + this adjustment does<EM> not</EM> occur if you are converting from a <TT> +void *</TT>.</P> +<P> The use of type tags marks all pointers with the real type of the + underlying object. This extra information is then used by SWIG + generated wrappers to correctly cast pointer values under inheritance + (avoiding the above problem).</P> +<P> Some of the language modules are able to solve the problem by + storing multiple instances of the pointer, for example, <TT>A *</TT>, + in the A proxy class as well as <TT>C *</TT> in the C proxy class. The + correct cast can then be made by choosing the correct <TT>void *</TT> + pointer to use and is guaranteed to work as the cast to a void pointer + and back to the same type does not lose any type information:</P> +<DIV class="code"> +<PRE> +C *c = new C(); +void *p = (void *) c; +void *pA = (void *) c; +void *pB = (void *) c; +... +int x = A_function((A *) pA); +int y = B_function((B *) pB); +</PRE> +</DIV> +<P> In practice, the pointer is held as an integral number in the target + language proxy class.</P> +<H2><A name="SWIGPlus_overloaded_methods"></A>6.15 Wrapping Overloaded + Functions and Methods</H2> +<P> In many language modules, SWIG provides partial support for + overloaded functions, methods, and constructors. For example, if you + supply SWIG with overloaded functions like this:</P> +<DIV class="code"> +<PRE> +void foo(int x) { + printf("x is %d\n", x); +} +void foo(char *x) { + printf("x is '%s'\n", x); +} +</PRE> +</DIV> +<P> The function is used in a completely natural way. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> foo(3) +x is 3 +>>> foo("hello") +x is 'hello' +>>> +</PRE> +</DIV> +<P> Overloading works in a similar manner for methods and constructors. + For example if you have this code,</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + Foo(const Foo &); // Copy constructor + void bar(int x); + void bar(char *s, int y); +}; +</PRE> +</DIV> +<P> it might be used like this</P> +<DIV class="targetlang"> +<PRE> +>>> f = Foo() # Create a Foo +>>> f.bar(3) +>>> g = Foo(f) # Copy Foo +>>> f.bar("hello",2) +</PRE> +</DIV> +<H3><A name="SWIGPlus_nn24"></A>6.15.1 Dispatch function generation</H3> +<P> The implementation of overloaded functions and methods is somewhat + complicated due to the dynamic nature of scripting languages. Unlike + C++, which binds overloaded methods at compile time, SWIG must + determine the proper function as a runtime check for scripting language + targets. This check is further complicated by the typeless nature of + certain scripting languages. For instance, in Tcl, all types are simply + strings. Therefore, if you have two overloaded functions like this,</P> +<DIV class="code"> +<PRE> +void foo(char *x); +void foo(int x); +</PRE> +</DIV> +<P> the order in which the arguments are checked plays a rather critical + role.</P> +<P> For statically typed languages, SWIG uses the language's method + overloading mechanism. To implement overloading for the scripting + languages, SWIG generates a dispatch function that checks the number of + passed arguments and their types. To create this function, SWIG first + examines all of the overloaded methods and ranks them according to the + following rules:</P> +<OL> +<LI><B>Number of required arguments.</B> Methods are sorted by + increasing number of required arguments.</LI> +<LI> +<P><B>Argument type precedence.</B> All C++ datatypes are assigned a + numeric type precedence value (which is determined by the language + module).</P> +<DIV class="diagram"> +<PRE> +Type Precedence +---------------- ---------- +TYPE * 0 (High) +void * 20 +Integers 40 +Floating point 60 +char 80 +Strings 100 (Low) +</PRE> +</DIV> +<P> Using these precedence values, overloaded methods with the same + number of required arguments are sorted in increased order of + precedence values.</P> +</LI> +</OL> +<P> This may sound very confusing, but an example will help. Consider + the following collection of overloaded methods:</P> +<DIV class="code"> +<PRE> +void foo(double); +void foo(int); +void foo(Bar *); +void foo(); +void foo(int x, int y, int z, int w); +void foo(int x, int y, int z = 3); +void foo(double x, double y); +void foo(double x, Bar *z); +</PRE> +</DIV> +<P> The first rule simply ranks the functions by required argument + count. This would produce the following list:</P> +<DIV class="diagram"> +<PRE> +rank +----- +[0] foo() +[1] foo(double); +[2] foo(int); +[3] foo(Bar *); +[4] foo(int x, int y, int z = 3); +[5] foo(double x, double y) +[6] foo(double x, Bar *z) +[7] foo(int x, int y, int z, int w); +</PRE> +</DIV> +<P> The second rule, simply refines the ranking by looking at argument + type precedence values.</P> +<DIV class="diagram"> +<PRE> +rank +----- +[0] foo() +[1] foo(Bar *); +[2] foo(int); +[3] foo(double); +[4] foo(int x, int y, int z = 3); +[5] foo(double x, Bar *z) +[6] foo(double x, double y) +[7] foo(int x, int y, int z, int w); +</PRE> +</DIV> +<P> Finally, to generate the dispatch function, the arguments passed to + an overloaded method are simply checked in the same order as they + appear in this ranking.</P> +<P> If you're still confused, don't worry about it---SWIG is probably + doing the right thing.</P> +<H3><A name="SWIGPlus_nn25"></A>6.15.2 Ambiguity in Overloading</H3> +<P> Regrettably, SWIG is not able to support every possible use of valid + C++ overloading. Consider the following example:</P> +<DIV class="code"> +<PRE> +void foo(int x); +void foo(long x); +</PRE> +</DIV> +<P> In C++, this is perfectly legal. However, in a scripting language, + there is generally only one kind of integer object. Therefore, which + one of these functions do you pick? Clearly, there is no way to truly + make a distinction just by looking at the value of the integer itself (<TT> +int</TT> and <TT>long</TT> may even be the same precision). Therefore, + when SWIG encounters this situation, it may generate a warning message + like this for scripting languages:</P> +<DIV class="shell"> +<PRE> +example.i:4: Warning(509): Overloaded foo(long) is shadowed by foo(int) at example.i:3. +</PRE> +</DIV> +<P> or for statically typed languages like Java:</P> +<DIV class="shell"> +<PRE> +example.i:4: Warning(516): Overloaded method foo(long) ignored. Method foo(int) +at example.i:3 used. +</PRE> +</DIV> +<P> This means that the second overloaded function will be inaccessible + from a scripting interface or the method won't be wrapped at all. This + is done as SWIG does not know how to disambiguate it from an earlier + method.</P> +<P> Ambiguity problems are known to arise in the following situations:</P> +<UL> +<LI>Integer conversions. Datatypes such as <TT>int</TT>, <TT>long</TT>, + and <TT>short</TT> cannot be disambiguated in some languages. Shown + above.</LI> +<LI>Floating point conversion. <TT>float</TT> and <TT>double</TT> can + not be disambiguated in some languages.</LI> +<LI>Pointers and references. For example, <TT>Foo *</TT> and <TT>Foo &</TT> +.</LI> +<LI>Pointers and arrays. For example, <TT>Foo *</TT> and <TT>Foo [4]</TT> +.</LI> +<LI>Pointers and instances. For example, <TT>Foo</TT> and <TT>Foo *</TT> +. Note: SWIG converts all instances to pointers.</LI> +<LI>Qualifiers. For example, <TT>const Foo *</TT> and <TT>Foo *</TT>.</LI> +<LI>Default vs. non default arguments. For example, <TT>foo(int a, int + b)</TT> and <TT>foo(int a, int b = 3)</TT>.</LI> +</UL> +<P> When an ambiguity arises, methods are checked in the same order as + they appear in the interface file. Therefore, earlier methods will + shadow methods that appear later.</P> +<P> When wrapping an overloaded function, there is a chance that you + will get an error message like this:</P> +<DIV class="shell"> +<PRE> +example.i:3: Warning(467): Overloaded foo(int) not supported (no type checking +rule for 'int'). +</PRE> +</DIV> +<P> This error means that the target language module supports + overloading, but for some reason there is no type-checking rule that + can be used to generate a working dispatch function. The resulting + behavior is then undefined. You should report this as a bug to the <A href="http://www.swig.org/bugs.html"> +SWIG bug tracking database</A>.</P> +<P> If you get an error message such as the following,</P> +<DIV class="shell"> +<PRE> +foo.i:6. Overloaded declaration ignored. Spam::foo(double ) +foo.i:5. Previous declaration is Spam::foo(int ) +foo.i:7. Overloaded declaration ignored. Spam::foo(Bar *,Spam *,int ) +foo.i:5. Previous declaration is Spam::foo(int ) +</PRE> +</DIV> +<P> it means that the target language module has not yet implemented + support for overloaded functions and methods. The only way to fix the + problem is to read the next section.</P> +<H3><A name="ambiguity_resolution_renaming"></A>6.15.3 Ambiguity + resolution and renaming</H3> +<P> If an ambiguity in overload resolution occurs or if a module doesn't + allow overloading, there are a few strategies for dealing with the + problem. First, you can tell SWIG to ignore one of the methods. This is + easy---simply use the <TT>%ignore</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%ignore foo(long); + +void foo(int); +void foo(long); // Ignored. Oh well. +</PRE> +</DIV> +<P> The other alternative is to rename one of the methods. This can be + done using <TT>%rename</TT>. For example:</P> +<DIV class="code"> +<PRE> +%rename("foo_short") foo(short); +%rename(foo_long) foo(long); + +void foo(int); +void foo(short); // Accessed as foo_short() +void foo(long); // Accessed as foo_long() +</PRE> +</DIV> +<P> Note that the quotes around the new name are optional, however, + should the new name be a C/C++ keyword they would be essential in order + to avoid a parsing error. The <TT>%ignore</TT> and <TT>%rename</TT> + directives are both rather powerful in their ability to match + declarations. When used in their simple form, they apply to both global + functions and methods. For example:</P> +<DIV class="code"> +<PRE> +/* Forward renaming declarations */ +%rename(foo_i) foo(int); +%rename(foo_d) foo(double); +... +void foo(int); // Becomes 'foo_i' +void foo(char *c); // Stays 'foo' (not renamed) + +class Spam { +public: + void foo(int); // Becomes 'foo_i' + void foo(double); // Becomes 'foo_d' + ... +}; +</PRE> +</DIV> +<P> If you only want the renaming to apply to a certain scope, the C++ + scope resolution operator (::) can be used. For example:</P> +<DIV class="code"> +<PRE> +%rename(foo_i) ::foo(int); // Only rename foo(int) in the global scope. + // (will not rename class members) + +%rename(foo_i) Spam::foo(int); // Only rename foo(int) in class Spam +</PRE> +</DIV> +<P> When a renaming operator is applied to a class as in <TT> +Spam::foo(int)</TT>, it is applied to that class and all derived + classes. This can be used to apply a consistent renaming across an + entire class hierarchy with only a few declarations. For example:</P> +<DIV class="code"> +<PRE> +%rename(foo_i) Spam::foo(int); +%rename(foo_d) Spam::foo(double); + +class Spam { +public: + virtual void foo(int); // Renamed to foo_i + virtual void foo(double); // Renamed to foo_d + ... +}; + +class Bar : public Spam { +public: + virtual void foo(int); // Renamed to foo_i + virtual void foo(double); // Renamed to foo_d +... +}; + +class Grok : public Bar { +public: + virtual void foo(int); // Renamed to foo_i + virtual void foo(double); // Renamed to foo_d +... +}; +</PRE> +</DIV> +<P> It is also possible to include <TT>%rename</TT> specifications in + the class definition itself. For example:</P> +<DIV class="code"> +<PRE> +class Spam { + %rename(foo_i) foo(int); + %rename(foo_d) foo(double); +public: + virtual void foo(int); // Renamed to foo_i + virtual void foo(double); // Renamed to foo_d + ... +}; + +class Bar : public Spam { +public: + virtual void foo(int); // Renamed to foo_i + virtual void foo(double); // Renamed to foo_d +... +}; +</PRE> +</DIV> +<P> In this case, the <TT>%rename</TT> directives still get applied + across the entire inheritance hierarchy, but it's no longer necessary + to explicitly specify the class prefix <TT>Spam::</TT>.</P> +<P> A special form of <TT>%rename</TT> can be used to apply a renaming + just to class members (of all classes):</P> +<DIV class="code"> +<PRE> +%rename(foo_i) *::foo(int); // Only rename foo(int) if it appears in a class. +</PRE> +</DIV> +<P> Note: the <TT>*::</TT> syntax is non-standard C++, but the '*' is + meant to be a wildcard that matches any class name (we couldn't think + of a better alternative so if you have a better idea, send email to the + <A href="http://www.swig.org/mail.html">swig-devel mailing list</A>.</P> +<P> Although this discussion has primarily focused on <TT>%rename</TT> + all of the same rules also apply to <TT>%ignore</TT>. For example:</P> +<DIV class="code"> +<PRE> +%ignore foo(double); // Ignore all foo(double) +%ignore Spam::foo; // Ignore foo in class Spam +%ignore Spam::foo(double); // Ignore foo(double) in class Spam +%ignore *::foo(double); // Ignore foo(double) in all classes +</PRE> +</DIV> +<P> When applied to a base class, <TT>%ignore</TT> forces all + definitions in derived classes to disappear. For example, <TT>%ignore + Spam::foo(double)</TT> will eliminate <TT>foo(double)</TT> in <TT>Spam</TT> + and all classes derived from <TT>Spam</TT>.</P> +<P><B> Notes on %rename and %ignore:</B></P> +<UL> +<LI> +<P>Since, the <TT>%rename</TT> declaration is used to declare a renaming + in advance, it can be placed at the start of an interface file. This + makes it possible to apply a consistent name resolution without having + to modify header files. For example:</P> +<DIV class="code"> +<PRE> +%module foo + +/* Rename these overloaded functions */ +%rename(foo_i) foo(int); +%rename(foo_d) foo(double); + +%include "header.h" +</PRE> +</DIV></LI> +<LI> +<P>The scope qualifier (::) can also be used on simple names. For + example:</P> +<DIV class="code"> +<PRE> +%rename(bar) ::foo; // Rename foo to bar in global scope only +%rename(bar) Spam::foo; // Rename foo to bar in class Spam only +%rename(bar) *::foo; // Rename foo in classes only +</PRE> +</DIV></LI> +<LI> +<P>Name matching tries to find the most specific match that is defined. + A qualified name such as <TT>Spam::foo</TT> always has higher + precedence than an unqualified name <TT>foo</TT>. <TT>Spam::foo</TT> + has higher precedence than <TT>*::foo</TT> and <TT>*::foo</TT> has + higher precedence than <TT>foo</TT>. A parameterized name has higher + precedence than an unparameterized name within the same scope level. + However, an unparameterized name with a scope qualifier has higher + precedence than a parameterized name in global scope (e.g., a renaming + of <TT>Spam::foo</TT> takes precedence over a renaming of <TT>foo(int)</TT> +).</P> +</LI> +<LI> +<P> The order in which <TT>%rename</TT> directives are defined does not + matter as long as they appear before the declarations to be renamed. + Thus, there is no difference between saying:</P> +<DIV class="code"> +<PRE> +%rename(bar) foo; +%rename(foo_i) Spam::foo(int); +%rename(Foo) Spam::foo; +</PRE> +</DIV> +<P> and this</P> +<DIV class="code"> +<PRE> +%rename(Foo) Spam::foo; +%rename(bar) foo; +%rename(foo_i) Spam::foo(int); +</PRE> +</DIV> +<P> (the declarations are not stored in a linked list and order has no + importance). Of course, a repeated <TT>%rename</TT> directive will + change the setting for a previous <TT>%rename</TT> directive if exactly + the same name, scope, and parameters are supplied.</P> +</LI> +<LI>For multiple inheritance where renaming rules are defined for + multiple base classes, the first renaming rule found on a depth-first + traversal of the class hierarchy is used.</LI> +<LI> +<P>The name matching rules strictly follow member qualification rules. + For example, if you have a class like this:</P> +<DIV class="code"> +<PRE> +class Spam { +public: + ... + void bar() const; + ... +}; +</PRE> +</DIV> +<P> the declaration</P> +<DIV class="code"> +<PRE> +%rename(name) Spam::bar(); +</PRE> +</DIV> +<P> will not apply as there is no unqualified member <TT>bar()</TT>. The + following will apply as the qualifier matches correctly:</P> +<DIV class="code"> +<PRE> +%rename(name) Spam::bar() const; +</PRE> +</DIV> +<P> An often overlooked C++ feature is that classes can define two + different overloaded members that differ only in their qualifiers, like + this:</P> +<DIV class="code"> +<PRE> +class Spam { +public: + ... + void bar(); // Unqualified member + void bar() const; // Qualified member + ... +}; +</PRE> +</DIV> +<P> %rename can then be used to target each of the overloaded methods + individually. For example we can give them separate names in the target + language:</P> +<DIV class="code"> +<PRE> +%rename(name1) Spam::bar(); +%rename(name2) Spam::bar() const; +</PRE> +</DIV> +<P> Similarly, if you merely wanted to ignore one of the declarations, + use <TT>%ignore</TT> with the full qualification. For example, the + following directive would tell SWIG to ignore the <TT>const</TT> + version of <TT>bar()</TT> above:</P> +<DIV class="code"> +<PRE> +%ignore Spam::bar() const; // Ignore bar() const, but leave other bar() alone +</PRE> +</DIV></LI> +<LI> +<P> Currently no resolution is performed in order to match function + parameters. This means function parameter types must match exactly. For + example, namespace qualifiers and typedefs will not work. The following + usage of typedefs demonstrates this:<DIV class="code"> +<PRE> +typedef int Integer; + +%rename(foo_i) foo(int); + +class Spam { +public: + void foo(Integer); // Stays 'foo' (not renamed) +}; +class Ham { +public: + void foo(int); // Renamed to foo_i +}; +</PRE> +</DIV></P> +</LI> +<LI> +<P> The name matching rules also use default arguments for finer control + when wrapping methods that have default arguments. Recall that methods + with default arguments are wrapped as if the equivalent overloaded + methods had been parsed (<A href="#SWIGPlus_default_args">Default + arguments</A> section). Let's consider the following example class:</P> +<DIV class="code"> +<PRE> +class Spam { +public: + ... + void bar(int i=-1, double d=0.0); + ... +}; +</PRE> +</DIV> +<P> The following <TT>%rename</TT> will match exactly and apply to all + the target language overloaded methods because the declaration with the + default arguments exactly matches the wrapped method:</P> +<DIV class="code"> +<PRE> +%rename(newbar) Spam::bar(int i=-1, double d=0.0); +</PRE> +</DIV> +<P> The C++ method can then be called from the target language with the + new name no matter how many arguments are specified, for example: <TT> +newbar(2, 2.0)</TT>, <TT>newbar(2)</TT> or <TT>newbar()</TT>. However, + if the <TT>%rename</TT> does not contain the default arguments, it will + only apply to the single equivalent target language overloaded method. + So if instead we have:</P> +<DIV class="code"> +<PRE> +%rename(newbar) Spam::bar(int i, double d); +</PRE> +</DIV> +<P> The C++ method must then be called from the target language with the + new name <TT>newbar(2, 2.0)</TT> when both arguments are supplied or + with the original name as <TT>bar(2)</TT> (one argument) or <TT>bar()</TT> + (no arguments). In fact it is possible to use <TT>%rename</TT> on the + equivalent overloaded methods, to rename all the equivalent overloaded + methods:</P> +<DIV class="code"> +<PRE> +%rename(bar_2args) Spam::bar(int i, double d); +%rename(bar_1arg) Spam::bar(int i); +%rename(bar_default) Spam::bar(); +</PRE> +</DIV> +<P> Similarly, the extra overloaded methods can be selectively ignored + using <TT>%ignore</TT>.</P> +<P><B> Compatibility note:</B> The <TT>%rename</TT> directive introduced + the default argument matching rules in SWIG-1.3.23 at the same time as + the changes to wrapping methods with default arguments was introduced.</P> +</LI> +</UL> +<H3><A name="SWIGPlus_nn27"></A>6.15.4 Comments on overloading</H3> +<P> Support for overloaded methods was first added in SWIG-1.3.14. The + implementation is somewhat unusual when compared to similar tools. For + instance, the order in which declarations appear is largely irrelevant + in SWIG. Furthermore, SWIG does not rely upon trial execution or + exception handling to figure out which method to invoke.</P> +<P> Internally, the overloading mechanism is completely configurable by + the target language module. Therefore, the degree of overloading + support may vary from language to language. As a general rule, + statically typed languages like Java are able to provide more support + than dynamically typed languages like Perl, Python, Ruby, and Tcl.</P> +<H2><A name="SWIGPlus_nn28"></A>6.16 Wrapping overloaded operators</H2> +<P> C++ overloaded operator declarations can be wrapped. For example, + consider a class like this:</P> +<DIV class="code"> +<PRE> +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + double re() const { return rpart; } + double im() const { return ipart; } +}; +</PRE> +</DIV> +<P> When operator declarations appear, they are handled in<EM> exactly</EM> + the same manner as regular methods. However, the names of these methods + are set to strings like "<TT>operator +</TT>" or "<TT>operator -</TT>". + The problem with these names is that they are illegal identifiers in + most scripting languages. For instance, you can't just create a method + called "<TT>operator +</TT>" in Python--there won't be any way to call + it.</P> +<P> Some language modules already know how to automatically handle + certain operators (mapping them into operators in the target language). + However, the underlying implementation of this is really managed in a + very general way using the <TT>%rename</TT> directive. For example, in + Python a declaration similar to this is used:</P> +<DIV class="code"> +<PRE> +%rename(__add__) Complex::operator+; +</PRE> +</DIV> +<P> This binds the + operator to a method called <TT>__add__</TT> (which + is conveniently the same name used to implement the Python + operator). + Internally, the generated wrapper code for a wrapped operator will look + something like this pseudocode:</P> +<DIV class="code"> +<PRE> +_wrap_Complex___add__(args) { + ... get args ... + obj->operator+(args); + ... +} +</PRE> +</DIV> +<P> When used in the target language, it may now be possible to use the + overloaded operator normally. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> a = Complex(3,4) +>>> b = Complex(5,2) +>>> c = a + b # Invokes __add__ method +</PRE> +</DIV> +<P> It is important to realize that there is nothing magical happening + here. The <TT>%rename</TT> directive really only picks a valid method + name. If you wrote this:</P> +<DIV class="code"> +<PRE> +%rename(add) operator+; +</PRE> +</DIV> +<P> The resulting scripting interface might work like this:</P> +<DIV class="targetlang"> +<PRE> +a = Complex(3,4) +b = Complex(5,2) +c = a.add(b) # Call a.operator+(b) +</PRE> +</DIV> +<P> All of the techniques described to deal with overloaded functions + also apply to operators. For example:</P> +<DIV class="code"> +<PRE> +%ignore Complex::operator=; // Ignore = in class Complex +%ignore *::operator=; // Ignore = in all classes +%ignore operator=; // Ignore = everywhere. + +%rename(__sub__) Complex::operator-; +%rename(__neg__) Complex::operator-(); // Unary - +</PRE> +</DIV> +<P> The last part of this example illustrates how multiple definitions + of the <TT>operator-</TT> method might be handled.</P> +<P> Handling operators in this manner is mostly straightforward. + However, there are a few subtle issues to keep in mind:</P> +<UL> +<LI> +<P>In C++, it is fairly common to define different versions of the + operators to account for different types. For example, a class might + also include a friend function like this:</P> +<DIV class="code"> +<PRE> +class Complex { +public: + friend Complex operator+(Complex &, double); +}; +Complex operator+(Complex &, double); +</PRE> +</DIV> +<P> SWIG simply ignores all <TT>friend</TT> declarations. Furthermore, + it doesn't know how to associate the associated <TT>operator+</TT> with + the class (because it's not a member of the class).</P> +<P> It's still possible to make a wrapper for this operator, but you'll + have to handle it like a normal function. For example:</P> +<DIV class="code"> +<PRE> +%rename(add_complex_double) operator+(Complex &, double); +</PRE> +</DIV></LI> +<LI> +<P>Certain operators are ignored by default. For instance, <TT>new</TT> + and <TT>delete</TT> operators are ignored as well as conversion + operators.</P> +</LI> +<LI>The semantics of certain C++ operators may not match those in the + target language.</LI> +</UL> +<H2><A name="SWIGPlus_class_extension"></A>6.17 Class extension</H2> +<P> New methods can be added to a class using the <TT>%extend</TT> + directive. This directive is primarily used in conjunction with proxy + classes to add additional functionality to an existing class. For + example :</P> +<DIV class="code"> +<PRE> +%module vector +%{ +#include "vector.h" +%} + +class Vector { +public: + double x,y,z; + Vector(); + ~Vector(); + ... bunch of C++ methods ... + %extend { + char *__str__() { + static char temp[256]; + sprintf(temp,"[ %g, %g, %g ]", $self->x,$self->y,$self->z); + return &temp[0]; + } + } +}; +</PRE> +</DIV> +<P> This code adds a <TT>__str__</TT> method to our class for producing + a string representation of the object. In Python, such a method would + allow us to print the value of an object using the <TT>print</TT> + command.</P> +<DIV class="targetlang"> +<PRE> +>>> +>>> v = Vector(); +>>> v.x = 3 +>>> v.y = 4 +>>> v.z = 0 +>>> print(v) +[ 3.0, 4.0, 0.0 ] +>>> + +</PRE> +</DIV> +<P> The C++ 'this' pointer is often needed to access member variables, + methods etc. The <TT>$self</TT> special variable should be used + wherever you could use 'this'. The example above demonstrates this for + accessing member variables. Note that the members dereferenced by <TT> +$self</TT> must be public members as the code is ultimately generated + into a global function and so will not have any access to non-public + members. The implicit 'this' pointer that is present in C++ methods is + not present in <TT>%extend</TT> methods. In order to access anything in + the extended class or its base class, an explicit 'this' is required. + The following example shows how one could access base class members:</P> +<DIV class="code"> +<PRE> +struct Base { + virtual void method(int v) { + ... + } + int value; +}; +struct Derived : Base { +}; +%extend Derived { + virtual void method(int v) { + $self->Base::method(v); // akin to this->Base::method(v); + $self->value = v; // akin to this->value = v; + ... + } +} +</PRE> +</DIV> +<P> The <TT>%extend</TT> directive follows all of the same conventions + as its use with C structures. Please refer to the <A href="#SWIG_adding_member_functions"> +Adding member functions to C structures</A> section for further details.</P> +<P><B> Compatibility note:</B> The <TT>%extend</TT> directive is a new + name for the <TT>%addmethods</TT> directive in SWIG1.1. Since <TT> +%addmethods</TT> could be used to extend a structure with more than just + methods, a more suitable directive name has been chosen.</P> +<H2><A name="SWIGPlus_nn30"></A>6.18 Templates</H2> +<P> Template type names may appear anywhere a type is expected in an + interface file. For example:</P> +<DIV class="code"> +<PRE> +void foo(vector<int> *a, int n); +void bar(list<int,100> *x); +</PRE> +</DIV> +<P> There are some restrictions on the use of non-type arguments. Simple + literals are supported, and so are some constant expressions. However, + use of '<' and '>' within a constant expressions currently is not + supported by SWIG ('<=' and '>=' are though). For example:</P> +<DIV class="code"> +<PRE> +void bar(list<int,100> *x); // OK +void bar(list<int,2*50> *x); // OK +void bar(list<int,(2>1 ? 100 : 50)> *x) // Not supported +</PRE> +</DIV> +<P> The type system is smart enough to figure out clever games you might + try to play with <TT>typedef</TT>. For instance, consider this code:</P> +<DIV class="code"> +<PRE> +typedef int Integer; +void foo(vector<int> *x, vector<Integer> *y); +</PRE> +</DIV> +<P> In this case, <TT>vector<Integer></TT> is exactly the same type as <TT> +vector<int></TT>. The wrapper for <TT>foo()</TT> will accept either + variant.</P> +<P> Starting with SWIG-1.3.7, simple C++ template declarations can also + be wrapped. SWIG-1.3.12 greatly expands upon the earlier + implementation. Before discussing this any further, there are a few + things you need to know about template wrapping. First, a bare C++ + template does not define any sort of runnable object-code for which + SWIG can normally create a wrapper. Therefore, in order to wrap a + template, you need to give SWIG information about a particular template + instantiation (e.g., <TT>vector<int></TT>, <TT>array<double></TT>, + etc.). Second, an instantiation name such as <TT>vector<int></TT> is + generally not a valid identifier name in most target languages. Thus, + you will need to give the template instantiation a more suitable name + such as <TT>intvector</TT> when creating a wrapper.</P> +<P> To illustrate, consider the following template definition:</P> +<DIV class="code"> +<PRE> +template<class T> class List { +private: + T *data; + int nitems; + int maxitems; +public: + List(int max) { + data = new T [max]; + nitems = 0; + maxitems = max; + } + ~List() { + delete [] data; + }; + void append(T obj) { + if (nitems < maxitems) { + data[nitems++] = obj; + } + } + int length() { + return nitems; + } + T get(int n) { + return data[n]; + } +}; +</PRE> +</DIV> +<P> By itself, this template declaration is useless--SWIG simply ignores + it because it doesn't know how to generate any code until unless a + definition of <TT>T</TT> is provided.</P> +<P> One way to create wrappers for a specific template instantiation is + to simply provide an expanded version of the class directly like this:</P> +<DIV class="code"> +<PRE> +%rename(intList) List<int>; // Rename to a suitable identifier +class List<int> { +private: + int *data; + int nitems; + int maxitems; +public: + List(int max); + ~List(); + void append(int obj); + int length(); + int get(int n); +}; +</PRE> +</DIV> +<P> The <TT>%rename</TT> directive is needed to give the template class + an appropriate identifier name in the target language (most languages + would not recognize C++ template syntax as a valid class name). The + rest of the code is the same as what would appear in a normal class + definition.</P> +<P> Since manual expansion of templates gets old in a hurry, the <TT> +%template</TT> directive can be used to create instantiations of a + template class. Semantically, <TT>%template</TT> is simply a + shortcut---it expands template code in exactly the same way as shown + above. Here are some examples:</P> +<DIV class="code"> +<PRE> +/* Instantiate a few different versions of the template */ +%template(intList) List<int>; +%template(doubleList) List<double>; +</PRE> +</DIV> +<P> The argument to <TT>%template()</TT> is the name of the + instantiation in the target language. The name you choose should not + conflict with any other declarations in the interface file with one + exception---it is okay for the template name to match that of a typedef + declaration. For example:</P> +<DIV class="code"> +<PRE> +%template(intList) List<int>; +... +typedef List<int> intList; // OK +</PRE> +</DIV> +<P> SWIG can also generate wrappers for function templates using a + similar technique. For example:</P> +<DIV class="code"> +<PRE> +// Function template +template<class T> T max(T a, T b) { return a > b ? a : b; } + +// Make some different versions of this function +%template(maxint) max<int>; +%template(maxdouble) max<double>; +</PRE> +</DIV> +<P> In this case, <TT>maxint</TT> and <TT>maxdouble</TT> become unique + names for specific instantiations of the function.</P> +<P> The number of arguments supplied to <TT>%template</TT> should match + that in the original template definition. Template default arguments + are supported. For example:</P> +<DIV class="code"> +<PRE> +template vector<typename T, int max=100> class vector { +... +}; + +%template(intvec) vector<int>; // OK +%template(vec1000) vector<int,1000>; // OK +</PRE> +</DIV> +<P> The <TT>%template</TT> directive should not be used to wrap the same + template instantiation more than once in the same scope. This will + generate an error. For example:</P> +<DIV class="code"> +<PRE> +%template(intList) List<int>; +%template(Listint) List<int>; // Error. Template already wrapped. +</PRE> +</DIV> +<P> This error is caused because the template expansion results in two + identical classes with the same name. This generates a symbol table + conflict. Besides, it probably more efficient to only wrap a specific + instantiation only once in order to reduce the potential for code + bloat.</P> +<P> Since the type system knows how to handle <TT>typedef</TT>, it is + generally not necessary to instantiate different versions of a template + for typenames that are equivalent. For instance, consider this code:</P> +<DIV class="code"> +<PRE> +%template(intList) vector<int>; +typedef int Integer; +... +void foo(vector<Integer> *x); +</PRE> +</DIV> +<P> In this case, <TT>vector<Integer></TT> is exactly the same type as <TT> +vector<int></TT>. Any use of <TT>Vector<Integer></TT> is mapped back to + the instantiation of <TT>vector<int></TT> created earlier. Therefore, + it is not necessary to instantiate a new class for the type <TT>Integer</TT> + (doing so is redundant and will simply result in code bloat).</P> +<P> When a template is instantiated using <TT>%template</TT>, + information about that class is saved by SWIG and used elsewhere in the + program. For example, if you wrote code like this,</P> +<DIV class="code"> +<PRE> +... +%template(intList) List<int>; +... +class UltraList : public List<int> { + ... +}; +</PRE> +</DIV> +<P> then SWIG knows that <TT>List<int></TT> was already wrapped as a + class called <TT>intList</TT> and arranges to handle the inheritance + correctly. If, on the other hand, nothing is known about <TT>List<int></TT> +, you will get a warning message similar to this:</P> +<DIV class="shell"> +<PRE> +example.h:42. Nothing known about class 'List<int >' (ignored). +example.h:42. Maybe you forgot to instantiate 'List<int >' using %template. +</PRE> +</DIV> +<P> If a template class inherits from another template class, you need + to make sure that base classes are instantiated before derived classes. + For example:</P> +<DIV class="code"> +<PRE> +template<class T> class Foo { +... +}; + +template<class T> class Bar : public Foo<T> { +... +}; + +// Instantiate base classes first +%template(intFoo) Foo<int>; +%template(doubleFoo) Foo<double>; + +// Now instantiate derived classes +%template(intBar) Bar<int>; +%template(doubleBar) Bar<double>; +</PRE> +</DIV> +<P> The order is important since SWIG uses the instantiation names to + properly set up the inheritance hierarchy in the resulting wrapper code + (and base classes need to be wrapped before derived classes). Don't + worry--if you get the order wrong, SWIG should generate a warning + message.</P> +<P> Occasionally, you may need to tell SWIG about base classes that are + defined by templates, but which aren't supposed to be wrapped. Since + SWIG is not able to automatically instantiate templates for this + purpose, you must do it manually. To do this, simply use <TT>%template</TT> + with no name. For example:</P> +<DIV class="code"> +<PRE> +// Instantiate traits<double,double>, but don't wrap it. +%template() traits<double,double>; +</PRE> +</DIV> +<P> If you have to instantiate a lot of different classes for many + different types, you might consider writing a SWIG macro. For example:</P> +<DIV class="code"> +<PRE> +%define TEMPLATE_WRAP(prefix, T...) +%template(prefix ## Foo) Foo<T >; +%template(prefix ## Bar) Bar<T >; +... +%enddef + +TEMPLATE_WRAP(int, int) +TEMPLATE_WRAP(double, double) +TEMPLATE_WRAP(String, char *) +TEMPLATE_WRAP(PairStringInt, std::pair<string, int>) +... +</PRE> +</DIV> +<P> Note the use of a vararg macro for the type T. If this wasn't used, + the comma in the templated type in the last example would not be + possible.</P> +<P> The SWIG template mechanism<EM> does</EM> support specialization. + For instance, if you define a class like this,</P> +<DIV class="code"> +<PRE> +template<> class List<int> { +private: + int *data; + int nitems; + int maxitems; +public: + List(int max); + ~List(); + void append(int obj); + int length(); + int get(int n); +}; +</PRE> +</DIV> +<P> then SWIG will use this code whenever the user expands <TT>List<int></TT> +. In practice, this may have very little effect on the underlying + wrapper code since specialization is often used to provide slightly + modified method bodies (which are ignored by SWIG). However, special + SWIG directives such as <TT>%typemap</TT>, <TT>%extend</TT>, and so + forth can be attached to a specialization to provide customization for + specific types.</P> +<P> Partial template specialization is partially supported by SWIG. For + example, this code defines a template that is applied when the template + argument is a pointer.</P> +<DIV class="code"> +<PRE> +template<class T> class List<T*> { +private: + T *data; + int nitems; + int maxitems; +public: + List(int max); + ~List(); + void append(int obj); + int length(); + T get(int n); +}; +</PRE> +</DIV> +<P> SWIG should be able to handle most simple uses of partial + specialization. However, it may fail to match templates properly in + more complicated cases. For example, if you have this code,</P> +<DIV class="code"> +<PRE> +template<class T1, class T2> class Foo<T1, T2 *> { }; +</PRE> +</DIV> +<P> SWIG isn't able to match it properly for instantiations like <TT> +Foo<int *, int *></TT>. This problem is not due to parsing, but due to + the fact that SWIG does not currently implement all of the C++ argument + deduction rules.</P> +<P> Member function templates are supported. The underlying principle is + the same as for normal templates--SWIG can't create a wrapper unless + you provide more information about types. For example, a class with a + member template might look like this:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + template<class T> void bar(T x, T y) { ... }; + ... +}; +</PRE> +</DIV> +<P> To expand the template, simply use <TT>%template</TT> inside the + class.</P> +<DIV class="code"> +<PRE> +class Foo { +public: + template<class T> void bar(T x, T y) { ... }; + ... + %template(barint) bar<int>; + %template(bardouble) bar<double>; +}; +</PRE> +</DIV> +<P> Or, if you want to leave the original class definition alone, just + do this:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + template<class T> void bar(T x, T y) { ... }; + ... +}; +... +%extend Foo { + %template(barint) bar<int>; + %template(bardouble) bar<double>; +}; +</PRE> +</DIV> +<P> or simply</P> +<DIV class="code"> +<PRE> +class Foo { +public: + template<class T> void bar(T x, T y) { ... }; + ... +}; +... + +%template(bari) Foo::bar<int>; +%template(bard) Foo::bar<double>; +</PRE> +</DIV> +<P> In this case, the <TT>%extend</TT> directive is not needed, and <TT> +%template</TT> does the exactly same job, i.e., it adds two new methods + to the Foo class.</P> +<P> Note: because of the way that templates are handled, the <TT> +%template</TT> directive must always appear<EM> after</EM> the + definition of the template to be expanded.</P> +<P> Now, if your target language supports overloading, you can even try</P> +<DIV class="code"> +<PRE> +%template(bar) Foo::bar<int>; +%template(bar) Foo::bar<double>; +</PRE> +</DIV> +<P> and since the two new wrapped methods have the same name 'bar', they + will be overloaded, and when called, the correct method will be + dispatched depending on the argument type.</P> +<P> When used with members, the <TT>%template</TT> directive may be + placed in another template class. Here is a slightly perverse example:</P> +<DIV class="code"> +<PRE> +// A template +template<class T> class Foo { +public: + // A member template + template<class S> T bar(S x, S y) { ... }; + ... +}; + +// Expand a few member templates +%extend Foo { + %template(bari) bar<int>; + %template(bard) bar<double>; +} + +// Create some wrappers for the template +%template(Fooi) Foo<int>; +%template(Food) Foo<double>; +</PRE> +</DIV> +<P> Miraculously, you will find that each expansion of <TT>Foo</TT> has + member functions <TT>bari()</TT> and <TT>bard()</TT> added.</P> +<P> A common use of member templates is to define constructors for + copies and conversions. For example:</P> +<DIV class="code"> +<PRE> +template<class T1, class T2> struct pair { + T1 first; + T2 second; + pair() : first(T1()), second(T2()) { } + pair(const T1 &x, const T2 &y) : first(x), second(y) { } + template<class U1, class U2> pair(const pair<U1,U2> &x) + : first(x.first),second(x.second) { } +}; +</PRE> +</DIV> +<P> This declaration is perfectly acceptable to SWIG, but the + constructor template will be ignored unless you explicitly expand it. + To do that, you could expand a few versions of the constructor in the + template class itself. For example:</P> +<DIV class="code"> +<PRE> +%extend pair { + %template(pair) pair<T1,T2>; // Generate default copy constructor +}; +</PRE> +</DIV> +<P> When using <TT>%extend</TT> in this manner, notice how you can still + use the template parameters in the original template definition.</P> +<P> Alternatively, you could expand the constructor template in selected + instantiations. For example:</P> +<DIV class="code"> +<PRE> +// Instantiate a few versions +%template(pairii) pair<int,int>; +%template(pairdd) pair<double,double>; + +// Create a default constructor only +%extend pair<int,int> { + %template(paird) pair<int,int>; // Default constructor +}; + +// Create default and conversion constructors +%extend pair<double,double> { + %template(paird) pair<double,dobule>; // Default constructor + %template(pairc) pair<int,int>; // Conversion constructor +}; +</PRE> +</DIV> +<P>And if your target language supports overloading, then you can try + instead:</P> +<DIV class="code"> +<PRE> +// Create default and conversion constructors +%extend pair<double,double> { + %template(pair) pair<double,dobule>; // Default constructor + %template(pair) pair<int,int>; // Conversion constructor +}; +</PRE> +</DIV> +<P> In this case, the default and conversion constructors have the same + name. Hence, Swig will overload them and define an unique visible + constructor, that will dispatch the proper call depending on the + argument type.</P> +<P> If all of this isn't quite enough and you really want to make + someone's head explode, SWIG directives such as <TT>%rename</TT>, <TT> +%extend</TT>, and <TT>%typemap</TT> can be included directly in template + definitions. For example:</P> +<DIV class="code"> +<PRE> +// File : list.h +template<class T> class List { + ... +public: + %rename(__getitem__) get(int); + List(int max); + ~List(); + ... + T get(int index); + %extend { + char *__str__() { + /* Make a string representation */ + ... + } + } +}; +</PRE> +</DIV> +<P> In this example, the extra SWIG directives are propagated to<EM> + every</EM> template instantiation.</P> +<P> It is also possible to separate these declarations from the template + class. For example:</P> +<DIV class="code"> +<PRE> +%rename(__getitem__) List::get; +%extend List { + char *__str__() { + /* Make a string representation */ + ... + } + /* Make a copy */ + T *__copy__() { + return new List<T>(*$self); + } +}; + +... +template<class T> class List { + ... + public: + List() { }; + T get(int index); + ... +}; +</PRE> +</DIV> +<P> When <TT>%extend</TT> is decoupled from the class definition, it is + legal to use the same template parameters as provided in the class + definition. These are replaced when the template is expanded. In + addition, the <TT>%extend</TT> directive can be used to add additional + methods to a specific instantiation. For example:</P> +<DIV class="code"> +<PRE> +%template(intList) List<int>; + +%extend List<int> { + void blah() { + printf("Hey, I'm an List<int>!\n"); + } +}; +</PRE> +</DIV> +<P> SWIG even supports overloaded templated functions. As usual the <TT> +%template</TT> directive is used to wrap templated functions. For + example:</P> +<DIV class="code"> +<PRE> +template<class T> void foo(T x) { }; +template<class T> void foo(T x, T y) { }; + +%template(foo) foo<int>; +</PRE> +</DIV> +<P> This will generate two overloaded wrapper methods, the first will + take a single integer as an argument and the second will take two + integer arguments.</P> +<P> Needless to say, SWIG's template support provides plenty of + opportunities to break the universe. That said, an important final + point is that<B> SWIG does not perform extensive error checking of + templates!</B> Specifically, SWIG does not perform type checking nor + does it check to see if the actual contents of the template declaration + make any sense. Since the C++ compiler will hopefully check this when + it compiles the resulting wrapper file, there is no practical reason + for SWIG to duplicate this functionality (besides, none of the SWIG + developers are masochistic enough to want to implement this right now).</P> +<P><B> Compatibility Note</B>: The first implementation of template + support relied heavily on macro expansion in the preprocessor. + Templates have been more tightly integrated into the parser and type + system in SWIG-1.3.12 and the preprocessor is no longer used. Code that + relied on preprocessing features in template expansion will no longer + work. However, SWIG still allows the # operator to be used to generate + a string from a template argument.</P> +<P><B> Compatibility Note</B>: In earlier versions of SWIG, the <TT> +%template</TT> directive introduced a new class name. This name could + then be used with other directives. For example:</P> +<DIV class="code"> +<PRE> +%template(vectori) vector<int>; +%extend vectori { + void somemethod() { } +}; +</PRE> +</DIV> +<P> This behavior is no longer supported. Instead, you should use the + original template name as the class name. For example:</P> +<DIV class="code"> +<PRE> +%template(vectori) vector<int>; +%extend vector<int> { + void somemethod() { } +}; +</PRE> +</DIV> +<P> Similar changes apply to typemaps and other customization features.</P> +<H2><A name="SWIGPlus_nn31"></A>6.19 Namespaces</H2> +<P> Support for C++ namespaces is a relatively late addition to SWIG, + first appearing in SWIG-1.3.12. Before describing the implementation, + it is worth noting that the semantics of C++ namespaces is extremely + non-trivial--especially with regard to the C++ type system and class + machinery. At a most basic level, namespaces are sometimes used to + encapsulate common functionality. For example:</P> +<DIV class="code"> +<PRE> +namespace math { + double sin(double); + double cos(double); + + class Complex { + double im,re; + public: + ... + }; + ... +}; +</PRE> +</DIV> +<P> Members of the namespace are accessed in C++ by prepending the + namespace prefix to names. For example:</P> +<DIV class="code"> +<PRE> +double x = math::sin(1.0); +double magnitude(math::Complex *c); +math::Complex c; +... +</PRE> +</DIV> +<P> At this level, namespaces are relatively easy to manage. However, + things start to get very ugly when you throw in the other ways a + namespace can be used. For example, selective symbols can be exported + from a namespace with <TT>using</TT>.</P> +<DIV class="code"> +<PRE> +using math::Complex; +double magnitude(Complex *c); // Namespace prefix stripped +</PRE> +</DIV> +<P> Similarly, the contents of an entire namespace can be made available + like this:</P> +<DIV class="code"> +<PRE> +using namespace math; +double x = sin(1.0); +double magnitude(Complex *c); +</PRE> +</DIV> +<P> Alternatively, a namespace can be aliased:</P> +<DIV class="code"> +<PRE> +namespace M = math; +double x = M::sin(1.0); +double magnitude(M::Complex *c); +</PRE> +</DIV> +<P> Using combinations of these features, it is possible to write + head-exploding code like this:</P> +<DIV class="code"> +<PRE> +namespace A { + class Foo { + }; +} + +namespace B { + namespace C { + using namespace A; + } + typedef C::Foo FooClass; +} + +namespace BIGB = B; + +namespace D { + using BIGB::FooClass; + class Bar : public FooClass { + } +}; + +class Spam : public D::Bar { +}; + +void evil(A::Foo *a, B::FooClass *b, B::C::Foo *c, BIGB::FooClass *d, + BIGB::C::Foo *e, D::FooClass *f); + +</PRE> +</DIV> +<P> Given the possibility for such perversion, it's hard to imagine how + every C++ programmer might want such code wrapped into the target + language. Clearly this code defines three different classes. However, + one of those classes is accessible under at least six different names!</P> +<P> SWIG fully supports C++ namespaces in its internal type system and + class handling code. If you feed SWIG the above code, it will be parsed + correctly, it will generate compilable wrapper code, and it will + produce a working scripting language module. However, the default + wrapping behavior is to flatten namespaces in the target language. This + means that the contents of all namespaces are merged together in the + resulting scripting language module. For example, if you have code like + this,</P> +<DIV class="code"> +<PRE> +%module foo +namespace foo { + void bar(int); + void spam(); +} + +namespace bar { + void blah(); +} + +</PRE> +</DIV> +<P> then SWIG simply creates three wrapper functions <TT>bar()</TT>, <TT> +spam()</TT>, and <TT>blah()</TT> in the target language. SWIG does not + prepend the names with a namespace prefix nor are the functions + packaged in any kind of nested scope.</P> +<P> There is some rationale for taking this approach. Since C++ + namespaces are often used to define modules in C++, there is a natural + correlation between the likely contents of a SWIG module and the + contents of a namespace. For instance, it would not be unreasonable to + assume that a programmer might make a separate extension module for + each C++ namespace. In this case, it would be redundant to prepend + everything with an additional namespace prefix when the module itself + already serves as a namespace in the target language. Or put another + way, if you want SWIG to keep namespaces separate, simply wrap each + namespace with its own SWIG interface.</P> +<P> Because namespaces are flattened, it is possible for symbols defined + in different namespaces to generate a name conflict in the target + language. For example:</P> +<DIV class="code"> +<PRE> +namespace A { + void foo(int); +} +namespace B { + void foo(double); +} +</PRE> +</DIV> +<P> When this conflict occurs, you will get an error message that + resembles this:</P> +<DIV class="shell"> +<PRE> +example.i:26. Error. 'foo' is multiply defined in the generated module. +example.i:23. Previous declaration of 'foo' +</PRE> +</DIV> +<P> To resolve this error, simply use <TT>%rename</TT> to disambiguate + the declarations. For example:</P> +<DIV class="code"> +<PRE> +%rename(B_foo) B::foo; +... +namespace A { + void foo(int); +} +namespace B { + void foo(double); // Gets renamed to B_foo +} +</PRE> +</DIV> +<P> Similarly, <TT>%ignore</TT> can be used to ignore declarations.</P> +<P> <TT>using</TT> declarations do not have any effect on the generated + wrapper code. They are ignored by SWIG language modules and they do not + result in any code. However, these declarations<EM> are</EM> used by + the internal type system to track type-names. Therefore, if you have + code like this:</P> +<DIV class="code"> +<PRE> +namespace A { + typedef int Integer; +} +using namespace A; +void foo(Integer x); +</PRE> +</DIV> +<P> SWIG knows that <TT>Integer</TT> is the same as <TT>A::Integer</TT> + which is the same as <TT>int</TT>.</P> +<P> Namespaces may be combined with templates. If necessary, the <TT> +%template</TT> directive can be used to expand a template defined in a + different namespace. For example:</P> +<DIV class="code"> +<PRE> +namespace foo { + template<typename T> T max(T a, T b) { return a > b ? a : b; } +} + +using foo::max; + +%template(maxint) max<int>; // Okay. +%template(maxfloat) foo::max<float>; // Okay (qualified name). + +namespace bar { + using namespace foo; + %template(maxdouble) max<double>; // Okay. +} +</PRE> +</DIV> +<P> The combination of namespaces and other SWIG directives may + introduce subtle scope-related problems. The key thing to keep in mind + is that all SWIG generated wrappers are produced in the<EM> global</EM> + namespace. Symbols from other namespaces are always accessed using + fully qualified names---names are never imported into the global space + unless the interface happens to do so with a <TT>using</TT> + declaration. In almost all cases, SWIG adjusts typenames and symbols to + be fully qualified. However, this is not done in code fragments such as + function bodies, typemaps, exception handlers, and so forth. For + example, consider the following:</P> +<DIV class="code"> +<PRE> +namespace foo { + typedef int Integer; + class bar { + public: + ... + }; +} + +%extend foo::bar { + Integer add(Integer x, Integer y) { + Integer r = x + y; // Error. Integer not defined in this scope + return r; + } +}; +</PRE> +</DIV> +<P> In this case, SWIG correctly resolves the added method parameters + and return type to <TT>foo::Integer</TT>. However, since function + bodies aren't parsed and such code is emitted in the global namespace, + this code produces a compiler error about <TT>Integer</TT>. To fix the + problem, make sure you use fully qualified names. For example:</P> +<DIV class="code"> +<PRE> +%extend foo::bar { + Integer add(Integer x, Integer y) { + foo::Integer r = x + y; // Ok. + return r; + } +}; +</PRE> +</DIV> +<P><B> Note:</B> SWIG does<EM> not</EM> propagate <TT>using</TT> + declarations to the resulting wrapper code. If these declarations + appear in an interface, they should<EM> also</EM> appear in any header + files that might have been included in a <TT>%{ ... %}</TT> section. In + other words, don't insert extra <TT>using</TT> declarations into a SWIG + interface unless they also appear in the underlying C++ code.</P> +<P><B> Note:</B> Code inclusion directives such as <TT>%{ ... %}</TT> or + <TT>%inline %{ ... %}</TT> should not be placed inside a namespace + declaration. The code emitted by these directives will not be enclosed + in a namespace and you may get very strange results. If you need to use + namespaces with these directives, consider the following:</P> +<DIV class="code"> +<PRE> +// Good version +%inline %{ +namespace foo { + void bar(int) { ... } + ... +} +%} + +// Bad version. Emitted code not placed in namespace. +namespace foo { +%inline %{ + void bar(int) { ... } /* I'm bad */ + ... +%} +} +</PRE> +</DIV> +<P><B> Note:</B> When the <TT>%extend</TT> directive is used inside a + namespace, the namespace name is included in the generated functions. + For example, if you have code like this,</P> +<DIV class="code"> +<PRE> +namespace foo { + class bar { + public: + %extend { + int blah(int x); + }; + }; +} +</PRE> +</DIV> +<P> the added method <TT>blah()</TT> is mapped to a function <TT>int + foo_bar_blah(foo::bar *self, int x)</TT>. This function resides in the + global namespace.</P> +<P><B> Note:</B> Although namespaces are flattened in the target + language, the SWIG generated wrapper code observes the same namespace + conventions as used in the input file. Thus, if there are no symbol + conflicts in the input, there will be no conflicts in the generated + code.</P> +<P><B> Note:</B> In the same way that no resolution is performed on + parameters, a conversion operator name must match exactly to how it is + defined. Do not change the qualification of the operator. For example, + suppose you had an interface like this:</P> +<DIV class="code"> +<PRE> +namespace foo { + class bar; + class spam { + public: + ... + operator bar(); // Conversion of spam -> bar + ... + }; +} +</PRE> +</DIV> +<P> The following is how the feature is expected to be written for a + successful match:</P> +<DIV class="code"> +<PRE> +%rename(tofoo) foo::spam::operator bar(); +</PRE> +</DIV> +<P> The following does not work as no namespace resolution is performed + in the matching of conversion operator names:</P> +<DIV class="code"> +<PRE> +%rename(tofoo) foo::spam::operator <B>foo::</B>bar(); +</PRE> +</DIV> +<P> Note, however, that if the operator is defined using a qualifier in + its name, then the feature must use it too...</P> +<DIV class="code"> +<PRE> +%rename(tofoo) foo::spam::operator bar(); // will not match +%rename(tofoo) foo::spam::operator foo::bar(); // will match +namespace foo { + class bar; + class spam { + public: + ... + operator foo::bar(); + ... + }; +} +</PRE> +</DIV> +<P><B> Compatibility Note:</B> Versions of SWIG prior to 1.3.32 were + inconsistent in this approach. A fully qualified name was usually + required, but would not work in some situations.</P> +<P><B> Note:</B> The flattening of namespaces is only intended to serve + as a basic namespace implementation. None of the target language + modules are currently programmed with any namespace awareness. In the + future, language modules may or may not provide more advanced namespace + support.</P> +<H2><A name="SWIGPlus_renaming_templated_types_namespaces"></A>6.20 + Renaming templated types in namespaces</H2> +<P> As has been mentioned, when %rename includes parameters, the + parameter types must match exactly (no typedef or namespace resolution + is performed). SWIG treats templated types slightly differently and has + an additional matching rule so unlike non-templated types, an exact + match is not always required. If the fully qualified templated type is + specified, it will have a higher precedence over the generic template + type. In the example below, the generic template type is used to rename + to <TT>bbb</TT> and the fully qualified type is used to rename to <TT> +ccc</TT>.</P> +<DIV class="code"> +<PRE> +%rename(bbb) Space::ABC::aaa(T t); // will match but with lower precedence than ccc +%rename(ccc) Space::ABC<Space::XYZ>::aaa(Space::XYZ t); // will match but with higher precedence than bbb + +namespace Space { + class XYZ {}; + template<typename T> struct ABC { + void aaa(T t) {} + }; +} +%template(ABCXYZ) Space::ABC<Space::XYZ>; +</PRE> +</DIV> +<P> It should now be apparent that there are many ways to achieve a + renaming with %rename. This is demonstrated by the following two + examples, which are effectively the same as the above example. Below + shows how %rename can be placed inside a namespace.</P> +<DIV class="code"> +<PRE> +namespace Space { + %rename(bbb) ABC::aaa(T t); // will match but with lower precedence than ccc + %rename(ccc) ABC<Space::XYZ>::aaa(Space::XYZ t); // will match but with higher precedence than bbb + %rename(ddd) ABC<Space::XYZ>::aaa(XYZ t); // will not match +} + +namespace Space { + class XYZ {}; + template<typename T> struct ABC { + void aaa(T t) {} + }; +} +%template(ABCXYZ) Space::ABC<Space::XYZ>; +</PRE> +</DIV> +<P> Note that <TT>ddd</TT> does not match as there is no namespace + resolution for parameter types and the fully qualified type must be + specified for template type expansion. The following example shows how + %rename can be placed within %extend.</P> +<DIV class="code"> +<PRE> +namespace Space { + %extend ABC { + %rename(bbb) aaa(T t); // will match but with lower precedence than ccc + } + %extend ABC<Space::XYZ> { + %rename(ccc) aaa(Space::XYZ t); // will match but with higher precedence than bbb + %rename(ddd) aaa(XYZ t); // will not match + } +} + +namespace Space { + class XYZ {}; + template<typename T> struct ABC { + void aaa(T t) {} + }; +} +%template(ABCXYZ) Space::ABC<Space::XYZ>; +</PRE> +</DIV> +<H2><A name="SWIGPlus_exception_specifications"></A>6.21 Exception + specifications</H2> +<P> When C++ programs utilize exceptions, exceptional behavior is + sometimes specified as part of a function or method declaration. For + example:</P> +<DIV class="code"> +<PRE> +class Error { }; + +class Foo { +public: + ... + void blah() throw(Error); + ... +}; +</PRE> +</DIV> +<P> If an exception specification is used, SWIG automatically generates + wrapper code for catching the indicated exception and, when possible, + rethrowing it into the target language, or converting it into an error + in the target language otherwise. For example, in Python, you can write + code like this:</P> +<DIV class="targetlang"> +<PRE> +f = Foo() +try: + f.blah() +except Error,e: + # e is a wrapped instance of "Error" +</PRE> +</DIV> +<P> Details of how to tailor code for handling the caught C++ exception + and converting it into the target language's exception/error handling + mechanism is outlined in the <A href="#throws_typemap">"throws" typemap</A> + section.</P> +<P> Since exception specifications are sometimes only used sparingly, + this alone may not be enough to properly handle C++ exceptions. To do + that, a different set of special SWIG directives are used. Consult the + "<A href="#exception">Exception handling with %exception</A>" section + for details. The next section details a way of simulating an exception + specification or replacing an existing one.</P> +<H2><A name="SWIGPlus_catches"></A>6.22 Exception handling with %catches</H2> +<P> Exceptions are automatically handled for methods with an exception + specification. Similar handling can be achieved for methods without + exception specifications through the <TT>%catches</TT> feature. It is + also possible to replace any declared exception specification using the + <TT>%catches</TT> feature. In fact, <TT>%catches</TT> uses the same <A href="#throws_typemap"> +"throws" typemaps</A> that SWIG uses for exception specifications in + handling exceptions. The <TT>%catches</TT> feature must contain a list + of possible types that can be thrown. For each type that is in the + list, SWIG will generate a catch handler, in the same way that it would + for types declared in the exception specification. Note that the list + can also include the catch all specification "...". For example,</P> +<DIV class="code"> +<PRE> +struct EBase { virtual ~EBase(); }; +struct Error1 : EBase { }; +struct Error2 : EBase { }; +struct Error3 : EBase { }; +struct Error4 : EBase { }; + +%catches(Error1,Error2,...) Foo::bar(); +%catches(EBase) Foo::blah(); + +class Foo { +public: + ... + void bar(); + void blah() throw(Error1,Error2,Error3,Error4); + ... +}; +</PRE> +</DIV> +<P> For the <TT>Foo::bar()</TT> method, which can throw anything, SWIG + will generate catch handlers for <TT>Error1</TT>, <TT>Error2</TT> as + well as a catch all handler (...). Each catch handler will convert the + caught exception and convert it into a target language error/exception. + The catch all handler will convert the caught exception into an unknown + error/exception.</P> +<P> Without the <TT>%catches</TT> feature being attached to <TT> +Foo::blah()</TT>, SWIG will generate catch handlers for all of the types + in the exception specification, that is, <TT>Error1, Error2, Error3, + Error4</TT>. However, with the <TT>%catches</TT> feature above, just a + single catch handler for the base class, <TT>EBase</TT> will be + generated to convert the C++ exception into a target language + error/exception.</P> +<H2><A name="SWIGPlus_nn33"></A>6.23 Pointers to Members</H2> +<P> Starting with SWIG-1.3.7, there is limited parsing support for + pointers to C++ class members. For example:</P> +<DIV class="code"> +<PRE> +double do_op(Object *o, double (Object::*callback)(double,double)); +extern double (Object::*fooptr)(double,double); +%constant double (Object::*FOO)(double,double) = &Object::foo; +</PRE> +</DIV> +<P> Although these kinds of pointers can be parsed and represented by + the SWIG type system, few language modules know how to handle them due + to implementation differences from standard C pointers. Readers are<EM> + strongly</EM> advised to consult an advanced text such as the "The + Annotated C++ Manual" for specific details.</P> +<P> When pointers to members are supported, the pointer value might + appear as a special string like this:</P> +<DIV class="targetlang"> +<PRE> +>>> print example.FOO +_ff0d54a800000000_m_Object__f_double_double__double +>>> +</PRE> +</DIV> +<P> In this case, the hexadecimal digits represent the entire value of + the pointer which is usually the contents of a small C++ structure on + most machines.</P> +<P> SWIG's type-checking mechanism is also more limited when working + with member pointers. Normally SWIG tries to keep track of inheritance + when checking types. However, no such support is currently provided for + member pointers.</P> +<H2><A name="SWIGPlus_nn34"></A>6.24 Smart pointers and operator->()</H2> +<P> In some C++ programs, objects are often encapsulated by + smart-pointers or proxy classes. This is sometimes done to implement + automatic memory management (reference counting) or persistence. + Typically a smart-pointer is defined by a template class where the <TT> +-></TT> operator has been overloaded. This class is then wrapped around + some other class. For example:</P> +<DIV class="code"> +<PRE> +// Smart-pointer class +template<class T> class SmartPtr { + T *pointee; +public: + ... + T *operator->() { + return pointee; + } + ... +}; + +// Ordinary class +class Foo_Impl { +public: + int x; + virtual void bar(); + ... +}; + +// Smart-pointer wrapper +typedef SmartPtr<Foo_Impl> Foo; + +// Create smart pointer Foo +Foo make_Foo() { + return SmartPtr(new Foo_Impl()); +} + +// Do something with smart pointer Foo +void do_something(Foo f) { + printf("x = %d\n", f->x); + f->bar(); +} +</PRE> +</DIV> +<P> A key feature of this approach is that by defining <TT>operator-></TT> + the methods and attributes of the object wrapped by a smart pointer are + transparently accessible. For example, expressions such as these (from + the previous example),</P> +<DIV class="code"> +<PRE> +f->x +f->bar() +</PRE> +</DIV> +<P> are transparently mapped to the following</P> +<DIV class="code"> +<PRE> +(f.operator->())->x; +(f.operator->())->bar(); +</PRE> +</DIV> +<P> When generating wrappers, SWIG tries to emulate this functionality + to the extent that it is possible. To do this, whenever <TT> +operator->()</TT> is encountered in a class, SWIG looks at its returned + type and uses it to generate wrappers for accessing attributes of the + underlying object. For example, wrapping the above code produces + wrappers like this:</P> +<DIV class="code"> +<PRE> +int Foo_x_get(Foo *f) { + return (*f)->x; +} +void Foo_x_set(Foo *f, int value) { + (*f)->x = value; +} +void Foo_bar(Foo *f) { + (*f)->bar(); +} +</PRE> +</DIV> +<P> These wrappers take a smart-pointer instance as an argument, but + dereference it in a way to gain access to the object returned by <TT> +operator->()</TT>. You should carefully compare these wrappers to those + in the first part of this chapter (they are slightly different).</P> +<P> The end result is that access looks very similar to C++. For + example, you could do this in Python:</P> +<DIV class="targetlang"> +<PRE> +>>> f = make_Foo() +>>> print f.x +0 +>>> f.bar() +>>> +</PRE> +</DIV> +<P> When generating wrappers through a smart-pointer, SWIG tries to + generate wrappers for all methods and attributes that might be + accessible through <TT>operator->()</TT>. This includes any methods + that might be accessible through inheritance. However, there are a + number of restrictions:</P> +<UL> +<LI>Member variables and methods are wrapped through a smart pointer. + Enumerations, constructors, and destructors are not wrapped.</LI> +<LI> +<P>If the smart-pointer class and the underlying object both define a + method or variable of the same name, then the smart-pointer version has + precedence. For example, if you have this code</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int x; +}; + +class Bar { +public: + int x; + Foo *operator->(); +}; +</PRE> +</DIV> +<P> then the wrapper for <TT>Bar::x</TT> accesses the <TT>x</TT> defined + in <TT>Bar</TT>, and not the <TT>x</TT> defined in <TT>Foo</TT>.</P> +</LI> +</UL> +<P> If your intent is to only expose the smart-pointer class in the + interface, it is not necessary to wrap both the smart-pointer class and + the class for the underlying object. However, you must still tell SWIG + about both classes if you want the technique described in this section + to work. To only generate wrappers for the smart-pointer class, you can + use the %ignore directive. For example:</P> +<DIV class="code"> +<PRE> +%ignore Foo; +class Foo { // Ignored +}; + +class Bar { +public: + Foo *operator->(); + ... +}; +</PRE> +</DIV> +<P> Alternatively, you can import the definition of <TT>Foo</TT> from a + separate file using <TT>%import</TT>.</P> +<P><B> Note:</B> When a class defines <TT>operator->()</TT>, the + operator itself is wrapped as a method <TT>__deref__()</TT>. For + example:</P> +<DIV class="targetlang"> +<PRE> +f = Foo() # Smart-pointer +p = f.__deref__() # Raw pointer from operator-> +</PRE> +</DIV> +<P><B> Note:</B> To disable the smart-pointer behavior, use <TT>%ignore</TT> + to ignore <TT>operator->()</TT>. For example:</P> +<DIV class="code"> +<PRE> +%ignore Bar::operator->; +</PRE> +</DIV> +<P><B> Note:</B> Smart pointer support was first added in SWIG-1.3.14.</P> +<H2><A name="SWIGPlus_nn35"></A>6.25 Using declarations and inheritance</H2> +<P> <TT>using</TT> declarations are sometimes used to adjust access to + members of base classes. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int blah(int x); +}; + +class Bar { +public: + double blah(double x); +}; + +class FooBar : public Foo, public Bar { +public: + using Foo::blah; + using Bar::blah; + char *blah(const char *x); +}; +</PRE> +</DIV> +<P> In this example, the <TT>using</TT> declarations make different + versions of the overloaded <TT>blah()</TT> method accessible from the + derived class. For example:</P> +<DIV class="code"> +<PRE> +FooBar *f; +f->blah(3); // Ok. Invokes Foo::blah(int) +f->blah(3.5); // Ok. Invokes Bar::blah(double) +f->blah("hello"); // Ok. Invokes FooBar::blah(const char *); +</PRE> +</DIV> +<P> SWIG emulates the same functionality when creating wrappers. For + example, if you wrap this code in Python, the module works just like + you would expect:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> f = example.FooBar() +>>> f.blah(3) +>>> f.blah(3.5) +>>> f.blah("hello") +</PRE> +</DIV> +<P> <TT>using</TT> declarations can also be used to change access when + applicable. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +protected: + int x; + int blah(int x); +}; + +class Bar : public Foo { +public: + using Foo::x; // Make x public + using Foo::blah; // Make blah public +}; +</PRE> +</DIV> +<P> This also works in SWIG---the exposed declarations will be wrapped + normally.</P> +<P> When <TT>using</TT> declarations are used as shown in these + examples, declarations from the base classes are copied into the + derived class and wrapped normally. When copied, the declarations + retain any properties that might have been attached using <TT>%rename</TT> +, <TT>%ignore</TT>, or <TT>%feature</TT>. Thus, if a method is ignored + in a base class, it will also be ignored by a <TT>using</TT> + declaration.</P> +<P> Because a <TT>using</TT> declaration does not provide fine-grained + control over the declarations that get imported, it may be difficult to + manage such declarations in applications that make heavy use of SWIG + customization features. If you can't get <TT>using</TT> to work + correctly, you can always change the interface to the following:</P> +<DIV class="code"> +<PRE> + +class FooBar : public Foo, public Bar { +public: +#ifndef SWIG + using Foo::blah; + using Bar::blah; +#else + int blah(int x); // explicitly tell SWIG about other declarations + double blah(double x); +#endif + + char *blah(const char *x); +}; +</PRE> +</DIV> +<P><B> Notes:</B></P> +<UL> +<LI> +<P>If a derived class redefines a method defined in a base class, then a + <TT>using</TT> declaration won't cause a conflict. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int blah(int ); + double blah(double); +}; + +class Bar : public Foo { +public: + using Foo::blah; // Only imports blah(double); + int blah(int); +}; +</PRE> +</DIV></LI> +<LI> +<P>Resolving ambiguity in overloading may prevent declarations from + being imported by <TT>using</TT>. For example:</P> +<DIV class="code"> +<PRE> +%rename(blah_long) Foo::blah(long); +class Foo { +public: + int blah(int); + long blah(long); // Renamed to blah_long +}; + +class Bar : public Foo { +public: + using Foo::blah; // Only imports blah(int) + double blah(double x); +}; +</PRE> +</DIV></LI> +</UL> +<H2><A name="SWIGPlus_nested_classes"></A>6.26 Nested classes</H2> +<P> There is limited support for nested structs and unions when wrapping + C code, see <A href="#SWIG_nested_structs">Nested structures</A> for + further details. However, there is no nested class/struct/union support + when wrapping C++ code (using the -c++ commandline option). This may be + added at a future date, however, until then some of the following + workarounds can be applied.</P> +<P> It might be possible to use partial class information. Since SWIG + does not need the entire class specification to work, conditional + compilation can be used to comment out the problematic nested class + definition, you might do this:</P> +<DIV class="code"> +<PRE> +class Foo { +public: +#ifndef SWIG + class Bar { + public: + ... + }; +#endif + Foo(); + ~Foo(); + ... +}; +</PRE> +</DIV> +<P> The next workaround assumes you cannot modify the source code as was + done above and it provides a solution for methods that use nested class + types. Imagine we are wrapping the <TT>Outer</TT> class which contains + a nested class <TT>Inner</TT>:</P> +<DIV class="code"> +<PRE> +// File outer.h +class Outer { +public: + class Inner { + public: + int var; + Inner(int v = 0) : var(v) {} + }; + void method(Inner inner); +}; +</PRE> +</DIV> +<P> The following interface file works around SWIG nested class + limitations by redefining the nested class as a global class. A typedef + for the compiler is also required in order for the generated wrappers + to compile.</P> +<DIV class="code"> +<PRE> +// File : example.i +%module example + +// Suppress SWIG warning +#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS + +// Redefine nested class in global scope in order for SWIG to generate +// a proxy class. Only SWIG parses this definition. +class Inner { + public: + int var; + Inner(int v = 0) : var(v) {} +}; + +%{ +#include "outer.h" +%} +%include "outer.h" + +%{ +// SWIG thinks that Inner is a global class, so we need to trick the C++ +// compiler into understanding this so called global type. +typedef Outer::Inner Inner; +%} + +</PRE> +</DIV> +<P> The downside to this approach is having to maintain two definitions + of <TT>Inner</TT>, the real one and the one in the interface file that + SWIG parses.</P> +<H2><A name="SWIGPlus_nn37"></A>6.27 A brief rant about + const-correctness</H2> +<P> A common issue when working with C++ programs is dealing with all + possible ways in which the <TT>const</TT> qualifier (or lack thereof) + will break your program, all programs linked against your program, and + all programs linked against those programs.</P> +<P> Although SWIG knows how to correctly deal with <TT>const</TT> in its + internal type system and it knows how to generate wrappers that are + free of const-related warnings, SWIG does not make any attempt to + preserve const-correctness in the target language. Thus, it is possible + to pass <TT>const</TT> qualified objects to non-const methods and + functions. For example, consider the following code in C++:</P> +<DIV class="code"> +<PRE> +const Object * foo(); +void bar(Object *); + +... +// C++ code +void blah() { + bar(foo()); // Error: bar discards const +}; +</PRE> +</DIV> +<P> Now, consider the behavior when wrapped into a Python module:</P> +<DIV class="targetlang"> +<PRE> +>>> bar(foo()) # Okay +>>> +</PRE> +</DIV> +<P> Although this is clearly a violation of the C++ type-system, fixing + the problem doesn't seem to be worth the added implementation + complexity that would be required to support it in the SWIG run-time + type system. There are no plans to change this in future releases + (although we'll never rule anything out entirely).</P> +<P> The bottom line is that this particular issue does not appear to be + a problem for most SWIG projects. Of course, you might want to consider + using another tool if maintaining constness is the most important part + of your project.</P> +<H2><A name="SWIGPlus_nn42"></A>6.28 Where to go for more information</H2> +<P> If you're wrapping serious C++ code, you might want to pick up a + copy of "The Annotated C++ Reference Manual" by Ellis and Stroustrup. + This is the reference document we use to guide a lot of SWIG's C++ + support.</P> + +<!-- LocalWords: destructors Enums Namespaces const SWIG's STL OO adaptor tcl + --> + +<!-- LocalWords: debuggable cxx OBJS Wiki accessor nodefault makedefault + --> + +<!-- LocalWords: notabstract CopyFoo + --> +<HR NOSHADE> +<H1><A name="Preprocessor"></A>7 Preprocessing</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Preprocessor_nn2">File inclusion</A></LI> +<LI><A href="#Preprocessor_nn3">File imports</A></LI> +<LI><A href="#Preprocessor_condition_compilation">Conditional + Compilation</A></LI> +<LI><A href="#Preprocessor_nn5">Macro Expansion</A></LI> +<LI><A href="#Preprocessor_nn6">SWIG Macros</A></LI> +<LI><A href="#Preprocessor_nn7">C99 and GNU Extensions</A></LI> +<LI><A href="#Preprocessor_nn8">Preprocessing and %{ ... %} & " ... " + delimiters</A></LI> +<LI><A href="#Preprocessor_nn9">Preprocessing and { ... } delimiters</A></LI> +<LI><A href="#Preprocessor_typemap_delimiters">Preprocessor and Typemaps</A> +</LI> +<LI><A href="#Preprocessor_nn10">Viewing preprocessor output</A></LI> +<LI><A href="#Preprocessor_warning_error">The #error and #warning + directives</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> SWIG includes its own enhanced version of the C preprocessor. The + preprocessor supports the standard preprocessor directives and macro + expansion rules. However, a number of modifications and enhancements + have been made. This chapter describes some of these modifications.</P> +<H2><A name="Preprocessor_nn2"></A>7.1 File inclusion</H2> +<P> To include another file into a SWIG interface, use the <TT>%include</TT> + directive like this:</P> +<DIV class="code"> +<PRE> +%include "pointer.i" +</PRE> +</DIV> +<P> Unlike, <TT>#include</TT>, <TT>%include</TT> includes each file once + (and will not reload the file on subsequent <TT>%include</TT> + declarations). Therefore, it is not necessary to use include-guards in + SWIG interfaces.</P> +<P> By default, the <TT>#include</TT> is ignored unless you run SWIG + with the <TT>-includeall</TT> option. The reason for ignoring + traditional includes is that you often don't want SWIG to try and wrap + everything included in standard header system headers and auxiliary + files.</P> +<H2><A name="Preprocessor_nn3"></A>7.2 File imports</H2> +<P> SWIG provides another file inclusion directive with the <TT>%import</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +%import "foo.i" +</PRE> +</DIV> +<P> The purpose of <TT>%import</TT> is to collect certain information + from another SWIG interface file or a header file without actually + generating any wrapper code. Such information generally includes type + declarations (e.g., <TT>typedef</TT>) as well as C++ classes that might + be used as base-classes for class declarations in the interface. The + use of <TT>%import</TT> is also important when SWIG is used to generate + extensions as a collection of related modules. This is an advanced + topic and is described in later in the <A href="Modules.html">Working + with Modules</A> chapter.</P> +<P> The <TT>-importall</TT> directive tells SWIG to follow all <TT> +#include</TT> statements as imports. This might be useful if you want to + extract type definitions from system header files without generating + any wrappers.</P> +<H2><A name="Preprocessor_condition_compilation"></A>7.3 Conditional + Compilation</H2> +<P> SWIG fully supports the use of <TT>#if</TT>, <TT>#ifdef</TT>, <TT> +#ifndef</TT>, <TT>#else</TT>, <TT>#endif</TT> to conditionally include + parts of an interface. The following symbols are predefined by SWIG + when it is parsing the interface:</P> +<DIV class="code"> +<PRE> +SWIG Always defined when SWIG is processing a file +SWIGIMPORTED Defined when SWIG is importing a file with <TT>%import</TT> +SWIGMAC Defined when running SWIG on the Macintosh +SWIGWIN Defined when running SWIG under Windows +SWIG_VERSION Hexadecimal number containing SWIG version, + such as 0x010311 (corresponding to SWIG-1.3.11). + +SWIGALLEGROCL Defined when using Allegro CL +SWIGCFFI Defined when using CFFI +SWIGCHICKEN Defined when using CHICKEN +SWIGCLISP Defined when using CLISP +SWIGCSHARP Defined when using C# +SWIGGUILE Defined when using Guile +SWIGJAVA Defined when using Java +SWIGLUA Defined when using Lua +SWIGMODULA3 Defined when using Modula-3 +SWIGMZSCHEME Defined when using Mzscheme +SWIGOCAML Defined when using Ocaml +SWIGOCTAVE Defined when using Octave +SWIGPERL Defined when using Perl +SWIGPHP Defined when using PHP +SWIGPIKE Defined when using Pike +SWIGPYTHON Defined when using Python +SWIGR Defined when using R +SWIGRUBY Defined when using Ruby +SWIGSEXP Defined when using S-expressions +SWIGTCL Defined when using Tcl +SWIGXML Defined when using XML +</PRE> +</DIV> +<P> In addition, SWIG defines the following set of standard C/C++ + macros:</P> +<DIV class="code"> +<PRE> +__LINE__ Current line number +__FILE__ Current file name +__STDC__ Defined to indicate ANSI C +__cplusplus Defined when -c++ option used +</PRE> +</DIV> +<P> Interface files can look at these symbols as necessary to change the + way in which an interface is generated or to mix SWIG directives with C + code. These symbols are also defined within the C code generated by + SWIG (except for the symbol `<TT>SWIG</TT>' which is only defined + within the SWIG compiler).</P> +<H2><A name="Preprocessor_nn5"></A>7.4 Macro Expansion</H2> +<P> Traditional preprocessor macros can be used in SWIG interfaces. Be + aware that the <TT>#define</TT> statement is also used to try and + detect constants. Therefore, if you have something like this in your + file,</P> +<DIV class="code"> +<PRE> +#ifndef _FOO_H 1 +#define _FOO_H 1 +... +#endif +</PRE> +</DIV> +<P> you may get some extra constants such as <TT>_FOO_H</TT> showing up + in the scripting interface.</P> +<P> More complex macros can be defined in the standard way. For example:</P> +<DIV class="code"> +<PRE> +#define EXTERN extern +#ifdef __STDC__ +#define _ANSI(args) (args) +#else +#define _ANSI(args) () +#endif +</PRE> +</DIV> +<P> The following operators can appear in macro definitions:</P> +<UL> +<LI><TT>#x</TT> +<BR> Converts macro argument <TT>x</TT> to a string surrounded by double + quotes ("x").</LI> +<LI><TT>x ## y</TT> +<BR> Concatenates x and y together to form <TT>xy</TT>.</LI> +<LI><TT>`x`</TT> +<BR> If <TT>x</TT> is a string surrounded by double quotes, do nothing. + Otherwise, turn into a string like <TT>#x</TT>. This is a non-standard + SWIG extension.</LI> +</UL> +<H2><A name="Preprocessor_nn6"></A>7.5 SWIG Macros</H2> +<P> SWIG provides an enhanced macro capability with the <TT>%define</TT> + and <TT>%enddef</TT> directives. For example:</P> +<DIV class="code"> +<PRE> +%define ARRAYHELPER(type,name) +%inline %{ +type *new_ ## name (int nitems) { + return (type *) malloc(sizeof(type)*nitems); +} +void delete_ ## name(type *t) { + free(t); +} +type name ## _get(type *t, int index) { + return t[index]; +} +void name ## _set(type *t, int index, type val) { + t[index] = val; +} +%} +%enddef + +ARRAYHELPER(int, IntArray) +ARRAYHELPER(double, DoubleArray) +</PRE> +</DIV> +<P> The primary purpose of <TT>%define</TT> is to define large macros of + code. Unlike normal C preprocessor macros, it is not necessary to + terminate each line with a continuation character (\)--the macro + definition extends to the first occurrence of <TT>%enddef</TT>. + Furthermore, when such macros are expanded, they are reparsed through + the C preprocessor. Thus, SWIG macros can contain all other + preprocessor directives except for nested <TT>%define</TT> statements.</P> +<P> The SWIG macro capability is a very quick and easy way to generate + large amounts of code. In fact, many of SWIG's advanced features and + libraries are built using this mechanism (such as C++ template + support).</P> +<H2><A name="Preprocessor_nn7"></A>7.6 C99 and GNU Extensions</H2> +<P> SWIG-1.3.12 and newer releases support variadic preprocessor macros. + For example:</P> +<DIV class="code"> +<PRE> +#define DEBUGF(fmt,...) fprintf(stderr,fmt,__VA_ARGS__) +</PRE> +</DIV> +<P> When used, any extra arguments to <TT>...</TT> are placed into the + special variable <TT>__VA_ARGS__</TT>. This also works with special + SWIG macros defined using <TT>%define</TT>.</P> +<P> SWIG allows a variable number of arguments to be empty. However, + this often results in an extra comma (,) and syntax error in the + resulting expansion. For example:</P> +<DIV class="code"> +<PRE> +DEBUGF("hello"); --> fprintf(stderr,"hello",); +</PRE> +</DIV> +<P> To get rid of the extra comma, use <TT>##</TT> like this:</P> +<DIV class="code"> +<PRE> +#define DEBUGF(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__) +</PRE> +</DIV> +<P> SWIG also supports GNU-style variadic macros. For example:</P> +<DIV class="code"> +<PRE> +#define DEBUGF(fmt, args...) fprintf(stdout,fmt,args) +</PRE> +</DIV> +<P><B> Comment:</B> It's not entirely clear how variadic macros might be + useful to interface building. However, they are used internally to + implement a number of SWIG directives and are provided to make SWIG + more compatible with C99 code.</P> +<H2><A name="Preprocessor_nn8"></A>7.7 Preprocessing and %{ ... %} & " + ... " delimiters</H2> +<P> The SWIG preprocessor does not process any text enclosed in a code + block %{ ... %}. Therefore, if you write code like this,</P> +<DIV class="code"> +<PRE> +%{ +#ifdef NEED_BLAH +int blah() { + ... +} +#endif +%} +</PRE> +</DIV> +<P> the contents of the <TT>%{ ... %}</TT> block are copied without + modification to the output (including all preprocessor directives).</P> +<H2><A name="Preprocessor_nn9"></A>7.8 Preprocessing and { ... } + delimiters</H2> +<P> SWIG always runs the preprocessor on text appearing inside <TT>{ ... + }</TT>. However, sometimes it is desirable to make a preprocessor + directive pass through to the output file. For example:</P> +<DIV class="code"> +<PRE> +%extend Foo { + void bar() { + #ifdef DEBUG + printf("I'm in bar\n"); + #endif + } +} +</PRE> +</DIV> +<P> By default, SWIG will interpret the <TT>#ifdef DEBUG</TT> statement. + However, if you really wanted that code to actually go into the wrapper + file, prefix the preprocessor directives with <TT>%</TT> like this:</P> +<DIV class="code"> +<PRE> +%extend Foo { + void bar() { + %#ifdef DEBUG + printf("I'm in bar\n"); + %#endif + } +} +</PRE> +</DIV> +<P> SWIG will strip the extra <TT>%</TT> and leave the preprocessor + directive in the code.</P> +<H2><A name="Preprocessor_typemap_delimiters"></A>7.9 Preprocessor and + Typemaps</H2> +<P> <A href="Typemaps.html">Typemaps</A> support a special attribute + called <TT>noblock</TT> where the { ... } delimiters can be used, but + the delimiters are not actually generated into the code. The effect is + then similar to using "" or %{ %} delimiters but the code<B> is</B> run + through the preprocessor. For example:</P> +<DIV class="code"> +<PRE> +#define SWIG_macro(CAST) (CAST)$input +%typemap(in) Int {$1= SWIG_macro(int);} +</PRE> +</DIV> +<P> might generate</P> +<DIV class="code"> +<PRE> + { + arg1=(int)jarg1; + } +</PRE> +</DIV> +<P> whereas</P> +<DIV class="code"> +<PRE> +#define SWIG_macro(CAST) (CAST)$input +%typemap(in,noblock=1) Int {$1= SWIG_macro(int);} +</PRE> +</DIV> +<P> might generate</P> +<DIV class="code"> +<PRE> + arg1=(int)jarg1; +</PRE> +</DIV> +<P> and</P> +<DIV class="code"> +<PRE> +#define SWIG_macro(CAST) (CAST)$input +%typemap(in) Int %{$1=SWIG_macro(int);%} +</PRE> +</DIV> +<P> would generate</P> +<DIV class="code"> +<PRE> + arg1=SWIG_macro(int); +</PRE> +</DIV> +<H2><A name="Preprocessor_nn10"></A>7.10 Viewing preprocessor output</H2> +<P> Like many compilers, SWIG supports a <TT>-E</TT> command line option + to display the output from the preprocessor. When the <TT>-E</TT> + switch is used, SWIG will not generate any wrappers. Instead the + results after the preprocessor has run are displayed. This might be + useful as an aid to debugging and viewing the results of macro + expansions.</P> +<H2><A name="Preprocessor_warning_error"></A>7.11 The #error and + #warning directives</H2> +<P> SWIG supports the commonly used <TT>#warning</TT> and <TT>#error</TT> + preprocessor directives. The <TT>#warning</TT> directive will cause + SWIG to issue a warning then continue processing. The <TT>#error</TT> + directive will cause SWIG to exit with a fatal error. Example usage:</P> +<DIV class="code"> +<PRE> +#error "This is a fatal error message" +#warning "This is a warning message" +</PRE> +</DIV> +<P> The <TT>#error</TT> behaviour can be made to work like <TT>#warning</TT> + if the <TT>-cpperraswarn</TT> commandline option is used. + Alternatively, the <TT>#pragma</TT> directive can be used to the same + effect, for example:</P> +<DIV class="code"> +<PRE> + /* Modified behaviour: #error does not cause SWIG to exit with error */ + #pragma SWIG cpperraswarn=1 + /* Normal behaviour: #error does cause SWIG to exit with error */ + #pragma SWIG cpperraswarn=0 +</PRE> +</DIV><HR NOSHADE> +<H1><A name="Library"></A>8 SWIG library</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Library_nn2">The %include directive and library search + path</A></LI> +<LI><A href="#Library_nn3">C Arrays and Pointers</A> +<UL> +<LI><A href="#Library_nn4">cpointer.i</A></LI> +<LI><A href="#Library_carrays">carrays.i</A></LI> +<LI><A href="#Library_nn6">cmalloc.i</A></LI> +<LI><A href="#Library_nn7">cdata.i</A></LI> +</UL> +</LI> +<LI><A href="#Library_nn8">C String Handling</A> +<UL> +<LI><A href="#Library_nn9">Default string handling</A></LI> +<LI><A href="#Library_nn10">Passing binary data</A></LI> +<LI><A href="#Library_nn11">Using %newobject to release memory</A></LI> +<LI><A href="#Library_nn12">cstring.i</A></LI> +</UL> +</LI> +<LI><A href="#Library_stl_cpp_library">STL/C++ Library</A> +<UL> +<LI><A href="#Library_nn14">std_string.i</A></LI> +<LI><A href="#Library_nn15">std_vector.i</A></LI> +<LI><A href="#Library_stl_exceptions">STL exceptions</A></LI> +</UL> +</LI> +<LI><A href="#Library_nn16">Utility Libraries</A> +<UL> +<LI><A href="#Library_nn17">exception.i</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> To help build extension modules, SWIG is packaged with a library of + support files that you can include in your own interfaces. These files + often define new SWIG directives or provide utility functions that can + be used to access parts of the standard C and C++ libraries. This + chapter provides a reference to the current set of supported library + files.</P> +<P><B> Compatibility note:</B> Older versions of SWIG included a number + of library files for manipulating pointers, arrays, and other + structures. Most these files are now deprecated and have been removed + from the distribution. Alternative libraries provide similar + functionality. Please read this chapter carefully if you used the old + libraries.</P> +<H2><A name="Library_nn2"></A>8.1 The %include directive and library + search path</H2> +<P> Library files are included using the <TT>%include</TT> directive. + When searching for files, directories are searched in the following + order:</P> +<UL> +<LI>The current directory</LI> +<LI>Directories specified with the <TT>-I</TT> command line option</LI> +<LI>.<TT>/swig_lib</TT></LI> +<LI>SWIG library install location as reported by <TT>swig -swiglib</TT>, + for example <TT>/usr/local/share/swig/1.3.30</TT></LI> +<LI>On Windows, a directory <TT>Lib</TT> relative to the location of <TT> +swig.exe</TT> is also searched.</LI> +</UL> +<P> Within each directory, SWIG first looks for a subdirectory + corresponding to a target language (e.g., <TT>python</TT>, <TT>tcl</TT> +, etc.). If found, SWIG will search the language specific directory + first. This allows for language-specific implementations of library + files.</P> +<P> You can ignore the installed SWIG library by setting the <TT> +SWIG_LIB</TT> environment variable. Set the environment variable to hold + an alternative library directory.</P> +<P> The directories that are searched are displayed when using <TT> +-verbose</TT> commandline option.</P> +<H2><A name="Library_nn3"></A>8.2 C Arrays and Pointers</H2> +<P> This section describes library modules for manipulating low-level C + arrays and pointers. The primary use of these modules is in supporting + C declarations that manipulate bare pointers such as <TT>int *</TT>, <TT> +double *</TT>, or <TT>void *</TT>. The modules can be used to allocate + memory, manufacture pointers, dereference memory, and wrap pointers as + class-like objects. Since these functions provide direct access to + memory, their use is potentially unsafe and you should exercise + caution.</P> +<H3><A name="Library_nn4"></A>8.2.1 cpointer.i</H3> +<P> The <TT>cpointer.i</TT> module defines macros that can be used to + used to generate wrappers around simple C pointers. The primary use of + this module is in generating pointers to primitive datatypes such as <TT> +int</TT> and <TT>double</TT>.</P> +<P><B> <TT>%pointer_functions(type,name)</TT></B></P> +<DIV class="indent"> +<P>Generates a collection of four functions for manipulating a pointer <TT> +type *</TT>:</P> +<P> <TT>type *new_name()</TT></P> +<DIV class="indent"> +<P> Creates a new object of type <TT>type</TT> and returns a pointer to + it. In C, the object is created using <TT>calloc()</TT>. In C++, <TT> +new</TT> is used.</P> +</DIV> +<P> <TT>type *copy_name(type value)</TT></P> +<DIV class="indent"> +<P> Creates a new object of type <TT>type</TT> and returns a pointer to + it. An initial value is set by copying it from <TT>value</TT>. In C, + the object is created using <TT>calloc()</TT>. In C++, <TT>new</TT> is + used.</P> +</DIV> +<P> <TT>type *delete_name(type *obj)</TT></P> +<DIV class="indent"> +<P> Deletes an object type <TT>type</TT>.</P> +</DIV> +<P> <TT>void name_assign(type *obj, type value)</TT></P> +<DIV class="indent"> +<P> Assigns <TT>*obj = value</TT>.</P> +</DIV> +<P> <TT>type name_value(type *obj)</TT></P> +<DIV class="indent"> +<P> Returns the value of <TT>*obj</TT>.</P> +</DIV> +<P> When using this macro, <TT>type</TT> may be any type and <TT>name</TT> + must be a legal identifier in the target language. <TT>name</TT> should + not correspond to any other name used in the interface file.</P> +<P> Here is a simple example of using <TT>%pointer_functions()</TT>:</P> +<DIV class="code"> +<PRE> +%module example +%include "cpointer.i" + +/* Create some functions for working with "int *" */ +%pointer_functions(int, intp); + +/* A function that uses an "int *" */ +void add(int x, int y, int *result); +</PRE> +</DIV> +<P> Now, in Python:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> c = example.new_intp() # Create an "int" for storing result +>>> example.add(3,4,c) # Call function +>>> example.intp_value(c) # Dereference +7 +>>> example.delete_intp(c) # Delete +</PRE> +</DIV></DIV> +<P><B> <TT>%pointer_class(type,name)</TT></B></P> +<DIV class="indent"> +<P> Wraps a pointer of <TT>type *</TT> inside a class-based interface. + This interface is as follows:</P> +<DIV class="code"> +<PRE> +struct name { + name(); // Create pointer object + ~name(); // Delete pointer object + void assign(type value); // Assign value + type value(); // Get value + type *cast(); // Cast the pointer to original type + static name *frompointer(type *); // Create class wrapper from existing + // pointer +}; +</PRE> +</DIV> +<P> When using this macro, <TT>type</TT> is restricted to a simple type + name like <TT>int</TT>, <TT>float</TT>, or <TT>Foo</TT>. Pointers and + other complicated types are not allowed. <TT>name</TT> must be a valid + identifier not already in use. When a pointer is wrapped as a class, + the "class" may be transparently passed to any function that expects + the pointer.</P> +<P> If the target language does not support proxy classes, the use of + this macro will produce the example same functions as <TT> +%pointer_functions()</TT> macro.</P> +<P> It should be noted that the class interface does introduce a new + object or wrap a pointer inside a special structure. Instead, the raw + pointer is used directly.</P> +<P> Here is the same example using a class instead:</P> +<DIV class="code"> +<PRE> +%module example +%include "cpointer.i" + +/* Wrap a class interface around an "int *" */ +%pointer_class(int, intp); + +/* A function that uses an "int *" */ +void add(int x, int y, int *result); +</PRE> +</DIV> +<P> Now, in Python (using proxy classes)</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> c = example.intp() # Create an "int" for storing result +>>> example.add(3,4,c) # Call function +>>> c.value() # Dereference +7 +</PRE> +</DIV> +<P> Of the two macros, <TT>%pointer_class</TT> is probably the most + convenient when working with simple pointers. This is because the + pointers are access like objects and they can be easily garbage + collected (destruction of the pointer object destroys the underlying + object).</P> +</DIV> +<P><B> <TT>%pointer_cast(type1, type2, name)</TT></B></P> +<DIV class="indent"> +<P> Creates a casting function that converts <TT>type1</TT> to <TT>type2</TT> +. The name of the function is <TT>name</TT>. For example:</P> +<DIV class="code"> +<PRE> +%pointer_cast(int *, unsigned int *, int_to_uint); +</PRE> +</DIV> +<P> In this example, the function <TT>int_to_uint()</TT> would be used + to cast types in the target language.</P> +</DIV> +<P><B> Note:</B> None of these macros can be used to safely work with + strings (<TT>char *</TT> or <TT>char **</TT>).</P> +<P><B> Note:</B> When working with simple pointers, typemaps can often + be used to provide more seamless operation.</P> +<H3><A name="Library_carrays"></A>8.2.2 carrays.i</H3> +<P> This module defines macros that assist in wrapping ordinary C + pointers as arrays. The module does not provide any safety or an extra + layer of wrapping--it merely provides functionality for creating, + destroying, and modifying the contents of raw C array data.</P> +<P><B> <TT>%array_functions(type,name)</TT></B></P> +<DIV class="indent"> +<P>Creates four functions.</P> +<P> <TT>type *new_name(int nelements)</TT></P> +<DIV class="indent"> +<P> Creates a new array of objects of type <TT>type</TT>. In C, the + array is allocated using <TT>calloc()</TT>. In C++, <TT>new []</TT> is + used.</P> +</DIV> +<P> <TT>type *delete_name(type *ary)</TT></P> +<DIV class="indent"> +<P> Deletes an array. In C, <TT>free()</TT> is used. In C++, <TT>delete + []</TT> is used.</P> +</DIV> +<P> <TT>type name_getitem(type *ary, int index)</TT></P> +<DIV class="indent"> +<P> Returns the value <TT>ary[index]</TT>.</P> +</DIV> +<P> <TT>void name_setitem(type *ary, int index, type value)</TT></P> +<DIV class="indent"> +<P> Assigns <TT>ary[index] = value</TT>.</P> +</DIV> +<P> When using this macro, <TT>type</TT> may be any type and <TT>name</TT> + must be a legal identifier in the target language. <TT>name</TT> should + not correspond to any other name used in the interface file.</P> +<P> Here is an example of <TT>%array_functions()</TT>. Suppose you had a + function like this:</P> +<DIV class="code"> +<PRE> +void print_array(double x[10]) { + int i; + for (i = 0; i < 10; i++) { + printf("[%d] = %g\n", i, x[i]); + } +} +</PRE> +</DIV> +<P> To wrap it, you might write this:</P> +<DIV class="code"> +<PRE> +%module example + +%include "carrays.i" +%array_functions(double, doubleArray); + +void print_array(double x[10]); +</PRE> +</DIV> +<P> Now, in a scripting language, you might write this:</P> +<DIV class="code"> +<PRE> +a = new_doubleArray(10) # Create an array +for i in range(0,10): + doubleArray_setitem(a,i,2*i) # Set a value +print_array(a) # Pass to C +delete_doubleArray(a) # Destroy array +</PRE> +</DIV></DIV> +<P><B> <TT>%array_class(type,name)</TT></B></P> +<DIV class="indent"> +<P> Wraps a pointer of <TT>type *</TT> inside a class-based interface. + This interface is as follows:</P> +<DIV class="code"> +<PRE> +struct name { + name(int nelements); // Create an array + ~name(); // Delete array + type getitem(int index); // Return item + void setitem(int index, type value); // Set item + type *cast(); // Cast to original type + static name *frompointer(type *); // Create class wrapper from + // existing pointer +}; +</PRE> +</DIV> +<P> When using this macro, <TT>type</TT> is restricted to a simple type + name like <TT>int</TT> or <TT>float</TT>. Pointers and other + complicated types are not allowed. <TT>name</TT> must be a valid + identifier not already in use. When a pointer is wrapped as a class, it + can be transparently passed to any function that expects the pointer.</P> +<P> When combined with proxy classes, the <TT>%array_class()</TT> macro + can be especially useful. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "carrays.i" +%array_class(double, doubleArray); + +void print_array(double x[10]); +</PRE> +</DIV> +<P> Allows you to do this:</P> +<DIV class="code"> +<PRE> +import example +c = example.doubleArray(10) # Create double[10] +for i in range(0,10): + c[i] = 2*i # Assign values +example.print_array(c) # Pass to C +</PRE> +</DIV></DIV> +<P><B> Note:</B> These macros do not encapsulate C arrays inside a + special data structure or proxy. There is no bounds checking or safety + of any kind. If you want this, you should consider using a special + array object rather than a bare pointer.</P> +<P><B> Note:</B> <TT>%array_functions()</TT> and <TT>%array_class()</TT> + should not be used with types of <TT>char</TT> or <TT>char *</TT>.</P> +<H3><A name="Library_nn6"></A>8.2.3 cmalloc.i</H3> +<P> This module defines macros for wrapping the low-level C memory + allocation functions <TT>malloc()</TT>, <TT>calloc()</TT>, <TT> +realloc()</TT>, and <TT>free()</TT>.</P> +<P><B> <TT>%malloc(type [,name=type])</TT></B></P> +<DIV class="indent"> +<P> Creates a wrapper around <TT>malloc()</TT> with the following + prototype:</P> +<DIV class="code"> +<PRE> +<EM>type</EM> *malloc_<EM>name</EM>(int nbytes = sizeof(<EM>type</EM>)); +</PRE> +</DIV> +<P> If <TT>type</TT> is <TT>void</TT>, then the size parameter <TT> +nbytes</TT> is required. The <TT>name</TT> parameter only needs to be + specified when wrapping a type that is not a valid identifier (e.g., "<TT> +int *</TT>", "<TT>double **</TT>", etc.).</P> +</DIV> +<P><B> <TT>%calloc(type [,name=type])</TT></B></P> +<DIV class="indent"> +<P> Creates a wrapper around <TT>calloc()</TT> with the following + prototype:</P> +<DIV class="code"> +<PRE> +<EM>type</EM> *calloc_<EM>name</EM>(int nobj =1, int sz = sizeof(<EM>type</EM>)); +</PRE> +</DIV> +<P> If <TT>type</TT> is <TT>void</TT>, then the size parameter <TT>sz</TT> + is required.</P> +</DIV> +<P><B> <TT>%realloc(type [,name=type])</TT></B></P> +<DIV class="indent"> +<P> Creates a wrapper around <TT>realloc()</TT> with the following + prototype:</P> +<DIV class="code"> +<PRE> +<EM>type</EM> *realloc_<EM>name</EM>(<EM>type</EM> *ptr, int nitems); +</PRE> +</DIV> +<P> Note: unlike the C <TT>realloc()</TT>, the wrapper generated by this + macro implicitly includes the size of the corresponding type. For + example, <TT>realloc_int(p, 100)</TT> reallocates <TT>p</TT> so that it + holds 100 integers.</P> +</DIV> +<P><B> <TT>%free(type [,name=type])</TT></B></P> +<DIV class="indent"> +<P> Creates a wrapper around <TT>free()</TT> with the following + prototype:</P> +<DIV class="code"> +<PRE> +void free_<EM>name</EM>(<EM>type</EM> *ptr); +</PRE> +</DIV></DIV> +<P><B> <TT>%sizeof(type [,name=type])</TT></B></P> +<DIV class="indent"> +<P> Creates the constant:</P> +<DIV class="code"> +<PRE> +%constant int sizeof_<EM>name</EM> = sizeof(<EM>type</EM>); +</PRE> +</DIV></DIV> +<P><B> <TT>%allocators(type [,name=type])</TT></B></P> +<DIV class="indent"> +<P> Generates wrappers for all five of the above operations.</P> +</DIV> +<P> Here is a simple example that illustrates the use of these macros:</P> +<DIV class="code"> +<PRE> +// SWIG interface +%module example +%include "cmalloc.i" + +%malloc(int); +%free(int); + +%malloc(int *, intp); +%free(int *, intp); + +%allocators(double); +</PRE> +</DIV> +<P> Now, in a script:</P> +<DIV class="targetlang"> +<PRE> +>>> from example import * +>>> a = malloc_int() +>>> a +'_000efa70_p_int' +>>> free_int(a) +>>> b = malloc_intp() +>>> b +'_000efb20_p_p_int' +>>> free_intp(b) +>>> c = calloc_double(50) +>>> c +'_000fab98_p_double' +>>> c = realloc_double(100000) +>>> free_double(c) +>>> print sizeof_double +8 +>>> +</PRE> +</DIV> +<H3><A name="Library_nn7"></A>8.2.4 cdata.i</H3> +<P> The <TT>cdata.i</TT> module defines functions for converting raw C + data to and from strings in the target language. The primary + applications of this module would be packing/unpacking of binary data + structures---for instance, if you needed to extract data from a buffer. + The target language must support strings with embedded binary data in + order for this to work.</P> +<P><B> <TT>char *cdata(void *ptr, int nbytes)</TT></B></P> +<DIV class="indent"> +<P> Converts <TT>nbytes</TT> of data at <TT>ptr</TT> into a string. <TT> +ptr</TT> can be any pointer.</P> +</DIV> +<P><B> <TT>void memmove(void *ptr, char *s)</TT></B></P> +<DIV class="indent"> +<P> Copies all of the string data in <TT>s</TT> into the memory pointed + to by <TT>ptr</TT>. The string may contain embedded NULL bytes. The + length of the string is implicitly determined in the underlying wrapper + code.</P> +</DIV> +<P> One use of these functions is packing and unpacking data from + memory. Here is a short example:</P> +<DIV class="code"> +<PRE> +// SWIG interface +%module example +%include "carrays.i" +%include "cdata.i" + +%array_class(int, intArray); +</PRE> +</DIV> +<P> Python example:</P> +<DIV class="targetlang"> +<PRE> +>>> a = intArray(10) +>>> for i in range(0,10): +... a[i] = i +>>> b = cdata(a,40) +>>> b +'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04 +\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t' +>>> c = intArray(10) +>>> memmove(c,b) +>>> print c[4] +4 +>>> +</PRE> +</DIV> +<P> Since the size of data is not always known, the following macro is + also defined:</P> +<P><B> <TT>%cdata(type [,name=type])</TT></B></P> +<DIV class="indent"> +<P> Generates the following function for extracting C data for a given + type.</P> +<DIV class="code"> +<PRE> +char *cdata_<EM>name</EM>(type* ptr, int nitems) +</PRE> +</DIV> +<P> <TT>nitems</TT> is the number of items of the given type to extract.</P> +</DIV> +<P><B> Note:</B> These functions provide direct access to memory and can + be used to overwrite data. Clearly they are unsafe.</P> +<H2><A name="Library_nn8"></A>8.3 C String Handling</H2> +<P> A common problem when working with C programs is dealing with + functions that manipulate raw character data using <TT>char *</TT>. In + part, problems arise because there are different interpretations of <TT> +char *</TT>---it could be a NULL-terminated string or it could point to + binary data. Moreover, functions that manipulate raw strings may mutate + data, perform implicit memory allocations, or utilize fixed-sized + buffers.</P> +<P> The problems (and perils) of using <TT>char *</TT> are well-known. + However, SWIG is not in the business of enforcing morality. The modules + in this section provide basic functionality for manipulating raw C + strings.</P> +<H3><A name="Library_nn9"></A>8.3.1 Default string handling</H3> +<P> Suppose you have a C function with this prototype:</P> +<DIV class="code"> +<PRE> +char *foo(char *s); +</PRE> +</DIV> +<P> The default wrapping behavior for this function is to set <TT>s</TT> + to a raw <TT>char *</TT> that refers to the internal string data in the + target language. In other words, if you were using a language like Tcl, + and you wrote this,</P> +<DIV class="code"> +<PRE> +% foo Hello +</PRE> +</DIV> +<P> then <TT>s</TT> would point to the representation of "Hello" inside + the Tcl interpreter. When returning a <TT>char *</TT>, SWIG assumes + that it is a NULL-terminated string and makes a copy of it. This gives + the target language its own copy of the result.</P> +<P> There are obvious problems with the default behavior. First, since a + <TT>char *</TT> argument points to data inside the target language, it + is<B> NOT</B> safe for a function to modify this data (doing so may + corrupt the interpreter and lead to a crash). Furthermore, the default + behavior does not work well with binary data. Instead, strings are + assumed to be NULL-terminated.</P> +<H3><A name="Library_nn10"></A>8.3.2 Passing binary data</H3> +<P> If you have a function that expects binary data,</P> +<DIV class="code"> +<PRE> +int parity(char *str, int len, int initial); +</PRE> +</DIV> +<P> you can wrap the parameters <TT>(char *str, int len)</TT> as a + single argument using a typemap. Just do this:</P> +<DIV class="code"> +<PRE> +%apply (char *STRING, int LENGTH) { (char *str, int len) }; +... +int parity(char *str, int len, int initial); +</PRE> +</DIV> +<P> Now, in the target language, you can use binary string data like + this:</P> +<DIV class="code"> +<PRE> +>>> s = "H\x00\x15eg\x09\x20" +>>> parity(s,0) +</PRE> +</DIV> +<P> In the wrapper function, the passed string will be expanded to a + pointer and length parameter.</P> +<H3><A name="Library_nn11"></A>8.3.3 Using %newobject to release memory</H3> +<P> If you have a function that allocates memory like this,</P> +<DIV class="code"> +<PRE> +char *foo() { + char *result = (char *) malloc(...); + ... + return result; +} +</PRE> +</DIV> +<P> then the SWIG generated wrappers will have a memory leak--the + returned data will be copied into a string object and the old contents + ignored.</P> +<P> To fix the memory leak, use the <TT>%newobject</TT> directive.</P> +<DIV class="code"> +<PRE> +%newobject foo; +... +char *foo(); +</PRE> +</DIV> +<P> This will release the result.</P> +<H3><A name="Library_nn12"></A>8.3.4 cstring.i</H3> +<P> The <TT>cstring.i</TT> library file provides a collection of macros + for dealing with functions that either mutate string arguments or which + try to output string data through their arguments. An example of such a + function might be this rather questionable implementation:</P> +<DIV class="code"> +<PRE> +void get_path(char *s) { + // Potential buffer overflow---uh, oh. + sprintf(s,"%s/%s", base_directory, sub_directory); +} +... +// Somewhere else in the C program +{ + char path[1024]; + ... + get_path(path); + ... +} +</PRE> +</DIV> +<P> (Off topic rant: If your program really has functions like this, you + would be well-advised to replace them with safer alternatives involving + bounds checking).</P> +<P> The macros defined in this module all expand to various combinations + of typemaps. Therefore, the same pattern matching rules and ideas + apply.</P> +<P><B> %cstring_bounded_output(parm, maxsize)</B></P> +<DIV class="indent"> +<P> Turns parameter <TT><EM>parm</EM></TT> into an output value. The + output string is assumed to be NULL-terminated and smaller than <TT><EM> +maxsize</EM></TT> characters. Here is an example:</P> +<DIV class="code"> +<PRE> +%cstring_bounded_output(char *path, 1024); +... +void get_path(char *path); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +>>> get_path() +/home/beazley/packages/Foo/Bar +>>> +</PRE> +</DIV> +<P> Internally, the wrapper function allocates a small buffer (on the + stack) of the requested size and passes it as the pointer value. Data + stored in the buffer is then returned as a function return value. If + the function already returns a value, then the return value and the + output string are returned together (multiple return values).<B> If + more than <TT><EM>maxsize</EM></TT> bytes are written, your program + will crash with a buffer overflow!</B></P> +</DIV> +<P><B> %cstring_chunk_output(parm, chunksize)</B></P> +<DIV class="indent"> +<P> Turns parameter <TT><EM>parm</EM></TT> into an output value. The + output string is always <TT><EM>chunksize</EM></TT> and may contain + binary data. Here is an example:</P> +<DIV class="code"> +<PRE> +%cstring_chunk_output(char *packet, PACKETSIZE); +... +void get_packet(char *packet); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +>>> get_packet() +'\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f\xd3\x99\x14V\xec\x06\xea\xa2\x88' +>>> +</PRE> +</DIV> +<P> This macro is essentially identical to <TT>%cstring_bounded_output</TT> +. The only difference is that the result is always <TT><EM>chunksize</EM> +</TT> characters. Furthermore, the result can contain binary data.<B> If + more than <TT><EM>maxsize</EM></TT> bytes are written, your program + will crash with a buffer overflow!</B></P> +</DIV> +<P><B> %cstring_bounded_mutable(parm, maxsize)</B></P> +<DIV class="indent"> +<P> Turns parameter <TT><EM>parm</EM></TT> into a mutable string + argument. The input string is assumed to be NULL-terminated and smaller + than <TT><EM>maxsize</EM></TT> characters. The output string is also + assumed to be NULL-terminated and less than <TT><EM>maxsize</EM></TT> + characters.</P> +<DIV class="code"> +<PRE> +%cstring_bounded_mutable(char *ustr, 1024); +... +void make_upper(char *ustr); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +>>> make_upper("hello world") +'HELLO WORLD' +>>> +</PRE> +</DIV> +<P> Internally, this macro is almost exactly the same as <TT> +%cstring_bounded_output</TT>. The only difference is that the parameter + accepts an input value that is used to initialize the internal buffer. + It is important to emphasize that this function does not mutate the + string value passed---instead it makes a copy of the input value, + mutates it, and returns it as a result.<B> If more than <TT><EM>maxsize</EM> +</TT> bytes are written, your program will crash with a buffer overflow!</B> +</P> +</DIV> +<P><B> %cstring_mutable(parm [, expansion])</B></P> +<DIV class="indent"> +<P> Turns parameter <TT><EM>parm</EM></TT> into a mutable string + argument. The input string is assumed to be NULL-terminated. An + optional parameter <TT><EM>expansion</EM></TT> specifies the number of + extra characters by which the string might grow when it is modified. + The output string is assumed to be NULL-terminated and less than the + size of the input string plus any expansion characters.</P> +<DIV class="code"> +<PRE> +%cstring_mutable(char *ustr); +... +void make_upper(char *ustr); + +%cstring_mutable(char *hstr, HEADER_SIZE); +... +void attach_header(char *hstr); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +>>> make_upper("hello world") +'HELLO WORLD' +>>> attach_header("Hello world") +'header: Hello world' +>>> +</PRE> +</DIV> +<P> This macro differs from <TT>%cstring_bounded_mutable()</TT> in that + a buffer is dynamically allocated (on the heap using <TT>malloc/new</TT> +). This buffer is always large enough to store a copy of the input value + plus any expansion bytes that might have been requested. It is + important to emphasize that this function does not directly mutate the + string value passed---instead it makes a copy of the input value, + mutates it, and returns it as a result.<B> If the function expands the + result by more than <TT><EM>expansion</EM></TT> extra bytes, then the + program will crash with a buffer overflow!</B></P> +</DIV> +<P><B> %cstring_output_maxsize(parm, maxparm)</B></P> +<DIV class="indent"> +<P> This macro is used to handle bounded character output functions + where both a <TT>char *</TT> and a maximum length parameter are + provided. As input, a user simply supplies the maximum length. The + return value is assumed to be a NULL-terminated string.</P> +<DIV class="code"> +<PRE> +%cstring_output_maxsize(char *path, int maxpath); +... +void get_path(char *path, int maxpath); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +>>> get_path(1024) +'/home/beazley/Packages/Foo/Bar' +>>> +</PRE> +</DIV> +<P> This macro provides a safer alternative for functions that need to + write string data into a buffer. User supplied buffer size is used to + dynamically allocate memory on heap. Results are placed into that + buffer and returned as a string object.</P> +</DIV> +<P><B> %cstring_output_withsize(parm, maxparm)</B></P> +<DIV class="indent"> +<P> This macro is used to handle bounded character output functions + where both a <TT>char *</TT> and a pointer <TT>int *</TT> are passed. + Initially, the <TT>int *</TT> parameter points to a value containing + the maximum size. On return, this value is assumed to contain the + actual number of bytes. As input, a user simply supplies the maximum + length. The output value is a string that may contain binary data.</P> +<DIV class="code"> +<PRE> +%cstring_output_withsize(char *data, int *maxdata); +... +void get_data(char *data, int *maxdata); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +>>> get_data(1024) +'x627388912' +>>> get_data(1024) +'xyzzy' +>>> +</PRE> +</DIV> +<P> This macro is a somewhat more powerful version of <TT> +%cstring_output_chunk()</TT>. Memory is dynamically allocated and can be + arbitrary large. Furthermore, a function can control how much data is + actually returned by changing the value of the <TT>maxparm</TT> + argument.</P> +</DIV> +<P><B> %cstring_output_allocate(parm, release)</B></P> +<DIV class="indent"> +<P> This macro is used to return strings that are allocated within the + program and returned in a parameter of type <TT>char **</TT>. For + example:</P> +<DIV class="code"> +<PRE> +void foo(char **s) { + *s = (char *) malloc(64); + sprintf(*s, "Hello world\n"); +} +</PRE> +</DIV> +<P> The returned string is assumed to be NULL-terminated. <TT><EM> +release</EM></TT> specifies how the allocated memory is to be released + (if applicable). Here is an example:</P> +<DIV class="code"> +<PRE> +%cstring_output_allocate(char **s, free(*$1)); +... +void foo(char **s); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +>>> foo() +'Hello world\n' +>>> +</PRE> +</DIV></DIV> +<P><B> %cstring_output_allocate_size(parm, szparm, release)</B></P> +<DIV class="indent"> +<P> This macro is used to return strings that are allocated within the + program and returned in two parameters of type <TT>char **</TT> and <TT> +int *</TT>. For example:</P> +<DIV class="code"> +<PRE> +void foo(char **s, int *sz) { + *s = (char *) malloc(64); + *sz = 64; + // Write some binary data + ... +} +</PRE> +</DIV> +<P> The returned string may contain binary data. <TT><EM>release</EM></TT> + specifies how the allocated memory is to be released (if applicable). + Here is an example:</P> +<DIV class="code"> +<PRE> +%cstring_output_allocate_size(char **s, int *slen, free(*$1)); +... +void foo(char **s, int *slen); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +>>> foo() +'\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f\xd3\x99\x14V\xec\x06\xea\xa2\x88' +>>> +</PRE> +</DIV> +<P> This is the safest and most reliable way to return binary string + data in SWIG. If you have functions that conform to another prototype, + you might consider wrapping them with a helper function. For example, + if you had this:</P> +<DIV class="code"> +<PRE> +char *get_data(int *len); +</PRE> +</DIV> +<P> You could wrap it with a function like this:</P> +<DIV class="code"> +<PRE> +void my_get_data(char **result, int *len) { + *result = get_data(len); +} +</PRE> +</DIV></DIV> +<P><B> Comments:</B></P> +<UL> +<LI>Support for the <TT>cstring.i</TT> module depends on the target + language. Not all SWIG modules currently support this library.</LI> +<LI>Reliable handling of raw C strings is a delicate topic. There are + many ways to accomplish this in SWIG. This library provides support for + a few common techniques.</LI> +<LI>If used in C++, this library uses <TT>new</TT> and <TT>delete []</TT> + for memory allocation. If using ANSI C, the library uses <TT>malloc()</TT> + and <TT>free()</TT>.</LI> +<LI>Rather than manipulating <TT>char *</TT> directly, you might + consider using a special string structure or class instead.</LI> +</UL> +<H2><A name="Library_stl_cpp_library"></A>8.4 STL/C++ Library</H2> +<P> The library modules in this section provide access to parts of the + standard C++ library including the STL. SWIG support for the STL is an + ongoing effort. Support is quite comprehensive for some language + modules but some of the lesser used modules do not have quite as much + library code written.</P> +<P> The following table shows which C++ classes are supported and the + equivalent SWIG interface library file for the C++ library.</P> +<TABLE BORDER summary="SWIG C++ library files"> +<TR VALIGN="TOP"><TD><B>C++ class</B></TD><TD><B>C++ Library file</B></TD><TD> +<B>SWIG Interface library file</B></TD></TR> +<TR><TD>std::deque</TD><TD>deque</TD><TD>std_deque.i</TD></TR> +<TR><TD>std::list</TD><TD>list</TD><TD>std_list.i</TD></TR> +<TR><TD>std::map</TD><TD>map</TD><TD>std_map.i</TD></TR> +<TR><TD>std::pair</TD><TD>utility</TD><TD>std_pair.i</TD></TR> +<TR><TD>std::set</TD><TD>set</TD><TD>std_set.i</TD></TR> +<TR><TD>std::string</TD><TD>string</TD><TD>std_string.i</TD></TR> +<TR><TD>std::vector</TD><TD>vector</TD><TD>std_vector.i</TD></TR> +</TABLE> +<P> The list is by no means complete; some language modules support a + subset of the above and some support additional STL classes. Please + look for the library files in the appropriate language library + directory.</P> +<H3><A name="Library_nn14"></A>8.4.1 std_string.i</H3> +<P> The <TT>std_string.i</TT> library provides typemaps for converting + C++ <TT>std::string</TT> objects to and from strings in the target + scripting language. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "std_string.i" + +std::string foo(); +void bar(const std::string &x); +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +x = foo(); # Returns a string object +bar("Hello World"); # Pass string as std::string +</PRE> +</DIV> +<P> A common problem that people encounter is that of classes/structures + containing a <TT>std::string</TT>. This can be overcome by defining a + typemap. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "std_string.i" + +%apply const std::string& {std::string* foo}; + +struct my_struct +{ + std::string foo; +}; +</PRE> +</DIV> +<P> In the target language:</P> +<DIV class="targetlang"> +<PRE> +x = my_struct(); +x.foo="Hello World"; # assign with string +print x.foo; # print as string +</PRE> +</DIV> +<P> This module only supports types <TT>std::string</TT> and <TT>const + std::string &</TT>. Pointers and non-const references are left + unmodified and returned as SWIG pointers.</P> +<P> This library file is fully aware of C++ namespaces. If you export <TT> +std::string</TT> or rename it with a typedef, make sure you include + those declarations in your interface. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "std_string.i" + +using namespace std; +typedef std::string String; +... +void foo(string s, const String &t); // std_string typemaps still applied +</PRE> +</DIV> +<P><B> Note:</B> The <TT>std_string</TT> library is incompatible with + Perl on some platforms. We're looking into it.</P> +<H3><A name="Library_nn15"></A>8.4.2 std_vector.i</H3> +<P> The <TT>std_vector.i</TT> library provides support for the C++ <TT> +vector</TT> class in the STL. Using this library involves the use of the + <TT>%template</TT> directive. All you need to do is to instantiate + different versions of <TT>vector</TT> for the types that you want to + use. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "std_vector.i" + +namespace std { + %template(vectori) vector<int>; + %template(vectord) vector<double>; +}; +</PRE> +</DIV> +<P> When a template <TT>vector<X></TT> is instantiated a number of + things happen:</P> +<UL> +<LI>A class that exposes the C++ API is created in the target language . + This can be used to create objects, invoke methods, etc. This class is + currently a subset of the real STL vector class.</LI> +<LI>Input typemaps are defined for <TT>vector<X></TT>, <TT>const + vector<X> &</TT>, and <TT>const vector<X> *</TT>. For each of these, a + pointer <TT>vector<X> *</TT> may be passed or a native list object in + the target language.</LI> +<LI>An output typemap is defined for <TT>vector<X></TT>. In this case, + the values in the vector are expanded into a list object in the target + language.</LI> +<LI>For all other variations of the type, the wrappers expect to receive + a <TT>vector<X> *</TT> object in the usual manner.</LI> +<LI>An exception handler for <TT>std::out_of_range</TT> is defined.</LI> +<LI>Optionally, special methods for indexing, item retrieval, slicing, + and element assignment may be defined. This depends on the target + language.</LI> +</UL> +<P> To illustrate the use of this library, consider the following + functions:</P> +<DIV class="code"> +<PRE> +/* File : example.h */ + +#include <vector> +#include <algorithm> +#include <functional> +#include <numeric> + +double average(std::vector<int> v) { + return std::accumulate(v.begin(),v.end(),0.0)/v.size(); +} + +std::vector<double> half(const std::vector<double>& v) { + std::vector<double> w(v); + for (unsigned int i=0; i<w.size(); i++) + w[i] /= 2.0; + return w; +} + +void halve_in_place(std::vector<double>& v) { + std::transform(v.begin(),v.end(),v.begin(), + std::bind2nd(std::divides<double>(),2.0)); +} +</PRE> +</DIV> +<P> To wrap with SWIG, you might write the following:</P> +<DIV class="code"> +<PRE> +%module example +%{ +#include "example.h" +%} + +%include "std_vector.i" +// Instantiate templates used by example +namespace std { + %template(IntVector) vector<int>; + %template(DoubleVector) vector<double>; +} + +// Include the header file with above prototypes +%include "example.h" +</PRE> +</DIV> +<P> Now, to illustrate the behavior in the scripting interpreter, + consider this Python example:</P> +<DIV class="targetlang"> +<PRE> +>>> from example import * +>>> iv = IntVector(4) # Create an vector<int> +>>> for i in range(0,4): +... iv[i] = i +>>> average(iv) # Call method +1.5 +>>> average([0,1,2,3]) # Call with list +1.5 +>>> half([1,2,3]) # Half a list +(0.5,1.0,1.5) +>>> halve_in_place([1,2,3]) # Oops +Traceback (most recent call last): + File "<stdin>", line 1, in ? +TypeError: Type error. Expected _p_std__vectorTdouble_t +>>> dv = DoubleVector(4) +>>> for i in range(0,4): +... dv[i] = i +>>> halve_in_place(dv) # Ok +>>> for i in dv: +... print i +... +0.0 +0.5 +1.0 +1.5 +>>> dv[20] = 4.5 +Traceback (most recent call last): + File "<stdin>", line 1, in ? + File "example.py", line 81, in __setitem__ + def __setitem__(*args): return apply(examplec.DoubleVector___setitem__,args) +IndexError: vector index out of range +>>> +</PRE> +</DIV> +<P> This library module is fully aware of C++ namespaces. If you use + vectors with other names, make sure you include the appropriate <TT> +using</TT> or typedef directives. For example:</P> +<DIV class="code"> +<PRE> +%include "std_vector.i" + +namespace std { + %template(IntVector) vector<int>; +} + +using namespace std; +typedef std::vector Vector; + +void foo(vector<int> *x, const Vector &x); +</PRE> +</DIV> +<P><B> Note:</B> This module makes use of several advanced SWIG features + including templatized typemaps and template partial specialization. If + you are trying to wrap other C++ code with templates, you might look at + the code contained in <TT>std_vector.i</TT>. Alternatively, you can + show them the code if you want to make their head explode.</P> +<P><B> Note:</B> This module is defined for all SWIG target languages. + However argument conversion details and the public API exposed to the + interpreter vary.</P> +<P><B> Note:</B> <TT>std_vector.i</TT> was written by Luigi "The + Amazing" Ballabio.</P> +<H3><A name="Library_stl_exceptions"></A>8.4.3 STL exceptions</H3> +<P> Many of the STL wrapper functions add parameter checking and will + throw a language dependent error/exception should the values not be + valid. The classic example is array bounds checking. The library + wrappers are written to throw a C++ exception in the case of error. The + C++ exception in turn gets converted into an appropriate + error/exception for the target language. By and large this handling + should not need customising, however, customisation can easily be + achieved by supplying appropriate "throws" typemaps. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "std_vector.i" +%typemap(throws) std::out_of_range { + // custom exception handler +} +%template(VectInt) std::vector<int>; +</PRE> +</DIV> +<P> The custom exception handler might, for example, log the exception + then convert it into a specific error/exception for the target + language.</P> +<P> When using the STL it is advisable to add in an exception handler to + catch all STL exceptions. The <TT>%exception</TT> directive can be used + by placing the following code before any other methods or libraries to + be wrapped:</P> +<DIV class="code"> +<PRE> +%include "exception.i" + +%exception { + try { + $action + } catch (const std::exception& e) { + SWIG_exception(SWIG_RuntimeError, e.what()); + } +} +</PRE> +</DIV> +<P> Any thrown STL exceptions will then be gracefully handled instead of + causing a crash.</P> +<H2><A name="Library_nn16"></A>8.5 Utility Libraries</H2> +<H3><A name="Library_nn17"></A>8.5.1 exception.i</H3> +<P> The <TT>exception.i</TT> library provides a language-independent + function for raising a run-time exception in the target language. This + library is largely used by the SWIG library writers. If possible, use + the error handling scheme available to your target language as there is + greater flexibility in what errors/exceptions can be thrown.</P> +<P><B> <TT>SWIG_exception(int code, const char *message)</TT></B></P> +<DIV class="indent"> +<P> Raises an exception in the target language. <TT>code</TT> is one of + the following symbolic constants:</P> +<DIV class="code"> +<PRE> +SWIG_MemoryError +SWIG_IOError +SWIG_RuntimeError +SWIG_IndexError +SWIG_TypeError +SWIG_DivisionByZero +SWIG_OverflowError +SWIG_SyntaxError +SWIG_ValueError +SWIG_SystemError +</PRE> +</DIV> +<P> <TT>message</TT> is a string indicating more information about the + problem.</P> +</DIV> +<P> The primary use of this module is in writing language-independent + exception handlers. For example:</P> +<DIV class="code"> +<PRE> +%include "exception.i" +%exception std::vector::getitem { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what())); + } +} +</PRE> +</DIV><HR NOSHADE> +<H1><A name="Arguments"></A>9 Argument Handling</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Arguments_nn2">The typemaps.i library</A> +<UL> +<LI><A href="#Arguments_nn3">Introduction</A></LI> +<LI><A href="#Arguments_nn4">Input parameters</A></LI> +<LI><A href="#Arguments_nn5">Output parameters</A></LI> +<LI><A href="#Arguments_nn6">Input/Output parameters</A></LI> +<LI><A href="#Arguments_nn7">Using different names</A></LI> +</UL> +</LI> +<LI><A href="#Arguments_nn8">Applying constraints to input values</A> +<UL> +<LI><A href="#Arguments_nn9">Simple constraint example</A></LI> +<LI><A href="#Arguments_nn10">Constraint methods</A></LI> +<LI><A href="#Arguments_nn11">Applying constraints to new datatypes</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> In Chapter 3, SWIG's treatment of basic datatypes and pointers was + described. In particular, primitive types such as <TT>int</TT> and <TT> +double</TT> are mapped to corresponding types in the target language. + For everything else, pointers are used to refer to structures, classes, + arrays, and other user-defined datatypes. However, in certain + applications it is desirable to change SWIG's handling of a specific + datatype. For example, you might want to return multiple values through + the arguments of a function. This chapter describes some of the + techniques for doing this.</P> +<H2><A name="Arguments_nn2"></A>9.1 The typemaps.i library</H2> +<P> This section describes the <TT>typemaps.i</TT> library + file--commonly used to change certain properties of argument + conversion.</P> +<H3><A name="Arguments_nn3"></A>9.1.1 Introduction</H3> +<P> Suppose you had a C function like this:</P> +<DIV class="code"> +<PRE> +void add(double a, double b, double *result) { + *result = a + b; +} +</PRE> +</DIV> +<P> From reading the source code, it is clear that the function is + storing a value in the <TT>double *result</TT> parameter. However, + since SWIG does not examine function bodies, it has no way to know that + this is the underlying behavior.</P> +<P> One way to deal with this is to use the <TT>typemaps.i</TT> library + file and write interface code like this:</P> +<DIV class="code"> +<PRE> +// Simple example using typemaps +%module example +%include "typemaps.i" + +%apply double *OUTPUT { double *result }; +%inlne %{ +extern void add(double a, double b, double *result); +%} +</PRE> +</DIV> +<P> The <TT>%apply</TT> directive tells SWIG that you are going to apply + a special type handling rule to a type. The "<TT>double *OUTPUT</TT>" + specification is the name of a rule that defines how to return an + output value from an argument of type <TT>double *</TT>. This rule gets + applied to all of the datatypes listed in curly braces-- in this case "<TT> +double *result</TT>".</P> +<P> When the resulting module is created, you can now use the function + like this (shown for Python):</P> +<DIV class="targetlang"> +<PRE> +>>> a = add(3,4) +>>> print a +7 +>>> +</PRE> +</DIV> +<P> In this case, you can see how the output value normally returned in + the third argument has magically been transformed into a function + return value. Clearly this makes the function much easier to use since + it is no longer necessary to manufacture a special <TT>double *</TT> + object and pass it to the function somehow.</P> +<P> Once a typemap has been applied to a type, it stays in effect for + all future occurrences of the type and name. For example, you could + write the following:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +%apply double *OUTPUT { double *result }; + +%inline %{ +extern void add(double a, double b, double *result); +extern void sub(double a, double b, double *result); +extern void mul(double a, double b, double *result); +extern void div(double a, double b, double *result); +%} +... +</PRE> +</DIV> +<P> In this case, the <TT>double *OUTPUT</TT> rule is applied to all of + the functions that follow.</P> +<P> Typemap transformations can even be extended to multiple return + values. For example, consider this code:</P> +<DIV class="code"> +<PRE> +%include "typemaps.i" +%apply int *OUTPUT { int *width, int *height }; + +// Returns a pair (width,height) +void getwinsize(int winid, int *width, int *height); +</PRE> +</DIV> +<P> In this case, the function returns multiple values, allowing it to + be used like this:</P> +<DIV class="targetlang"> +<PRE> +>>> w,h = genwinsize(wid) +>>> print w +400 +>>> print h +300 +>>> +</PRE> +</DIV> +<P> It should also be noted that although the <TT>%apply</TT> directive + is used to associate typemap rules to datatypes, you can also use the + rule names directly in arguments. For example, you could write this:</P> +<DIV class="code"> +<PRE> +// Simple example using typemaps +%module example +%include "typemaps.i" + +%{ +extern void add(double a, double b, double *OUTPUT); +%} +extern void add(double a, double b, double *OUTPUT); +</PRE> +</DIV> +<P> Typemaps stay in effect until they are explicitly deleted or + redefined to something else. To clear a typemap, the <TT>%clear</TT> + directive should be used. For example:</P> +<DIV class="code"> +<PRE> +%clear double *result; // Remove all typemaps for double *result +</PRE> +</DIV> +<H3><A name="Arguments_nn4"></A>9.1.2 Input parameters</H3> +<P> The following typemaps instruct SWIG that a pointer really only + holds a single input value:</P> +<DIV class="code"> +<PRE> +int *INPUT +short *INPUT +long *INPUT +unsigned int *INPUT +unsigned short *INPUT +unsigned long *INPUT +double *INPUT +float *INPUT +</PRE> +</DIV> +<P> When used, it allows values to be passed instead of pointers. For + example, consider this function:</P> +<DIV class="code"> +<PRE> +double add(double *a, double *b) { + return *a+*b; +} +</PRE> +</DIV> +<P> Now, consider this SWIG interface:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +... +%{ +extern double add(double *, double *); +%} +extern double add(double *INPUT, double *INPUT); + +</PRE> +</DIV> +<P> When the function is used in the scripting language interpreter, it + will work like this:</P> +<DIV class="targetlang"> +<PRE> +result = add(3,4) +</PRE> +</DIV> +<H3><A name="Arguments_nn5"></A>9.1.3 Output parameters</H3> +<P> The following typemap rules tell SWIG that pointer is the output + value of a function. When used, you do not need to supply the argument + when calling the function. Instead, one or more output values are + returned.</P> +<DIV class="code"> +<PRE> +int *OUTPUT +short *OUTPUT +long *OUTPUT +unsigned int *OUTPUT +unsigned short *OUTPUT +unsigned long *OUTPUT +double *OUTPUT +float *OUTPUT + +</PRE> +</DIV> +<P> These methods can be used as shown in an earlier example. For + example, if you have this C function :</P> +<DIV class="code"> +<PRE> +void add(double a, double b, double *c) { + *c = a+b; +} +</PRE> +</DIV> +<P> A SWIG interface file might look like this :</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +... +%inline %{ +extern void add(double a, double b, double *OUTPUT); +%} + +</PRE> +</DIV> +<P> In this case, only a single output value is returned, but this is + not a restriction. An arbitrary number of output values can be returned + by applying the output rules to more than one argument (as shown + previously).</P> +<P> If the function also returns a value, it is returned along with the + argument. For example, if you had this:</P> +<DIV class="code"> +<PRE> +extern int foo(double a, double b, double *OUTPUT); +</PRE> +</DIV> +<P> The function will return two values like this:</P> +<DIV class="targetlang"> +<PRE> +iresult, dresult = foo(3.5, 2) +</PRE> +</DIV> +<H3><A name="Arguments_nn6"></A>9.1.4 Input/Output parameters</H3> +<P> When a pointer serves as both an input and output value you can use + the following typemaps :</P> +<DIV class="code"> +<PRE> +int *INOUT +short *INOUT +long *INOUT +unsigned int *INOUT +unsigned short *INOUT +unsigned long *INOUT +double *INOUT +float *INOUT + +</PRE> +</DIV> +<P> A C function that uses this might be something like this:</P> +<DIV class="code"> +<PRE> +void negate(double *x) { + *x = -(*x); +} + +</PRE> +</DIV> +<P> To make x function as both and input and output value, declare the + function like this in an interface file :</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +... +%{ +extern void negate(double *); +%} +extern void negate(double *INOUT); + +</PRE> +</DIV> +<P> Now within a script, you can simply call the function normally :</P> +<DIV class="targetlang"> +<PRE> +a = negate(3); # a = -3 after calling this +</PRE> +</DIV> +<P> One subtle point of the <TT>INOUT</TT> rule is that many scripting + languages enforce mutability constraints on primitive objects (meaning + that simple objects like integers and strings aren't supposed to + change). Because of this, you can't just modify the object's value in + place as the underlying C function does in this example. Therefore, the + <TT>INOUT</TT> rule returns the modified value as a new object rather + than directly overwriting the value of the original input object.</P> +<P><B> Compatibility note :</B> The <TT>INOUT</TT> rule used to be known + as <TT>BOTH</TT> in earlier versions of SWIG. Backwards compatibility + is preserved, but deprecated.</P> +<H3><A name="Arguments_nn7"></A>9.1.5 Using different names</H3> +<P> As previously shown, the <TT>%apply</TT> directive can be used to + apply the <TT>INPUT</TT>, <TT>OUTPUT</TT>, and <TT>INOUT</TT> typemaps + to different argument names. For example:</P> +<DIV class="code"> +<PRE> +// Make double *result an output value +%apply double *OUTPUT { double *result }; + +// Make Int32 *in an input value +%apply int *INPUT { Int32 *in }; + +// Make long *x inout +%apply long *INOUT {long *x}; + +</PRE> +</DIV> +<P> To clear a rule, the <TT>%clear</TT> directive is used:</P> +<DIV class="code"> +<PRE> +%clear double *result; +%clear Int32 *in, long *x; +</PRE> +</DIV> +<P> Typemap declarations are lexically scoped so a typemap takes effect + from the point of definition to the end of the file or a matching <TT> +%clear</TT> declaration.</P> +<H2><A name="Arguments_nn8"></A>9.2 Applying constraints to input values</H2> +<P> In addition to changing the handling of various input values, it is + also possible to use typemaps to apply constraints. For example, maybe + you want to insure that a value is positive, or that a pointer is + non-NULL. This can be accomplished including the <TT>constraints.i</TT> + library file.</P> +<H3><A name="Arguments_nn9"></A>9.2.1 Simple constraint example</H3> +<P> The constraints library is best illustrated by the following + interface file :</P> +<DIV class="code"> +<PRE> +// Interface file with constraints +%module example +%include "constraints.i" + +double exp(double x); +double log(double POSITIVE); // Allow only positive values +double sqrt(double NONNEGATIVE); // Non-negative values only +double inv(double NONZERO); // Non-zero values +void free(void *NONNULL); // Non-NULL pointers only + +</PRE> +</DIV> +<P> The behavior of this file is exactly as you would expect. If any of + the arguments violate the constraint condition, a scripting language + exception will be raised. As a result, it is possible to catch bad + values, prevent mysterious program crashes and so on.</P> +<H3><A name="Arguments_nn10"></A>9.2.2 Constraint methods</H3> +<P> The following constraints are currently available</P> +<DIV class="code"> +<PRE> +POSITIVE Any number > 0 (not zero) +NEGATIVE Any number < 0 (not zero) +NONNEGATIVE Any number >= 0 +NONPOSITIVE Any number <= 0 +NONZERO Nonzero number +NONNULL Non-NULL pointer (pointers only). + +</PRE> +</DIV> +<H3><A name="Arguments_nn11"></A>9.2.3 Applying constraints to new + datatypes</H3> +<P> The constraints library only supports the primitive C datatypes, but + it is easy to apply it to new datatypes using <TT>%apply</TT>. For + example :</P> +<DIV class="code"> +<PRE> +// Apply a constraint to a Real variable +%apply Number POSITIVE { Real in }; + +// Apply a constraint to a pointer type +%apply Pointer NONNULL { Vector * }; + +</PRE> +</DIV> +<P> The special types of "Number" and "Pointer" can be applied to any + numeric and pointer variable type respectively. To later remove a + constraint, the <TT>%clear</TT> directive can be used :</P> +<DIV class="code"> +<PRE> +%clear Real in; +%clear Vector *; +</PRE> +</DIV><HR NOSHADE> +<H1><A name="Typemaps"></A>10 Typemaps</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Typemaps_nn2">Introduction</A> +<UL> +<LI><A href="#Typemaps_nn3">Type conversion</A></LI> +<LI><A href="#Typemaps_nn4">Typemaps</A></LI> +<LI><A href="#Typemaps_nn5">Pattern matching</A></LI> +<LI><A href="#Typemaps_nn6">Reusing typemaps</A></LI> +<LI><A href="#Typemaps_nn7">What can be done with typemaps?</A></LI> +<LI><A href="#Typemaps_nn8">What can't be done with typemaps?</A></LI> +<LI><A href="#Typemaps_nn9">The rest of this chapter</A></LI> +</UL> +</LI> +<LI><A href="#Typemaps_nn10">Typemap specifications</A> +<UL> +<LI><A href="#Typemaps_defining">Defining a typemap</A></LI> +<LI><A href="#Typemaps_nn12">Typemap scope</A></LI> +<LI><A href="#Typemaps_nn13">Copying a typemap</A></LI> +<LI><A href="#Typemaps_nn14">Deleting a typemap</A></LI> +<LI><A href="#Typemaps_nn15">Placement of typemaps</A></LI> +</UL> +</LI> +<LI><A href="#Typemaps_pattern_matching">Pattern matching rules</A> +<UL> +<LI><A href="#Typemaps_nn17">Basic matching rules</A></LI> +<LI><A href="#Typemaps_nn18">Typedef reductions</A></LI> +<LI><A href="#Typemaps_nn19">Default typemaps</A></LI> +<LI><A href="#Typemaps_mixed_default">Mixed default typemaps</A></LI> +<LI><A href="#Typemaps_nn20">Multi-arguments typemaps</A></LI> +</UL> +</LI> +<LI><A href="#Typemaps_nn21">Code generation rules</A> +<UL> +<LI><A href="#Typemaps_nn22">Scope</A></LI> +<LI><A href="#Typemaps_nn23">Declaring new local variables</A></LI> +<LI><A href="#Typemaps_special_variables">Special variables</A></LI> +<LI><A href="#Typemaps_special_variable_macros">Special variable macros</A> +<UL> +<LI><A href="#Typemaps_special_macro_descriptor">$descriptor(type)</A></LI> +<LI><A href="#Typemaps_special_macro_typemap">$typemap(method, + typepattern)</A></LI> +</UL> +</LI> +</UL> +</LI> +<LI><A href="#Typemaps_nn25">Common typemap methods</A> +<UL> +<LI><A href="#Typemaps_nn26">"in" typemap</A></LI> +<LI><A href="#Typemaps_nn27">"typecheck" typemap</A></LI> +<LI><A href="#Typemaps_nn28">"out" typemap</A></LI> +<LI><A href="#Typemaps_nn29">"arginit" typemap</A></LI> +<LI><A href="#Typemaps_nn30">"default" typemap</A></LI> +<LI><A href="#Typemaps_nn31">"check" typemap</A></LI> +<LI><A href="#Typemaps_nn32">"argout" typemap</A></LI> +<LI><A href="#Typemaps_nn33">"freearg" typemap</A></LI> +<LI><A href="#Typemaps_nn34">"newfree" typemap</A></LI> +<LI><A href="#Typemaps_nn35">"memberin" typemap</A></LI> +<LI><A href="#Typemaps_nn36">"varin" typemap</A></LI> +<LI><A href="#Typemaps_nn37">"varout" typemap</A></LI> +<LI><A href="#throws_typemap">"throws" typemap</A></LI> +</UL> +</LI> +<LI><A href="#Typemaps_nn39">Some typemap examples</A> +<UL> +<LI><A href="#Typemaps_nn40">Typemaps for arrays</A></LI> +<LI><A href="#Typemaps_nn41">Implementing constraints with typemaps</A></LI> +</UL> +</LI> +<LI><A href="#Typemaps_nn43">Typemaps for multiple languages</A></LI> +<LI><A href="#Typemaps_optimal">Optimal code generation when returning + by value</A></LI> +<LI><A href="#Typemaps_multi_argument_typemaps">Multi-argument typemaps</A> +</LI> +<LI><A href="#runtime_type_checker">The run-time type checker</A> +<UL> +<LI><A href="#Typemaps_nn45">Implementation</A></LI> +<LI><A href="#Typemaps_runtime_type_checker_usage">Usage</A></LI> +</UL> +</LI> +<LI><A href="#Typemaps_overloading">Typemaps and overloading</A></LI> +<LI><A href="#Typemaps_nn48">More about <TT>%apply</TT> and <TT>%clear</TT> +</A></LI> +<LI><A href="#Typemaps_nn49">Reducing wrapper code size</A></LI> +<LI><A href="#Typemaps_nn47">Passing data between typemaps</A></LI> +<LI><A href="#Typemaps_nn52">C++ "this" pointer</A></LI> +<LI><A href="#Typemaps_nn51">Where to go for more information?</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<H2><A name="Typemaps_nn2"></A>10.1 Introduction</H2> +<P> Chances are, you are reading this chapter for one of two reasons; + you either want to customize SWIG's behavior or you overheard someone + mumbling some incomprehensible drivel about "typemaps" and you asked + yourself "typemaps, what are those?" That said, let's start with a + short disclaimer that "typemaps" are an advanced customization feature + that provide direct access to SWIG's low-level code generator. Not only + that, they are an integral part of the SWIG C++ type system (a + non-trivial topic of its own). Typemaps are generally<EM> not</EM> a + required part of using SWIG. Therefore, you might want to re-read the + earlier chapters if you have found your way to this chapter with only a + vague idea of what SWIG already does by default.</P> +<H3><A name="Typemaps_nn3"></A>10.1.1 Type conversion</H3> +<P> One of the most important problems in wrapper code generation is the + conversion of datatypes between programming languages. Specifically, + for every C/C++ declaration, SWIG must somehow generate wrapper code + that allows values to be passed back and forth between languages. Since + every programming language represents data differently, this is not a + simple of matter of simply linking code together with the C linker. + Instead, SWIG has to know something about how data is represented in + each language and how it can be manipulated.</P> +<P> To illustrate, suppose you had a simple C function like this:</P> +<DIV class="code"> +<PRE> +int factorial(int n); +</PRE> +</DIV> +<P> To access this function from Python, a pair of Python API functions + are used to convert integer values. For example:</P> +<DIV class="code"> +<PRE> +long PyInt_AsLong(PyObject *obj); /* Python --> C */ +PyObject *PyInt_FromLong(long x); /* C --> Python */ +</PRE> +</DIV> +<P> The first function is used to convert the input argument from a + Python integer object to C <TT>long</TT>. The second function is used + to convert a value from C back into a Python integer object.</P> +<P> Inside the wrapper function, you might see these functions used like + this:</P> +<DIV class="code"> +<PRE> +PyObject *wrap_factorial(PyObject *self, PyObject *args) { + int arg1; + int result; + PyObject *obj1; + PyObject *resultobj; + + if (!PyArg_ParseTuple("O:factorial", &obj1)) return NULL; + <B>arg1 = PyInt_AsLong(obj1);</B> + result = factorial(arg1); + <B>resultobj = PyInt_FromLong(result);</B> + return resultobj; +} +</PRE> +</DIV> +<P> Every target language supported by SWIG has functions that work in a + similar manner. For example, in Perl, the following functions are used:</P> +<DIV class="code"> +<PRE> +IV SvIV(SV *sv); /* Perl --> C */ +void sv_setiv(SV *sv, IV val); /* C --> Perl */ +</PRE> +</DIV> +<P> In Tcl:</P> +<DIV class="code"> +<PRE> +int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *obj, long *value); +Tcl_Obj *Tcl_NewIntObj(long value); +</PRE> +</DIV> +<P> The precise details are not so important. What is important is that + all of the underlying type conversion is handled by collections of + utility functions and short bits of C code like this---you simply have + to read the extension documentation for your favorite language to know + how it works (an exercise left to the reader).</P> +<H3><A name="Typemaps_nn4"></A>10.1.2 Typemaps</H3> +<P> Since type handling is so central to wrapper code generation, SWIG + allows it to be completely defined (or redefined) by the user. To do + this, a special <TT>%typemap</TT> directive is used. For example:</P> +<DIV class="code"> +<PRE> +/* Convert from Python --> C */ +%typemap(in) int { + $1 = PyInt_AsLong($input); +} + +/* Convert from C --> Python */ +%typemap(out) int { + $result = PyInt_FromLong($1); +} +</PRE> +</DIV> +<P> At first glance, this code will look a little confusing. However, + there is really not much to it. The first typemap (the "in" typemap) is + used to convert a value from the target language to C. The second + typemap (the "out" typemap) is used to convert in the other direction. + The content of each typemap is a small fragment of code that is + inserted directly into the SWIG generated wrapper functions. The code + is usually C or C++ code which will be generated into the C/C++ wrapper + functions. Note that this isn't always the case as some target language + modules allow target language code within the typemaps which gets + generated into target language specific files. Within this code, a + number of special variables prefixed with a $ are expanded. These are + really just placeholders for C/C++ variables that are generated in the + course of creating the wrapper function. In this case, <TT>$input</TT> + refers to an input object that needs to be converted to C/C++ and <TT> +$result</TT> refers to an object that is going to be returned by a + wrapper function. <TT>$1</TT> refers to a C/C++ variable that has the + same type as specified in the typemap declaration (an <TT>int</TT> in + this example).</P> +<P> A short example might make this a little more clear. If you were + wrapping a function like this:</P> +<DIV class="code"> +<PRE> +int gcd(int x, int y); +</PRE> +</DIV> +<P> A wrapper function would look approximately like this:</P> +<DIV class="code"> +<PRE> +PyObject *wrap_gcd(PyObject *self, PyObject *args) { + int arg1; + int arg2; + int result; + PyObject *obj1; + PyObject *obj2; + PyObject *resultobj; + + if (!PyArg_ParseTuple("OO:gcd", &obj1, &obj2)) return NULL; + + /* "in" typemap, argument 1 */<B> + { + arg1 = PyInt_AsLong(obj1); + } +</B> + /* "in" typemap, argument 2 */<B> + { + arg2 = PyInt_AsLong(obj2); + } +</B> + result = gcd(arg1,arg2); + + /* "out" typemap, return value */<B> + { + resultobj = PyInt_FromLong(result); + } +</B> + return resultobj; +} +</PRE> +</DIV> +<P> In this code, you can see how the typemap code has been inserted + into the function. You can also see how the special $ variables have + been expanded to match certain variable names inside the wrapper + function. This is really the whole idea behind typemaps--they simply + let you insert arbitrary code into different parts of the generated + wrapper functions. Because arbitrary code can be inserted, it possible + to completely change the way in which values are converted.</P> +<H3><A name="Typemaps_nn5"></A>10.1.3 Pattern matching</H3> +<P> As the name implies, the purpose of a typemap is to "map" C + datatypes to types in the target language. Once a typemap is defined + for a C datatype, it is applied to all future occurrences of that type + in the input file. For example:</P> +<DIV class="code"> +<PRE> +/* Convert from Perl --> C */ +%typemap(in) <B>int</B> { + $1 = SvIV($input); +} + +... +int factorial(<B>int</B> n); +int gcd(<B>int</B> x, <B>int</B> y); +int count(char *s, char *t, <B>int</B> max); +</PRE> +</DIV> +<P> The matching of typemaps to C datatypes is more than a simple + textual match. In fact, typemaps are fully built into the underlying + type system. Therefore, typemaps are unaffected by <TT>typedef</TT>, + namespaces, and other declarations that might hide the underlying type. + For example, you could have code like this:</P> +<DIV class="code"> +<PRE> +/* Convert from Ruby--> C */ +%typemap(in) <B>int</B> { + $1 = NUM2INT($input); +} +... +typedef int Integer; +namespace foo { + typedef Integer Number; +}; + +int foo(<B>int</B> x); +int bar(<B>Integer</B> y); +int spam(<B>foo::Number</B> a, <B>foo::Number</B> b); +</PRE> +</DIV> +<P> In this case, the typemap is still applied to the proper arguments + even though typenames don't always match the text "int". This ability + to track types is a critical part of SWIG--in fact, all of the target + language modules work merely define a set of typemaps for the basic + types. Yet, it is never necessary to write new typemaps for typenames + introduced by <TT>typedef</TT>.</P> +<P> In addition to tracking typenames, typemaps may also be specialized + to match against a specific argument name. For example, you could write + a typemap like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) <B>double nonnegative</B> { + $1 = PyFloat_AsDouble($input); + if ($1 < 0) { + PyErr_SetString(PyExc_ValueError,"argument must be nonnegative."); + return NULL; + } +} + +... +double sin(double x); +double cos(double x); +double sqrt(<B>double nonnegative</B>); + +typedef double Real; +double log(<B>Real nonnegative</B>); +... +</PRE> +</DIV> +<P> For certain tasks such as input argument conversion, typemaps can be + defined for sequences of consecutive arguments. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (<B>char *str, int len</B>) { + $1 = PyString_AsString($input); /* char *str */ + $2 = PyString_Size($input); /* int len */ +} +... +int count(<B>char *str, int len</B>, char c); +</PRE> +</DIV> +<P> In this case, a single input object is expanded into a pair of C + arguments. This example also provides a hint to the unusual variable + naming scheme involving <TT>$1</TT>, <TT>$2</TT>, and so forth.</P> +<H3><A name="Typemaps_nn6"></A>10.1.4 Reusing typemaps</H3> +<P> Typemaps are normally defined for specific type and argument name + patterns. However, typemaps can also be copied and reused. One way to + do this is to use assignment like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) Integer = int; +%typemap(in) (char *buffer, int size) = (char *str, int len); +</PRE> +</DIV> +<P> A more general form of copying is found in the <TT>%apply</TT> + directive like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) int { + /* Convert an integer argument */ + ... +} +%typemap(out) int { + /* Return an integer value */ + ... +} + +/* Apply all of the integer typemaps to size_t */ +%apply int { size_t }; +</PRE> +</DIV> +<P> <TT>%apply</TT> merely takes<EM> all</EM> of the typemaps that are + defined for one type and applies them to other types. Note: you can + include a comma separated set of types in the <TT>{ ... }</TT> part of <TT> +%apply</TT>.</P> +<P> It should be noted that it is not necessary to copy typemaps for + types that are related by <TT>typedef</TT>. For example, if you have + this,</P> +<DIV class="code"> +<PRE> +typedef int size_t; +</PRE> +</DIV> +<P> then SWIG already knows that the <TT>int</TT> typemaps apply. You + don't have to do anything.</P> +<H3><A name="Typemaps_nn7"></A>10.1.5 What can be done with typemaps?</H3> +<P> The primary use of typemaps is for defining wrapper generation + behavior at the level of individual C/C++ datatypes. There are + currently six general categories of problems that typemaps address:</P> +<P><B> Argument handling</B></P> +<DIV class="code"> +<PRE> +int foo(<B>int x, double y, char *s</B>); +</PRE> +</DIV> +<UL> +<LI>Input argument conversion ("in" typemap).</LI> +<LI>Input argument type checking ("typecheck" typemap).</LI> +<LI>Output argument handling ("argout" typemap).</LI> +<LI>Input argument value checking ("check" typemap).</LI> +<LI>Input argument initialization ("arginit" typemap).</LI> +<LI>Default arguments ("default" typemap).</LI> +<LI>Input argument resource management ("freearg" typemap).</LI> +</UL> +<P><B> Return value handling</B></P> +<DIV class="code"> +<PRE> +<B>int</B> foo(int x, double y, char *s); +</PRE> +</DIV> +<UL> +<LI>Function return value conversion ("out" typemap).</LI> +<LI>Return value resource management ("ret" typemap).</LI> +<LI>Resource management for newly allocated objects ("newfree" typemap).</LI> +</UL> +<P><B> Exception handling</B></P> +<DIV class="code"> +<PRE> +<B>int</B> foo(int x, double y, char *s) throw(<B>MemoryError, IndexError</B>); +</PRE> +</DIV> +<UL> +<LI>Handling of C++ exception specifications. ("throw" typemap).</LI> +</UL> +<P><B> Global variables</B></P> +<DIV class="code"> +<PRE> +<B>int foo;</B> +</PRE> +</DIV> +<UL> +<LI>Assignment of a global variable. ("varin" typemap).</LI> +<LI>Reading a global variable. ("varout" typemap).</LI> +</UL> +<P><B> Member variables</B></P> +<DIV class="code"> +<PRE> +struct Foo { + <B>int x[20]</B>; +}; +</PRE> +</DIV> +<UL> +<LI>Assignment of data to a class/structure member. ("memberin" + typemap).</LI> +</UL> +<P><B> Constant creation</B></P> +<DIV class="code"> +<PRE> +#define FOO 3 +%constant int BAR = 42; +enum { ALE, LAGER, STOUT }; +</PRE> +</DIV> +<UL> +<LI>Creation of constant values. ("consttab" or "constcode" typemap).</LI> +</UL> +<P> Details of each of these typemaps will be covered shortly. Also, + certain language modules may define additional typemaps that expand + upon this list. For example, the Java module defines a variety of + typemaps for controlling additional aspects of the Java bindings. + Consult language specific documentation for further details.</P> +<H3><A name="Typemaps_nn8"></A>10.1.6 What can't be done with typemaps?</H3> +<P> Typemaps can't be used to define properties that apply to C/C++ + declarations as a whole. For example, suppose you had a declaration + like this,</P> +<DIV class="code"> +<PRE> +Foo *make_Foo(); +</PRE> +</DIV> +<P> and you wanted to tell SWIG that <TT>make_Foo()</TT> returned a + newly allocated object (for the purposes of providing better memory + management). Clearly, this property of <TT>make_Foo()</TT> is<EM> not</EM> + a property that would be associated with the datatype <TT>Foo *</TT> by + itself. Therefore, a completely different SWIG customization mechanism + (<TT>%feature</TT>) is used for this purpose. Consult the <A href="#Customization"> +Customization Features</A> chapter for more information about that.</P> +<P> Typemaps also can't be used to rearrange or transform the order of + arguments. For example, if you had a function like this:</P> +<DIV class="code"> +<PRE> +void foo(int, char *); +</PRE> +</DIV> +<P> you can't use typemaps to interchange the arguments, allowing you to + call the function like this:</P> +<DIV class="targetlang"> +<PRE> +foo("hello",3) # Reversed arguments +</PRE> +</DIV> +<P> If you want to change the calling conventions of a function, write a + helper function instead. For example:</P> +<DIV class="code"> +<PRE> +%rename(foo) wrap_foo; +%inline %{ +void wrap_foo(char *s, int x) { + foo(x,s); +} +%} +</PRE> +</DIV> +<H3><A name="Typemaps_nn9"></A>10.1.7 The rest of this chapter</H3> +<P> The rest of this chapter provides detailed information for people + who want to write new typemaps. This information is of particular + importance to anyone who intends to write a new SWIG target language + module. Power users can also use this information to write application + specific type conversion rules.</P> +<P> Since typemaps are strongly tied to the underlying C++ type system, + subsequent sections assume that you are reasonably familiar with the + basic details of values, pointers, references, arrays, type qualifiers + (e.g., <TT>const</TT>), structures, namespaces, templates, and memory + management in C/C++. If not, you would be well-advised to consult a + copy of "The C Programming Language" by Kernighan and Ritchie or "The + C++ Programming Language" by Stroustrup before going any further.</P> +<H2><A name="Typemaps_nn10"></A>10.2 Typemap specifications</H2> +<P> This section describes the behavior of the <TT>%typemap</TT> + directive itself.</P> +<H3><A name="Typemaps_defining"></A>10.2.1 Defining a typemap</H3> +<P> New typemaps are defined using the <TT>%typemap</TT> declaration. + The general form of this declaration is as follows (parts enclosed in [ + ... ] are optional):</P> +<DIV class="code"> +<PRE> +%typemap(<EM>method</EM> [, <EM>modifiers</EM>]) <EM>typelist</EM> <EM>code</EM> ; +</PRE> +</DIV> +<P><EM> method</EM> is a simply a name that specifies what kind of + typemap is being defined. It is usually a name like <TT>"in"</TT>, <TT> +"out"</TT>, or <TT>"argout"</TT>. The purpose of these methods is + described later.</P> +<P><EM> modifiers</EM> is an optional comma separated list of <TT> +name="value"</TT> values. These are sometimes to attach extra + information to a typemap and is often target-language dependent.</P> +<P><EM> typelist</EM> is a list of the C++ type patterns that the + typemap will match. The general form of this list is as follows:</P> +<DIV class="diagram"> +<PRE> +typelist : typepattern [, typepattern, typepattern, ... ] ; + +typepattern : type [ (parms) ] + | type name [ (parms) ] + | ( typelist ) [ (parms) ] + +</PRE> +</DIV> +<P> Each type pattern is either a simple type, a simple type and + argument name, or a list of types in the case of multi-argument + typemaps. In addition, each type pattern can be parameterized with a + list of temporary variables (parms). The purpose of these variables + will be explained shortly.</P> +<P><EM>code</EM> specifies the code used in the typemap. Usually this is + C/C++ code, but in the statically typed target languages, such as Java + and C#, this can contain target language code for certain typemaps. It + can take any one of the following forms:</P> +<DIV class="diagram"> +<PRE> +code : { ... } + | " ... " + | %{ ... %} +</PRE> +</DIV> +<P> Note that the preprocessor will expand code within the {} + delimiters, but not in the last two styles of delimiters, see <A href="#Preprocessor_typemap_delimiters"> +Preprocessor and Typemaps</A>. Here are some examples of valid typemap + specifications:</P> +<DIV class="code"> +<PRE> +/* Simple typemap declarations */ +%typemap(in) int { + $1 = PyInt_AsLong($input); +} +%typemap(in) int "$1 = PyInt_AsLong($input);"; +%typemap(in) int %{ + $1 = PyInt_AsLong($input); +%} + +/* Typemap with extra argument name */ +%typemap(in) int nonnegative { + ... +} + +/* Multiple types in one typemap */ +%typemap(in) int, short, long { + $1 = SvIV($input); +} + +/* Typemap with modifiers */ +%typemap(in,doc="integer") int "$1 = gh_scm2int($input);"; + +/* Typemap applied to patterns of multiple arguments */ +%typemap(in) (char *str, int len), + (char *buffer, int size) +{ + $1 = PyString_AsString($input); + $2 = PyString_Size($input); +} + +/* Typemap with extra pattern parameters */ +%typemap(in, numinputs=0) int *output (int temp), + long *output (long temp) +{ + $1 = &temp; +} +</PRE> +</DIV> +<P> Admittedly, it's not the most readable syntax at first glance. + However, the purpose of the individual pieces will become clear.</P> +<H3><A name="Typemaps_nn12"></A>10.2.2 Typemap scope</H3> +<P> Once defined, a typemap remains in effect for all of the + declarations that follow. A typemap may be redefined for different + sections of an input file. For example:</P> +<DIV class="code"> +<PRE> +// typemap1 +%typemap(in) int { +... +} + +int fact(int); // typemap1 +int gcd(int x, int y); // typemap1 + +// typemap2 +%typemap(in) int { +... +} + +int isprime(int); // typemap2 +</PRE> +</DIV> +<P> One exception to the typemap scoping rules pertains to the <TT> +%extend</TT> declaration. <TT>%extend</TT> is used to attach new + declarations to a class or structure definition. Because of this, all + of the declarations in an <TT>%extend</TT> block are subject to the + typemap rules that are in effect at the point where the class itself is + defined. For example:</P> +<DIV class="code"> +<PRE> +class Foo { + ... +}; + +%typemap(in) int { + ... +} + +%extend Foo { + int blah(int x); // typemap has no effect. Declaration is attached to Foo which + // appears before the %typemap declaration. +}; +</PRE> +</DIV> +<H3><A name="Typemaps_nn13"></A>10.2.3 Copying a typemap</H3> +<P> A typemap is copied by using assignment. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) Integer = int; +</PRE> +</DIV> +<P> or this:</P> +<DIV class="code"> +<PRE> +%typemap(in) Integer, Number, int32_t = int; +</PRE> +</DIV> +<P> Types are often managed by a collection of different typemaps. For + example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int { ... } +%typemap(out) int { ... } +%typemap(varin) int { ... } +%typemap(varout) int { ... } +</PRE> +</DIV> +<P> To copy all of these typemaps to a new type, use <TT>%apply</TT>. + For example:</P> +<DIV class="code"> +<PRE> +%apply int { Integer }; // Copy all int typemaps to Integer +%apply int { Integer, Number }; // Copy all int typemaps to both Integer and Number +</PRE> +</DIV> +<P> The patterns for <TT>%apply</TT> follow the same rules as for <TT> +%typemap</TT>. For example:</P> +<DIV class="code"> +<PRE> +%apply int *output { Integer *output }; // Typemap with name +%apply (char *buf, int len) { (char *buffer, int size) }; // Multiple arguments +</PRE> +</DIV> +<H3><A name="Typemaps_nn14"></A>10.2.4 Deleting a typemap</H3> +<P> A typemap can be deleted by simply defining no code. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int; // Clears typemap for int +%typemap(in) int, long, short; // Clears typemap for int, long, short +%typemap(in) int *output; +</PRE> +</DIV> +<P> The <TT>%clear</TT> directive clears all typemaps for a given type. + For example:</P> +<DIV class="code"> +<PRE> +%clear int; // Removes all types for int +%clear int *output, long *output; +</PRE> +</DIV> +<P><B> Note:</B> Since SWIG's default behavior is defined by typemaps, + clearing a fundamental type like <TT>int</TT> will make that type + unusable unless you also define a new set of typemaps immediately after + the clear operation.</P> +<H3><A name="Typemaps_nn15"></A>10.2.5 Placement of typemaps</H3> +<P> Typemap declarations can be declared in the global scope, within a + C++ namespace, and within a C++ class. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int { + ... +} + +namespace std { + class string; + %typemap(in) string { + ... + } +} + +class Bar { +public: + typedef const int & const_reference; + %typemap(out) const_reference { + ... + } +}; +</PRE> +</DIV> +<P> When a typemap appears inside a namespace or class, it stays in + effect until the end of the SWIG input (just like before). However, the + typemap takes the local scope into account. Therefore, this code</P> +<DIV class="code"> +<PRE> +namespace std { + class string; + %typemap(in) string { + ... + } +} +</PRE> +</DIV> +<P> is really defining a typemap for the type <TT>std::string</TT>. You + could have code like this:</P> +<DIV class="code"> +<PRE> +namespace std { + class string; + %typemap(in) string { /* std::string */ + ... + } +} + +namespace Foo { + class string; + %typemap(in) string { /* Foo::string */ + ... + } +} +</PRE> +</DIV> +<P> In this case, there are two completely distinct typemaps that apply + to two completely different types (<TT>std::string</TT> and <TT> +Foo::string</TT>).</P> +<P> It should be noted that for scoping to work, SWIG has to know that <TT> +string</TT> is a typename defined within a particular namespace. In this + example, this is done using the class declaration <TT>class string</TT> +.</P> +<H2><A name="Typemaps_pattern_matching"></A>10.3 Pattern matching rules</H2> +<P> The section describes the pattern matching rules by which C + datatypes are associated with typemaps.</P> +<H3><A name="Typemaps_nn17"></A>10.3.1 Basic matching rules</H3> +<P> Typemaps are matched using both a type and a name (typically the + name of a argument). For a given <TT>TYPE NAME</TT> pair, the following + rules are applied, in order, to find a match. The first typemap found + is used.</P> +<UL> +<LI>Typemaps that exactly match <TT>TYPE</TT> and <TT>NAME</TT>.</LI> +<LI>Typemaps that exactly match <TT>TYPE</TT> only.</LI> +</UL> +<P> If <TT>TYPE</TT> includes qualifiers (const, volatile, etc.), they + are stripped and the following checks are made:</P> +<UL> +<LI>Typemaps that match the stripped <TT>TYPE</TT> and <TT>NAME</TT>.</LI> +<LI>Typemaps that match the stripped <TT>TYPE</TT> only.</LI> +</UL> +<P> If <TT>TYPE</TT> is an array. The following transformation is made:</P> +<UL> +<LI>Replace all dimensions to <TT>[ANY]</TT> and look for a generic + array typemap.</LI> +</UL> +<P> To illustrate, suppose that you had a function like this:</P> +<DIV class="code"> +<PRE> +int foo(const char *s); +</PRE> +</DIV> +<P> To find a typemap for the argument <TT>const char *s</TT>, SWIG will + search for the following typemaps:</P> +<DIV class="diagram"> +<PRE> +const char *s Exact type and name match +const char * Exact type match +char *s Type and name match (stripped qualifiers) +char * Type match (stripped qualifiers) +</PRE> +</DIV> +<P> When more than one typemap rule might be defined, only the first + match found is actually used. Here is an example that shows how some of + the basic rules are applied:</P> +<DIV class="code"> +<PRE> +%typemap(in) int *x { + ... typemap 1 +} + +%typemap(in) int * { + ... typemap 2 +} + +%typemap(in) const int *z { + ... typemap 3 +} + +%typemap(in) int [4] { + ... typemap 4 +} + +%typemap(in) int [ANY] { + ... typemap 5 +} + +void A(int *x); // int *x rule (typemap 1) +void B(int *y); // int * rule (typemap 2) +void C(const int *x); // int *x rule (typemap 1) +void D(const int *z); // int * rule (typemap 3) +void E(int x[4]); // int [4] rule (typemap 4) +void F(int x[1000]); // int [ANY] rule (typemap 5) +</PRE> +</DIV> +<H3><A name="Typemaps_nn18"></A>10.3.2 Typedef reductions</H3> +<P> If no match is found using the rules in the previous section, SWIG + applies a typedef reduction to the type and repeats the typemap search + for the reduced type. To illustrate, suppose you had code like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) int { + ... typemap 1 +} + +typedef int Integer; +void blah(Integer x); +</PRE> +</DIV> +<P> To find the typemap for <TT>Integer x</TT>, SWIG will first search + for the following typemaps:</P> +<DIV class="diagram"> +<PRE> +Integer x +Integer +</PRE> +</DIV> +<P> Finding no match, it then applies a reduction <TT>Integer -> int</TT> + to the type and repeats the search.</P> +<DIV class="diagram"> +<PRE> +int x +int --> match: typemap 1 +</PRE> +</DIV> +<P> Even though two types might be the same via typedef, SWIG allows + typemaps to be defined for each typename independently. This allows for + interesting customization possibilities based solely on the typename + itself. For example, you could write code like this:</P> +<DIV class="code"> +<PRE> +typedef double pdouble; // Positive double + +// typemap 1 +%typemap(in) double { + ... get a double ... +} +// typemap 2 +%typemap(in) pdouble { + ... get a positive double ... +} +double sin(double x); // typemap 1 +pdouble sqrt(pdouble x); // typemap 2 +</PRE> +</DIV> +<P> When reducing the type, only one typedef reduction is applied at a + time. The search process continues to apply reductions until a match is + found or until no more reductions can be made.</P> +<P> For complicated types, the reduction process can generate a long + list of patterns. Consider the following:</P> +<DIV class="code"> +<PRE> +typedef int Integer; +typedef Integer Row4[4]; +void foo(Row4 rows[10]); +</PRE> +</DIV> +<P> To find a match for the <TT>Row4 rows[10]</TT> argument, SWIG would + check the following patterns, stopping only when it found a match:</P> +<DIV class="code"> +<PRE> +Row4 rows[10] +Row4 [10] +Row4 rows[ANY] +Row4 [ANY] + +# Reduce Row4 --> Integer[4] +Integer rows[10][4] +Integer [10][4] +Integer rows[ANY][ANY] +Integer [ANY][ANY] + +# Reduce Integer --> int +int rows[10][4] +int [10][4] +int rows[ANY][ANY] +int [ANY][ANY] +</PRE> +</DIV> +<P> For parameterized types like templates, the situation is even more + complicated. Suppose you had some declarations like this:</P> +<DIV class="code"> +<PRE> +typedef int Integer; +typedef foo<Integer,Integer> fooii; +void blah(fooii *x); +</PRE> +</DIV> +<P> In this case, the following typemap patterns are searched for the + argument <TT>fooii *x</TT>:</P> +<DIV class="code"> +<PRE> +fooii *x +fooii * + +# Reduce fooii --> foo<Integer,Integer> +foo<Integer,Integer> *x +foo<Integer,Integer> * + +# Reduce Integer -> int +foo<int, Integer> *x +foo<int, Integer> * + +# Reduce Integer -> int +foo<int, int> *x +foo<int, int> * +</PRE> +</DIV> +<P> Typemap reductions are always applied to the left-most type that + appears. Only when no reductions can be made to the left-most type are + reductions made to other parts of the type. This behavior means that + you could define a typemap for <TT>foo<int,Integer></TT>, but a typemap + for <TT>foo<Integer,int></TT> would never be matched. Admittedly, this + is rather esoteric--there's little practical reason to write a typemap + quite like that. Of course, you could rely on this to confuse your + coworkers even more.</P> +<H3><A name="Typemaps_nn19"></A>10.3.3 Default typemaps</H3> +<P> Most SWIG language modules use typemaps to define the default + behavior of the C primitive types. This is entirely straightforward. + For example, a set of typemaps are written like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) int "convert an int"; +%typemap(in) short "convert a short"; +%typemap(in) float "convert a float"; +... +</PRE> +</DIV> +<P> Since typemap matching follows all <TT>typedef</TT> declarations, + any sort of type that is mapped to a primitive type through <TT>typedef</TT> + will be picked up by one of these primitive typemaps.</P> +<P> The default behavior for pointers, arrays, references, and other + kinds of types are handled by specifying rules for variations of the + reserved <TT>SWIGTYPE</TT> type. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) SWIGTYPE * { ... default pointer handling ... } +%typemap(in) SWIGTYPE & { ... default reference handling ... } +%typemap(in) SWIGTYPE [] { ... default array handling ... } +%typemap(in) enum SWIGTYPE { ... default handling for enum values ... } +%typemap(in) SWIGTYPE (CLASS::*) { ... default pointer member handling ... } +</PRE> +</DIV> +<P> These rules match any kind of pointer, reference, or array--even + when multiple levels of indirection or multiple array dimensions are + used. Therefore, if you wanted to change SWIG's default handling for + all types of pointers, you would simply redefine the rule for <TT> +SWIGTYPE *</TT>.</P> +<P> Finally, the following typemap rule is used to match against simple + types that don't match any other rules:</P> +<DIV class="code"> +<PRE> +%typemap(in) SWIGTYPE { ... handle an unknown type ... } +</PRE> +</DIV> +<P> This typemap is important because it is the rule that gets triggered + when call or return by value is used. For instance, if you have a + declaration like this:</P> +<DIV class="code"> +<PRE> +double dot_product(Vector a, Vector b); +</PRE> +</DIV> +<P> The <TT>Vector</TT> type will usually just get matched against <TT> +SWIGTYPE</TT>. The default implementation of <TT>SWIGTYPE</TT> is to + convert the value into pointers (as described in chapter 3).</P> +<P> By redefining <TT>SWIGTYPE</TT> it may be possible to implement + other behavior. For example, if you cleared all typemaps for <TT> +SWIGTYPE</TT>, SWIG simply won't wrap any unknown datatype (which might + be useful for debugging). Alternatively, you might modify SWIGTYPE to + marshal objects into strings instead of converting them to pointers.</P> +<P> The best way to explore the default typemaps is to look at the ones + already defined for a particular language module. Typemaps definitions + are usually found in the SWIG library in a file such as <TT>python.swg</TT> +, <TT>tcl8.swg</TT>, etc.</P> +<H3><A name="Typemaps_mixed_default"></A>10.3.4 Mixed default typemaps</H3> +<P> The default typemaps described above can be mixed with <TT>const</TT> + and with each other. For example the <TT>SWIGTYPE *</TT> typemap is for + default pointer handling, but if a <TT>const SWIGTYPE *</TT> typemap is + defined it will be used instead for constant pointers. Some further + examples follow:</P> +<DIV class="code"> +<PRE> +%typemap(in) enum SWIGTYPE & { ... enum references ... } +%typemap(in) const enum SWIGTYPE & { ... const enum references ... } +%typemap(in) SWIGTYPE *& { ... pointers passed by reference ... } +%typemap(in) SWIGTYPE * const & { ... constant pointers passed by reference ... } +%typemap(in) SWIGTYPE[ANY][ANY] { ... 2D arrays ... } +</PRE> +</DIV> +<P> Note that the the typedef reduction described earlier is also used + with these mixed default typemaps. For example, say the following + typemaps are defined and SWIG is looking for the best match for the + enum shown below:</P> +<DIV class="code"> +<PRE> +%typemap(in) const Hello & { ... } +%typemap(in) const enum SWIGTYPE & { ... } +%typemap(in) enum SWIGTYPE & { ... } +%typemap(in) SWIGTYPE & { ... } +%typemap(in) SWIGTYPE { ... } + +enum Hello {}; +const Hello &hi; +</PRE> +</DIV> +<P> The typemap at the top of the list will be chosen, not because it is + defined first, but because it is the closest match for the type being + wrapped. If any of the typemaps in the above list were not defined, + then the next one on the list would have precedence. In other words the + typemap chosen is the closest explicit match.</P> +<P><B> Compatibility note:</B> The mixed default typemaps were + introduced in SWIG-1.3.23, but were not used much in this version. + Expect to see them being used more and more within the various + libraries in later versions of SWIG.</P> +<H3><A name="Typemaps_nn20"></A>10.3.5 Multi-arguments typemaps</H3> +<P> When multi-argument typemaps are specified, they take precedence + over any typemaps specified for a single type. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (char *buffer, int len) { + // typemap 1 +} + +%typemap(in) char *buffer { + // typemap 2 +} + +void foo(char *buffer, int len, int count); // (char *buffer, int len) +void bar(char *buffer, int blah); // char *buffer +</PRE> +</DIV> +<P> Multi-argument typemaps are also more restrictive in the way that + they are matched. Currently, the first argument follows the matching + rules described in the previous section, but all subsequent arguments + must match exactly.</P> +<H2><A name="Typemaps_nn21"></A>10.4 Code generation rules</H2> +<P> This section describes rules by which typemap code is inserted into + the generated wrapper code.</P> +<H3><A name="Typemaps_nn22"></A>10.4.1 Scope</H3> +<P> When a typemap is defined like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) int { + $1 = PyInt_AsLong($input); +} +</PRE> +</DIV> +<P> the typemap code is inserted into the wrapper function using a new + block scope. In other words, the wrapper code will look like this:</P> +<DIV class="code"> +<PRE> +wrap_whatever() { + ... + // Typemap code + { + arg1 = PyInt_AsLong(obj1); + } + ... +} +</PRE> +</DIV> +<P> Because the typemap code is enclosed in its own block, it is legal + to declare temporary variables for use during typemap execution. For + example:</P> +<DIV class="code"> +<PRE> +%typemap(in) short { + long temp; /* Temporary value */ + if (Tcl_GetLongFromObj(interp, $input, &temp) != TCL_OK) { + return TCL_ERROR; + } + $1 = (short) temp; +} +</PRE> +</DIV> +<P> Of course, any variables that you declare inside a typemap are + destroyed as soon as the typemap code has executed (they are not + visible to other parts of the wrapper function or other typemaps that + might use the same variable names).</P> +<P> Occasionally, typemap code will be specified using a few alternative + forms. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int "$1 = PyInt_AsLong($input);"; +%typemap(in) int %{ +$1 = PyInt_AsLong($input); +%} +</PRE> +</DIV> +<P> These two forms are mainly used for cosmetics--the specified code is + not enclosed inside a block scope when it is emitted. This sometimes + results in a less complicated looking wrapper function.</P> +<H3><A name="Typemaps_nn23"></A>10.4.2 Declaring new local variables</H3> +<P> Sometimes it is useful to declare a new local variable that exists + within the scope of the entire wrapper function. A good example of this + might be an application in which you wanted to marshal strings. Suppose + you had a C++ function like this</P> +<DIV class="code"> +<PRE> +int foo(std::string *s); +</PRE> +</DIV> +<P> and you wanted to pass a native string in the target language as an + argument. For instance, in Perl, you wanted the function to work like + this:</P> +<DIV class="targetlang"> +<PRE> +$x = foo("Hello World"); +</PRE> +</DIV> +<P> To do this, you can't just pass a raw Perl string as the <TT> +std::string *</TT> argument. Instead, you have to create a temporary <TT> +std::string</TT> object, copy the Perl string data into it, and then + pass a pointer to the object. To do this, simply specify the typemap + with an extra parameter like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) std::string * <B>(std::string temp)</B> { + unsigned int len; + char *s; + s = SvPV($input,len); /* Extract string data */ + temp.assign(s,len); /* Assign to temp */ + $1 = &temp; /* Set argument to point to temp */ +} +</PRE> +</DIV> +<P> In this case, <TT>temp</TT> becomes a local variable in the scope of + the entire wrapper function. For example:</P> +<DIV class="code"> +<PRE> +wrap_foo() { + std::string temp; <--- Declaration of temp goes here + ... + + /* Typemap code */ + { + ... + temp.assign(s,len); + ... + } + ... +} +</PRE> +</DIV> +<P> When you set <TT>temp</TT> to a value, it persists for the duration + of the wrapper function and gets cleaned up automatically on exit.</P> +<P> It is perfectly safe to use more than one typemap involving local + variables in the same declaration. For example, you could declare a + function as :</P> +<DIV class="code"> +<PRE> +void foo(std::string *x, std::string *y, std::string *z); +</PRE> +</DIV> +<P> This is safely handled because SWIG actually renames all local + variable references by appending an argument number suffix. Therefore, + the generated code would actually look like this:</P> +<DIV class="code"> +<PRE> +wrap_foo() { + int *arg1; /* Actual arguments */ + int *arg2; + int *arg3; + std::string temp1; /* Locals declared in the typemap */ + std::string temp2; + std::string temp3; + ... + { + char *s; + unsigned int len; + ... + temp1.assign(s,len); + arg1 = *temp1; + } + { + char *s; + unsigned int len; + ... + temp2.assign(s,len); + arg2 = &temp2; + } + { + char *s; + unsigned int len; + ... + temp3.assign(s,len); + arg3 = &temp3; + } + ... +} +</PRE> +</DIV> +<P> Some typemaps do not recognize local variables (or they may simply + not apply). At this time, only typemaps that apply to argument + conversion support this.</P> +<P><B> Note:</B></P> +<P> When declaring a typemap for multiple types, each type must have its + own local variable declaration.</P> +<DIV class="code"> +<PRE> +%typemap(in) const std::string *, std::string * (std::string temp) // NO! +// only std::string * has a local variable +// const std::string * does not (oops) +.... + +%typemap(in) const std::string * (std::string temp), std::string * (std::string temp) // Correct +.... +</PRE> +</DIV> +<H3><A name="Typemaps_special_variables"></A>10.4.3 Special variables</H3> +<P> Within all typemaps, the following special variables are expanded. + This is by no means a complete list as some target languages have + additional special variables which are documented in the language + specific chapters.</P> +<CENTER> +<TABLE border="1" summary="Typemap special variables"> +<TR><TH>Variable</TH><TH>Meaning</TH></TR> +<TR><TD>$<EM>n</EM></TD><TD> A C local variable corresponding to type<EM> + n</EM> in the typemap pattern.</TD></TR> +<TR><TD>$argnum</TD><TD>Argument number. Only available in typemaps + related to argument conversion</TD></TR> +<TR><TD>$<EM>n</EM>_name</TD><TD>Argument name</TD></TR> +<TR><TD>$<EM>n</EM>_type</TD><TD>Real C datatype of type<EM> n</EM>.</TD> +</TR> +<TR><TD>$<EM>n</EM>_ltype</TD><TD>ltype of type<EM> n</EM></TD></TR> +<TR><TD>$<EM>n</EM>_mangle</TD><TD>Mangled form of type<EM> n</EM>. For + example <TT>_p_Foo</TT></TD></TR> +<TR><TD>$<EM>n</EM>_descriptor</TD><TD>Type descriptor structure for + type<EM> n</EM>. For example <TT>SWIGTYPE_p_Foo</TT>. This is primarily + used when interacting with the run-time type checker (described later).</TD> +</TR> +<TR><TD>$*<EM>n</EM>_type</TD><TD>Real C datatype of type<EM> n</EM> + with one pointer removed.</TD></TR> +<TR><TD>$*<EM>n</EM>_ltype</TD><TD>ltype of type<EM> n</EM> with one + pointer removed.</TD></TR> +<TR><TD>$*<EM>n</EM>_mangle</TD><TD>Mangled form of type<EM> n</EM> with + one pointer removed.</TD></TR> +<TR><TD>$*<EM>n</EM>_descriptor</TD><TD>Type descriptor structure for + type<EM> n</EM> with one pointer removed.</TD></TR> +<TR><TD>$&<EM>n</EM>_type</TD><TD>Real C datatype of type<EM> n</EM> + with one pointer added.</TD></TR> +<TR><TD>$&<EM>n</EM>_ltype</TD><TD>ltype of type<EM> n</EM> with one + pointer added.</TD></TR> +<TR><TD>$&<EM>n</EM>_mangle</TD><TD>Mangled form of type<EM> n</EM> with + one pointer added.</TD></TR> +<TR><TD>$&<EM>n</EM>_descriptor</TD><TD>Type descriptor structure for + type<EM> n</EM> with one pointer added.</TD></TR> +<TR><TD>$<EM>n</EM>_basetype</TD><TD>Base typename with all pointers and + qualifiers stripped.</TD></TR> +</TABLE> +</CENTER> +<P> Within the table, $<EM>n</EM> refers to a specific type within the + typemap specification. For example, if you write this</P> +<DIV class="code"> +<PRE> +%typemap(in) int *INPUT { + +} +</PRE> +</DIV> +<P> then $1 refers to <TT>int *INPUT</TT>. If you have a typemap like + this,</P> +<DIV class="code"> +<PRE> +%typemap(in) (int argc, char *argv[]) { + ... +} +</PRE> +</DIV> +<P> then $1 refers to <TT>int argc</TT> and $2 refers to <TT>char + *argv[]</TT>.</P> +<P> Substitutions related to types and names always fill in values from + the actual code that was matched. This is useful when a typemap might + match multiple C datatype. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int, short, long { + $1 = ($1_ltype) PyInt_AsLong($input); +} +</PRE> +</DIV> +<P> In this case, <TT>$1_ltype</TT> is replaced with the datatype that + is actually matched.</P> +<P> When typemap code is emitted, the C/C++ datatype of the special + variables <TT>$1</TT> and <TT>$2</TT> is always an "ltype." An "ltype" + is simply a type that can legally appear on the left-hand side of a C + assignment operation. Here are a few examples of types and ltypes:</P> +<DIV class="diagram"> +<PRE> +type ltype +------ ---------------- +int int +const int int +const int * int * +int [4] int * +int [4][5] int (*)[5] +</PRE> +</DIV> +<P> In most cases a ltype is simply the C datatype with qualifiers + stripped off. In addition, arrays are converted into pointers.</P> +<P> Variables such as <TT>$&1_type</TT> and <TT>$*1_type</TT> are used + to safely modify the type by removing or adding pointers. Although not + needed in most typemaps, these substitutions are sometimes needed to + properly work with typemaps that convert values between pointers and + values.</P> +<P> If necessary, type related substitutions can also be used when + declaring locals. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int * ($*1_type temp) { + temp = PyInt_AsLong($input); + $1 = &temp; +} +</PRE> +</DIV> +<P> There is one word of caution about declaring local variables in this + manner. If you declare a local variable using a type substitution such + as <TT>$1_ltype temp</TT>, it won't work like you expect for arrays and + certain kinds of pointers. For example, if you wrote this,</P> +<DIV class="code"> +<PRE> +%typemap(in) int [10][20] { + $1_ltype temp; +} +</PRE> +</DIV> +<P> then the declaration of <TT>temp</TT> will be expanded as</P> +<DIV class="code"> +<PRE> +int (*)[20] temp; +</PRE> +</DIV> +<P> This is illegal C syntax and won't compile. There is currently no + straightforward way to work around this problem in SWIG due to the way + that typemap code is expanded and processed. However, one possible + workaround is to simply pick an alternative type such as <TT>void *</TT> + and use casts to get the correct type when needed. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int [10][20] { + void *temp; + ... + (($1_ltype) temp)[i][j] = x; /* set a value */ + ... +} +</PRE> +</DIV> +<P> Another approach, which only works for arrays is to use the <TT> +$1_basetype</TT> substitution. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int [10][20] { + $1_basetype temp[10][20]; + ... + temp[i][j] = x; /* set a value */ + ... +} +</PRE> +</DIV> +<H3><A name="Typemaps_special_variable_macros"></A>10.4.4 Special + variable macros</H3> +<P> Special variable macros are like macro functions in that they take + one or more input arguments which are used for the macro expansion. + They look like macro/function calls but use the special variable <TT>$</TT> + prefix to the macro name. Note that unlike normal macros, the expansion + is not done by the preprocessor, it is done during the SWIG + parsing/compilation stages. The following special variable macros are + available across all language modules.</P> +<H4><A name="Typemaps_special_macro_descriptor"></A>10.4.4.1 + $descriptor(type)</H4> +<P> This macro expands into the type descriptor structure for any C/C++ + type specified in <TT>type</TT>. It behaves like the <TT>$1_descriptor</TT> + special variable described above except that the type to expand is + taken from the macro argument rather than inferred from the typemap + type. For example, <TT>$descriptor(std::vector<int> *)</TT> will expand + into <TT>SWIGTYPE_p_std__vectorT_int_t</TT>. This macro is mostly used + in the scripting target languages and is demonstrated later in the <A href="#Typemaps_runtime_type_checker_usage"> +Run-time type checker usage</A> section.</P> +<H4><A name="Typemaps_special_macro_typemap"></A>10.4.4.2 + $typemap(method, typepattern)</H4> +<P> This macro uses the <A href="#Typemaps_pattern_matching">pattern + matching rules</A> described earlier to lookup and then substitute the + special variable macro with the code in the matched typemap. The + typemap to search for is specified by the arguments, where <TT>method</TT> + is the typemap method name and <TT>typepattern</TT> is a type pattern + as per the <TT>%typemap</TT> specification in the <A href="#Typemaps_defining"> +Defining a typemap</A> section.</P> +<P> The special variables within the matched typemap are expanded into + those for the matched typemap type, not the typemap within which the + macro is called. In practice, there is little use for this macro in the + scripting target languages. It is mostly used in the target languages + that are statically typed as a way to obtain the target language type + given the C/C++ type and more commonly only when the C++ type is a + template parameter.</P> +<P> The example below is for C# only and uses some typemap method names + documented in the C# chapter, but it shows some of the possible syntax + variations.</P> +<DIV class="code"> +<PRE> +%typemap(cstype) unsigned long "uint" +%typemap(cstype) unsigned long bb "bool" +%typemap(cscode) BarClass %{ + void foo($typemap(cstype, unsigned long aa) var1, + $typemap(cstype, unsigned long bb) var2, + $typemap(cstype, (unsigned long bb)) var3, + $typemap(cstype, unsigned long) var4) + { + // do something + } +%} +</PRE> +</DIV> +<P> The result is the following expansion</P> +<DIV class="code"> +<PRE> +%typemap(cstype) unsigned long "uint" +%typemap(cstype) unsigned long bb "bool" +%typemap(cscode) BarClass %{ + void foo(uint var1, + bool var2, + bool var3, + uint var4) + { + // do something + } +%} +</PRE> +</DIV> +<H2><A name="Typemaps_nn25"></A>10.5 Common typemap methods</H2> +<P> The set of typemaps recognized by a language module may vary. + However, the following typemap methods are nearly universal:</P> +<H3><A name="Typemaps_nn26"></A>10.5.1 "in" typemap</H3> +<P> The "in" typemap is used to convert function arguments from the + target language to C. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int { + $1 = PyInt_AsLong($input); +} +</PRE> +</DIV> +<P> The following special variables are available:</P> +<DIV class="code"> +<PRE> +$input - Input object holding value to be converted. +$symname - Name of function/method being wrapped +</PRE> +</DIV> +<P> This is probably the most commonly redefined typemap because it can + be used to implement customized conversions.</P> +<P> In addition, the "in" typemap allows the number of converted + arguments to be specified. The <TT>numinputs</TT> attributes + facilitates this. For example:</P> +<DIV class="code"> +<PRE> +// Ignored argument. +%typemap(in, numinputs=0) int *out (int temp) { + $1 = &temp; +} +</PRE> +</DIV> +<P> At this time, only zero or one arguments may be converted. When <TT> +numinputs</TT> is set to 0, the argument is effectively ignored and + cannot be supplied from the target language. The argument is still + required when making the C/C++ call and the above typemap shows the + value used is instead obtained from a locally declared variable called <TT> +temp</TT>. Usually <TT>numinputs</TT> is not specified, whereupon the + default value is 1, that is, there is a one to one mapping of the + number of arguments when used from the target language to the C/C++ + call. <A href="#Typemaps_multi_argument_typemaps">Multi-argument + typemaps</A> provide a similar concept where the number of arguments + mapped from the target language to C/C++ can be changed for more tha + multiple adjacent C/C++ arguments.</P> +<P><B> Compatibility note:</B> Specifying <TT>numinputs=0</TT> is the + same as the old "ignore" typemap.</P> +<H3><A name="Typemaps_nn27"></A>10.5.2 "typecheck" typemap</H3> +<P> The "typecheck" typemap is used to support overloaded functions and + methods. It merely checks an argument to see whether or not it matches + a specific type. For example:</P> +<DIV class="code"> +<PRE> +%typemap(typecheck,precedence=SWIG_TYPECHECK_INTEGER) int { + $1 = PyInt_Check($input) ? 1 : 0; +} +</PRE> +</DIV> +<P> For typechecking, the $1 variable is always a simple integer that is + set to 1 or 0 depending on whether or not the input argument is the + correct type.</P> +<P> If you define new "in" typemaps<EM> and</EM> your program uses + overloaded methods, you should also define a collection of "typecheck" + typemaps. More details about this follow in a later section on + "Typemaps and Overloading."</P> +<H3><A name="Typemaps_nn28"></A>10.5.3 "out" typemap</H3> +<P> The "out" typemap is used to convert function/method return values + from C into the target language. For example:</P> +<DIV class="code"> +<PRE> +%typemap(out) int { + $result = PyInt_FromLong($1); +} +</PRE> +</DIV> +<P> The following special variables are available.</P> +<DIV class="code"> +<PRE> +$result - Result object returned to target language. +$symname - Name of function/method being wrapped +</PRE> +</DIV> +<P> The "out" typemap supports an optional attribute flag called + "optimal". This is for code optimisation and is detailed in the <A href="#Typemaps_optimal"> +Optimal code generation when returning by value</A> section.</P> +<H3><A name="Typemaps_nn29"></A>10.5.4 "arginit" typemap</H3> +<P> The "arginit" typemap is used to set the initial value of a function + argument--before any conversion has occurred. This is not normally + necessary, but might be useful in highly specialized applications. For + example:</P> +<DIV class="code"> +<PRE> +// Set argument to NULL before any conversion occurs +%typemap(arginit) int *data { + $1 = NULL; +} +</PRE> +</DIV> +<H3><A name="Typemaps_nn30"></A>10.5.5 "default" typemap</H3> +<P> The "default" typemap is used to turn an argument into a default + argument. For example:</P> +<DIV class="code"> +<PRE> +%typemap(default) int flags { + $1 = DEFAULT_FLAGS; +} +... +int foo(int x, int y, int flags); +</PRE> +</DIV> +<P> The primary use of this typemap is to either change the wrapping of + default arguments or specify a default argument in a language where + they aren't supported (like C). Target languages that do not support + optional arguments, such as Java and C#, effectively ignore the value + specified by this typemap as all arguments must be given.</P> +<P> Once a default typemap has been applied to an argument, all + arguments that follow must have default values. See the <A href="#SWIG_default_args"> +Default/optional arguments</A> section for further information on + default argument wrapping.</P> +<H3><A name="Typemaps_nn31"></A>10.5.6 "check" typemap</H3> +<P> The "check" typemap is used to supply value checking code during + argument conversion. The typemap is applied<EM> after</EM> arguments + have been converted. For example:</P> +<DIV class="code"> +<PRE> +%typemap(check) int positive { + if ($1 <= 0) { + SWIG_exception(SWIG_ValueError,"Expected positive value."); + } +} +</PRE> +</DIV> +<H3><A name="Typemaps_nn32"></A>10.5.7 "argout" typemap</H3> +<P> The "argout" typemap is used to return values from arguments. This + is most commonly used to write wrappers for C/C++ functions that need + to return multiple values. The "argout" typemap is almost always + combined with an "in" typemap---possibly to ignore the input value. For + example:</P> +<DIV class="code"> +<PRE> +/* Set the input argument to point to a temporary variable */ +%typemap(in, numinputs=0) int *out (int temp) { + $1 = &temp; +} + +%typemap(argout) int *out { + // Append output value $1 to $result + ... +} +</PRE> +</DIV> +<P> The following special variables are available.</P> +<DIV class="diagram"> +<PRE> +$result - Result object returned to target language. +$input - The original input object passed. +$symname - Name of function/method being wrapped +</PRE> +</DIV> +<P> The code supplied to the "argout" typemap is always placed after the + "out" typemap. If multiple return values are used, the extra return + values are often appended to return value of the function.</P> +<P> See the <TT>typemaps.i</TT> library for examples.</P> +<H3><A name="Typemaps_nn33"></A>10.5.8 "freearg" typemap</H3> +<P> The "freearg" typemap is used to cleanup argument data. It is only + used when an argument might have allocated resources that need to be + cleaned up when the wrapper function exits. The "freearg" typemap + usually cleans up argument resources allocated by the "in" typemap. For + example:</P> +<DIV class="code"> +<PRE> +// Get a list of integers +%typemap(in) int *items { + int nitems = Length($input); + $1 = (int *) malloc(sizeof(int)*nitems); +} +// Free the list +%typemap(freearg) int *items { + free($1); +} +</PRE> +</DIV> +<P> The "freearg" typemap inserted at the end of the wrapper function, + just before control is returned back to the target language. This code + is also placed into a special variable <TT>$cleanup</TT> that may be + used in other typemaps whenever a wrapper function needs to abort + prematurely.</P> +<H3><A name="Typemaps_nn34"></A>10.5.9 "newfree" typemap</H3> +<P> The "newfree" typemap is used in conjunction with the <TT>%newobject</TT> + directive and is used to deallocate memory used by the return result of + a function. For example:</P> +<DIV class="code"> +<PRE> +%typemap(newfree) string * { + delete $1; +} +%typemap(out) string * { + $result = PyString_FromString($1->c_str()); +} +... + +%newobject foo; +... +string *foo(); +</PRE> +</DIV> +<P> See <A href="#ownership">Object ownership and %newobject</A> for + further details.</P> +<H3><A name="Typemaps_nn35"></A>10.5.10 "memberin" typemap</H3> +<P> The "memberin" typemap is used to copy data from<EM> an already + converted input value</EM> into a structure member. It is typically + used to handle array members and other special cases. For example:</P> +<DIV class="code"> +<PRE> +%typemap(memberin) int [4] { + memmove($1, $input, 4*sizeof(int)); +} +</PRE> +</DIV> +<P> It is rarely necessary to write "memberin" typemaps---SWIG already + provides a default implementation for arrays, strings, and other + objects.</P> +<H3><A name="Typemaps_nn36"></A>10.5.11 "varin" typemap</H3> +<P> The "varin" typemap is used to convert objects in the target + language to C for the purposes of assigning to a C/C++ global variable. + This is implementation specific.</P> +<H3><A name="Typemaps_nn37"></A>10.5.12 "varout" typemap</H3> +<P> The "varout" typemap is used to convert a C/C++ object to an object + in the target language when reading a C/C++ global variable. This is + implementation specific.</P> +<H3><A name="throws_typemap"></A>10.5.13 "throws" typemap</H3> +<P> The "throws" typemap is only used when SWIG parses a C++ method with + an exception specification or has the <TT>%catches</TT> feature + attached to the method. It provides a default mechanism for handling + C++ methods that have declared the exceptions they will throw. The + purpose of this typemap is to convert a C++ exception into an error or + exception in the target language. It is slightly different to the other + typemaps as it is based around the exception type rather than the type + of a parameter or variable. For example:</P> +<DIV class="code"> +<PRE> +%typemap(throws) const char * %{ + PyErr_SetString(PyExc_RuntimeError, $1); + SWIG_fail; +%} +void bar() throw (const char *); +</PRE> +</DIV> +<P> As can be seen from the generated code below, SWIG generates an + exception handler with the catch block comprising the "throws" typemap + content.</P> +<DIV class="code"> +<PRE> +... +try { + bar(); +} +catch(char const *_e) { + PyErr_SetString(PyExc_RuntimeError, _e); + SWIG_fail; + +} +... +</PRE> +</DIV> +<P> Note that if your methods do not have an exception specification yet + they do throw exceptions, SWIG cannot know how to deal with them. For a + neat way to handle these, see the <A href="#exception">Exception + handling with %exception</A> section.</P> +<H2><A name="Typemaps_nn39"></A>10.6 Some typemap examples</H2> +<P> This section contains a few examples. Consult language module + documentation for more examples.</P> +<H3><A name="Typemaps_nn40"></A>10.6.1 Typemaps for arrays</H3> +<P> A common use of typemaps is to provide support for C arrays + appearing both as arguments to functions and as structure members.</P> +<P> For example, suppose you had a function like this:</P> +<DIV class="code"> +<PRE> +void set_vector(int type, float value[4]); +</PRE> +</DIV> +<P> If you wanted to handle <TT>float value[4]</TT> as a list of floats, + you might write a typemap similar to this:</P> +<DIV class="code"> +<PRE> + +%typemap(in) float value[4] (float temp[4]) { + int i; + if (!PySequence_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a sequence"); + return NULL; + } + if (PySequence_Length($input) != 4) { + PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected 4 elements"); + return NULL; + } + for (i = 0; i < 4; i++) { + PyObject *o = PySequence_GetItem($input,i); + if (PyNumber_Check(o)) { + temp[i] = (float) PyFloat_AsDouble(o); + } else { + PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); + return NULL; + } + } + $1 = temp; +} +</PRE> +</DIV> +<P> In this example, the variable <TT>temp</TT> allocates a small array + on the C stack. The typemap then populates this array and passes it to + the underlying C function.</P> +<P> When used from Python, the typemap allows the following type of + function call:</P> +<DIV class="targetlang"> +<PRE> +>>> set_vector(type, [ 1, 2.5, 5, 20 ]) +</PRE> +</DIV> +<P> If you wanted to generalize the typemap to apply to arrays of all + dimensions you might write this:</P> +<DIV class="code"> +<PRE> +%typemap(in) float value[ANY] (float temp[$1_dim0]) { + int i; + if (!PySequence_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a sequence"); + return NULL; + } + if (PySequence_Length($input) != $1_dim0) { + PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements"); + return NULL; + } + for (i = 0; i < $1_dim0; i++) { + PyObject *o = PySequence_GetItem($input,i); + if (PyNumber_Check(o)) { + temp[i] = (float) PyFloat_AsDouble(o); + } else { + PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); + return NULL; + } + } + $1 = temp; +} +</PRE> +</DIV> +<P> In this example, the special variable <TT>$1_dim0</TT> is expanded + with the actual array dimensions. Multidimensional arrays can be + matched in a similar manner. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) float matrix[ANY][ANY] (float temp[$1_dim0][$1_dim1]) { + ... convert a 2d array ... +} +</PRE> +</DIV> +<P> For large arrays, it may be impractical to allocate storage on the + stack using a temporary variable as shown. To work with heap allocated + data, the following technique can be used.</P> +<DIV class="code"> +<PRE> +%typemap(in) float value[ANY] { + int i; + if (!PySequence_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a sequence"); + return NULL; + } + if (PySequence_Length($input) != $1_dim0) { + PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements"); + return NULL; + } + $1 = (float *) malloc($1_dim0*sizeof(float)); + for (i = 0; i < $1_dim0; i++) { + PyObject *o = PySequence_GetItem($input,i); + if (PyNumber_Check(o)) { + $1[i] = (float) PyFloat_AsDouble(o); + } else { + PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); + free($1); + return NULL; + } + } +} +%typemap(freearg) float value[ANY] { + if ($1) free($1); +} +</PRE> +</DIV> +<P> In this case, an array is allocated using <TT>malloc</TT>. The <TT> +freearg</TT> typemap is then used to release the argument after the + function has been called.</P> +<P> Another common use of array typemaps is to provide support for array + structure members. Due to subtle differences between pointers and + arrays in C, you can't just "assign" to a array structure member. + Instead, you have to explicitly copy elements into the array. For + example, suppose you had a structure like this:</P> +<DIV class="code"> +<PRE> +struct SomeObject { + float value[4]; + ... +}; +</PRE> +</DIV> +<P> When SWIG runs, it won't produce any code to set the <TT>vec</TT> + member. You may even get a warning message like this:</P> +<DIV class="shell"> +<PRE> +swig -python example.i +Generating wrappers for Python +example.i:10. Warning. Array member value will be read-only. +</PRE> +</DIV> +<P> These warning messages indicate that SWIG does not know how you want + to set the <TT>vec</TT> field.</P> +<P> To fix this, you can supply a special "memberin" typemap like this:</P> +<DIV class="code"> +<PRE> +%typemap(memberin) float [ANY] { + int i; + for (i = 0; i < $1_dim0; i++) { + $1[i] = $input[i]; + } +} +</PRE> +</DIV> +<P> The memberin typemap is used to set a structure member from data + that has already been converted from the target language to C. In this + case, <TT>$input</TT> is the local variable in which converted input + data is stored. This typemap then copies this data into the structure.</P> +<P> When combined with the earlier typemaps for arrays, the combination + of the "in" and "memberin" typemap allows the following usage:</P> +<DIV class="targetlang"> +<PRE> +>>> s = SomeObject() +>>> s.x = [1, 2.5, 5, 10] +</PRE> +</DIV> +<P> Related to structure member input, it may be desirable to return + structure members as a new kind of object. For example, in this + example, you will get very odd program behavior where the structure + member can be set nicely, but reading the member simply returns a + pointer:</P> +<DIV class="targetlang"> +<PRE> +>>> s = SomeObject() +>>> s.x = [1, 2.5, 5, 10] +>>> print s.x +_1008fea8_p_float +>>> +</PRE> +</DIV> +<P> To fix this, you can write an "out" typemap. For example:</P> +<DIV class="code"> +<PRE> +%typemap(out) float [ANY] { + int i; + $result = PyList_New($1_dim0); + for (i = 0; i < $1_dim0; i++) { + PyObject *o = PyFloat_FromDouble((double) $1[i]); + PyList_SetItem($result,i,o); + } +} +</PRE> +</DIV> +<P> Now, you will find that member access is quite nice:</P> +<DIV class="targetlang"> +<PRE> +>>> s = SomeObject() +>>> s.x = [1, 2.5, 5, 10] +>>> print s.x +[ 1, 2.5, 5, 10] +</PRE> +</DIV> +<P><B> Compatibility Note:</B> SWIG1.1 used to provide a special + "memberout" typemap. However, it was mostly useless and has since been + eliminated. To return structure members, simply use the "out" typemap.</P> +<H3><A name="Typemaps_nn41"></A>10.6.2 Implementing constraints with + typemaps</H3> +<P> One particularly interesting application of typemaps is the + implementation of argument constraints. This can be done with the + "check" typemap. When used, this allows you to provide code for + checking the values of function arguments. For example :</P> +<DIV class="code"> +<PRE> +%module math + +%typemap(check) double posdouble { + if ($1 < 0) { + croak("Expecting a positive number"); + } +} + +... +double sqrt(double posdouble); + +</PRE> +</DIV> +<P> This provides a sanity check to your wrapper function. If a negative + number is passed to this function, a Perl exception will be raised and + your program terminated with an error message.</P> +<P> This kind of checking can be particularly useful when working with + pointers. For example :</P> +<DIV class="code"> +<PRE> +%typemap(check) Vector * { + if ($1 == 0) { + PyErr_SetString(PyExc_TypeError,"NULL Pointer not allowed"); + return NULL; + } +} + +</PRE> +</DIV> +<P> will prevent any function involving a <TT>Vector *</TT> from + accepting a NULL pointer. As a result, SWIG can often prevent a + potential segmentation faults or other run-time problems by raising an + exception rather than blindly passing values to the underlying C/C++ + program.</P> +<P> Note: A more advanced constraint checking system is in development. + Stay tuned.</P> +<H2><A name="Typemaps_nn43"></A>10.7 Typemaps for multiple languages</H2> +<P> The code within typemaps is usually language dependent, however, + many languages support the same typemaps. In order to distinguish + typemaps across different languages, the preprocessor should be used. + For example, the "in" typemap for Perl and Ruby could be written as:</P> +<DIV class="code"> +<PRE> +#if defined(SWIGPERL) + %typemap(in) int "$1 = ($1_ltype) SvIV($input);" +#elif defined(SWIGRUBY) + %typemap(in) int "$1 = NUM2INT($input);" +#else + #warning no "in" typemap defined +#endif +</PRE> +</DIV> +<P> The full set of language specific macros is defined in the <A href="#Preprocessor_condition_compilation"> +Conditional Compilation</A> section. The example above also shows a + common approach of issuing a warning for an as yet unsupported + language.</P> +<P><B> Compatibility note:</B> In SWIG-1.1 different languages could be + distinguished with the language name being put within the <TT>%typemap</TT> + directive, for example, +<BR> <TT>%typemap(ruby,in) int "$1 = NUM2INT($input);"</TT>.</P> +<H2><A name="Typemaps_optimal"></A>10.8 Optimal code generation when + returning by value</H2> +<P> The "out" typemap is the main typemap for return types. This typemap + supports an optional attribute flag called "optimal", which is for + reducing temporary variables and the amount of generated code, thereby + giving the compiler the opportunity to use<I> return value optimization</I> + for generating faster executing code. It only really makes a difference + when returning objects by value and has some limitations on usage, as + explained later on.</P> +<P> When a function returns an object by value, SWIG generates code that + instantiates the default type on the stack then assigns the value + returned by the function call to it. A copy of this object is then made + on the heap and this is what is ultimately stored and used from the + target language. This will be clearer considering an example. Consider + running the following code through SWIG:</P> +<DIV class="code"> +<PRE> +%typemap(out) SWIGTYPE %{ + $result = new $1_ltype((const $1_ltype &)$1); +%} + +%inline %{ +#include <iostream> +using namespace std; + +struct XX { + XX() { cout << "XX()" << endl; } + XX(int i) { cout << "XX(" << i << ")" << endl; } + XX(const XX &other) { cout << "XX(const XX &)" << endl; } + XX & operator =(const XX &other) { cout << "operator=(const XX &)" << endl; return *this; } + ~XX() { cout << "~XX()" << endl; } + static XX create() { + return XX(0); + } +}; +%} +</PRE> +</DIV> +<P> The "out" typemap shown is the default typemap for C# when returning + by objects by value. When making a call to <TT>XX::create()</TT> from + C#, the output is as follows:</P> +<DIV class="targetlang"> +<PRE> +XX() +XX(0) +operator=(const XX &) +~XX() +XX(const XX &) +~XX() +~XX() +</PRE> +</DIV> +<P> Note that three objects are being created as well as an assignment. + Wouldn't it be great if the <TT>XX::create()</TT> method was the only + time a constructor was called? As the method returns by value, this is + asking a lot and the code that SWIG generates by default makes it + impossible for the compiler to use<I> return value optimisation (RVO)</I> +. However, this is where the "optimal" attribute in the "out" typemap + can help out. If the typemap code is kept the same and just the + "optimal" attribute specified like this:</P> +<DIV class="code"> +<PRE> +%typemap(out, optimal="1") SWIGTYPE %{ + $result = new $1_ltype((const $1_ltype &)$1); +%} +</PRE> +</DIV> +<P> then when the code is run again, the output is simply:</P> +<DIV class="targetlang"> +<PRE> +XX(0) +~XX() +</PRE> +</DIV> +<P> How the "optimal" attribute works is best explained using the + generated code. Without "optimal", the generated code is:</P> +<DIV class="code"> +<PRE> +SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() { + void * jresult ; + XX result; + result = XX::create(); + jresult = new XX((const XX &)result); + return jresult; +} + +</PRE> +</DIV> +<P> With the "optimal" attribute, the code is:</P> +<DIV class="code"> +<PRE> +SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() { + void * jresult ; + jresult = new XX((const XX &)XX::create()); + return jresult; +} +</PRE> +</DIV> +<P> The major difference is the <TT>result</TT> temporary variable + holding the value returned from <TT>XX::create()</TT> is no longer + generated and instead the copy constructor call is made directly from + the value returned by <TT>XX::create()</TT>. With modern compilers + implementing RVO, the copy is not actually done, in fact the object is + never created on the stack in <TT>XX::create()</TT> at all, it is + simply created directly on the heap. In the first instance, the <TT>$1</TT> + special variable in the typemap is expanded into <TT>result</TT>. In + the second instance, <TT>$1</TT> is expanded into <TT>XX::create()</TT> + and this is essentially what the "optimal" attribute is telling SWIG to + do.</P> +<P> The "optimal" attribute optimisation is not turned on by default as + it has a number of restrictions. Firstly, some code cannot be condensed + into a simple call for passing into the copy constructor. One common + occurrence is when <A href="#exception">%exception</A> is used. + Consider adding the following <TT>%exception</TT> to the example:</P> +<DIV class="code"> +<PRE> +%exception XX::create() %{ +try { + $action +} catch(const std::exception &e) { + cout << e.what() << endl; +} +%} +</PRE> +</DIV> +<P> SWIG can detect when the "optimal" attribute cannot be used and will + ignore it and in this case will issue the following warning:</P> +<DIV class="targetlang"> +<PRE> +example.i:28: Warning(474): Method XX::create() usage of the optimal attribute in the out +typemap at example.i:14 ignored as the following cannot be used to generate optimal code: +try { + result = XX::create(); +} catch(const std::exception &e) { + cout << e.what() << endl; +} +</PRE> +</DIV> +<P> It should be clear that the above code cannot be used as the + argument to the copy constructor call, ie for the <TT>$1</TT> + substitution.</P> +<P> Secondly, if the typemaps uses <TT>$1</TT> more than once, then + multiple calls to the wrapped function will be made. Obviously that is + not very optimal. In fact SWIG attempts to detect this and will issue a + warning something like:</P> +<DIV class="targetlang"> +<PRE> +example.i:21: Warning(475): Multiple calls to XX::create() might be generated due to +optimal attribute usage in the out typemap at example.i:7. +</PRE> +</DIV> +<P> However, it doesn't always get it right, for example when <TT>$1</TT> + is within some commented out code.</P> +<H2><A name="Typemaps_multi_argument_typemaps"></A>10.9 Multi-argument + typemaps</H2> +<P> So far, the typemaps presented have focused on the problem of + dealing with single values. For example, converting a single input + object to a single argument in a function call. However, certain + conversion problems are difficult to handle in this manner. As an + example, consider the example at the very beginning of this chapter:</P> +<DIV class="code"> +<PRE> +int foo(int argc, char *argv[]); +</PRE> +</DIV> +<P> Suppose that you wanted to wrap this function so that it accepted a + single list of strings like this:</P> +<DIV class="targetlang"> +<PRE> +>>> foo(["ale","lager","stout"]) +</PRE> +</DIV> +<P> To do this, you not only need to map a list of strings to <TT>char + *argv[]</TT>, but the value of <TT>int argc</TT> is implicitly + determined by the length of the list. Using only simple typemaps, this + type of conversion is possible, but extremely painful. Therefore, + SWIG1.3 introduces the notion of multi-argument typemaps.</P> +<P> A multi-argument typemap is a conversion rule that specifies how to + convert a<EM> single</EM> object in the target language to set of + consecutive function arguments in C/C++. For example, the following + multi-argument maps perform the conversion described for the above + example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (int argc, char *argv[]) { + int i; + if (!PyList_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting a list"); + return NULL; + } + $1 = PyList_Size($input); + $2 = (char **) malloc(($1+1)*sizeof(char *)); + for (i = 0; i < $1; i++) { + PyObject *s = PyList_GetItem($input,i); + if (!PyString_Check(s)) { + free($2); + PyErr_SetString(PyExc_ValueError, "List items must be strings"); + return NULL; + } + $2[i] = PyString_AsString(s); + } + $2[i] = 0; +} + +%typemap(freearg) (int argc, char *argv[]) { + if ($2) free($2); +} +</PRE> +</DIV> +<P> A multi-argument map is always specified by surrounding the + arguments with parentheses as shown. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (int argc, char *argv[]) { ... } +</PRE> +</DIV> +<P> Within the typemap code, the variables <TT>$1</TT>, <TT>$2</TT>, and + so forth refer to each type in the map. All of the usual substitutions + apply--just use the appropriate <TT>$1</TT> or <TT>$2</TT> prefix on + the variable name (e.g., <TT>$2_type</TT>, <TT>$1_ltype</TT>, etc.)</P> +<P> Multi-argument typemaps always have precedence over simple typemaps + and SWIG always performs longest-match searching. Therefore, you will + get the following behavior:</P> +<DIV class="code"> +<PRE> +%typemap(in) int argc { ... typemap 1 ... } +%typemap(in) (int argc, char *argv[]) { ... typemap 2 ... } +%typemap(in) (int argc, char *argv[], char *env[]) { ... typemap 3 ... } + +int foo(int argc, char *argv[]); // Uses typemap 2 +int bar(int argc, int x); // Uses typemap 1 +int spam(int argc, char *argv[], char *env[]); // Uses typemap 3 +</PRE> +</DIV> +<P> It should be stressed that multi-argument typemaps can appear + anywhere in a function declaration and can appear more than once. For + example, you could write this:</P> +<DIV class="code"> +<PRE> +%typemap(in) (int scount, char *swords[]) { ... } +%typemap(in) (int wcount, char *words[]) { ... } + +void search_words(int scount, char *swords[], int wcount, char *words[], int maxcount); +</PRE> +</DIV> +<P> Other directives such as <TT>%apply</TT> and <TT>%clear</TT> also + work with multi-argument maps. For example:</P> +<DIV class="code"> +<PRE> +%apply (int argc, char *argv[]) { + (int scount, char *swords[]), + (int wcount, char *words[]) +}; +... +%clear (int scount, char *swords[]), (int wcount, char *words[]); +... +</PRE> +</DIV> +<P> Although multi-argument typemaps may seem like an exotic, little + used feature, there are several situations where they make sense. + First, suppose you wanted to wrap functions similar to the low-level <TT> +read()</TT> and <TT>write()</TT> system calls. For example:</P> +<DIV class="code"> +<PRE> +typedef unsigned int size_t; + +int read(int fd, void *rbuffer, size_t len); +int write(int fd, void *wbuffer, size_t len); +</PRE> +</DIV> +<P> As is, the only way to use the functions would be to allocate memory + and pass some kind of pointer as the second argument---a process that + might require the use of a helper function. However, using + multi-argument maps, the functions can be transformed into something + more natural. For example, you might write typemaps like this:</P> +<DIV class="code"> +<PRE> +// typemap for an outgoing buffer +%typemap(in) (void *wbuffer, size_t len) { + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting a string"); + return NULL; + } + $1 = (void *) PyString_AsString($input); + $2 = PyString_Size($input); +} + +// typemap for an incoming buffer +%typemap(in) (void *rbuffer, size_t len) { + if (!PyInt_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting an integer"); + return NULL; + } + $2 = PyInt_AsLong($input); + if ($2 < 0) { + PyErr_SetString(PyExc_ValueError, "Positive integer expected"); + return NULL; + } + $1 = (void *) malloc($2); +} + +// Return the buffer. Discarding any previous return result +%typemap(argout) (void *rbuffer, size_t len) { + Py_XDECREF($result); /* Blow away any previous result */ + if (result < 0) { /* Check for I/O error */ + free($1); + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + $result = PyString_FromStringAndSize($1,result); + free($1); +} +</PRE> +</DIV> +<P> (note: In the above example, <TT>$result</TT> and <TT>result</TT> + are two different variables. <TT>result</TT> is the real C datatype + that was returned by the function. <TT>$result</TT> is the scripting + language object being returned to the interpreter.).</P> +<P> Now, in a script, you can write code that simply passes buffers as + strings like this:</P> +<DIV class="targetlang"> +<PRE> +>>> f = example.open("Makefile") +>>> example.read(f,40) +'TOP = ../..\nSWIG = $(TOP)/.' +>>> example.read(f,40) +'./swig\nSRCS = example.c\nTARGET ' +>>> example.close(f) +0 +>>> g = example.open("foo", example.O_WRONLY | example.O_CREAT, 0644) +>>> example.write(g,"Hello world\n") +12 +>>> example.write(g,"This is a test\n") +15 +>>> example.close(g) +0 +>>> +</PRE> +</DIV> +<P> A number of multi-argument typemap problems also arise in libraries + that perform matrix-calculations--especially if they are mapped onto + low-level Fortran or C code. For example, you might have a function + like this:</P> +<DIV class="code"> +<PRE> +int is_symmetric(double *mat, int rows, int columns); +</PRE> +</DIV> +<P> In this case, you might want to pass some kind of higher-level + object as an matrix. To do this, you could write a multi-argument + typemap like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) (double *mat, int rows, int columns) { + MatrixObject *a; + a = GetMatrixFromObject($input); /* Get matrix somehow */ + + /* Get matrix properties */ + $1 = GetPointer(a); + $2 = GetRows(a); + $3 = GetColumns(a); +} +</PRE> +</DIV> +<P> This kind of technique can be used to hook into scripting-language + matrix packages such as Numeric Python. However, it should also be + stressed that some care is in order. For example, when crossing + languages you may need to worry about issues such as row-major vs. + column-major ordering (and perform conversions if needed).</P> +<H2><A name="runtime_type_checker"></A>10.10 The run-time type checker</H2> +<P> Most scripting languages need type information at run-time. This + type information can include how to construct types, how to garbage + collect types, and the inheritance relationships between types. If the + language interface does not provide its own type information storage, + the generated SWIG code needs to provide it.</P> +<P> Requirements for the type system:</P> +<UL> +<LI>Store inheritance and type equivalence information and be able to + correctly re-create the type pointer.</LI> +<LI>Share type information between modules.</LI> +<LI>Modules can be loaded in any order, irregardless of actual type + dependency.</LI> +<LI>Avoid the use of dynamically allocated memory, and library/system + calls in general.</LI> +<LI>Provide a reasonably fast implementation, minimizing the lookup time + for all language modules.</LI> +<LI>Custom, language specific information can be attached to types.</LI> +<LI>Modules can be unloaded from the type system.</LI> +</UL> +<H3><A name="Typemaps_nn45"></A>10.10.1 Implementation</H3> +<P> The run-time type checker is used by many, but not all, of SWIG's + supported target languages. The run-time type checker features are not + required and are thus not used for strongly typed languages such as + Java and C#. The scripting and scheme based languages rely on it and it + forms a critical part of SWIG's operation for these languages.</P> +<P> When pointers, arrays, and objects are wrapped by SWIG, they are + normally converted into typed pointer objects. For example, an instance + of <TT>Foo *</TT> might be a string encoded like this:</P> +<DIV class="diagram"> +<PRE> +_108e688_p_Foo +</PRE> +</DIV> +<P> At a basic level, the type checker simply restores some type-safety + to extension modules. However, the type checker is also responsible for + making sure that wrapped C++ classes are handled correctly---especially + when inheritance is used. This is especially important when an + extension module makes use of multiple inheritance. For example:</P> +<DIV class="code"> +<PRE> +class Foo { + int x; +}; + +class Bar { + int y; +}; + +class FooBar : public Foo, public Bar { + int z; +}; +</PRE> +</DIV> +<P> When the class <TT>FooBar</TT> is organized in memory, it contains + the contents of the classes <TT>Foo</TT> and <TT>Bar</TT> as well as + its own data members. For example:</P> +<DIV class="diagram"> +<PRE> +FooBar --> | -----------| <-- Foo + | int x | + |------------| <-- Bar + | int y | + |------------| + | int z | + |------------| +</PRE> +</DIV> +<P> Because of the way that base class data is stacked together, the + casting of a <TT>Foobar *</TT> to either of the base classes may change + the actual value of the pointer. This means that it is generally not + safe to represent pointers using a simple integer or a bare <TT>void *</TT> +---type tags are needed to implement correct handling of pointer values + (and to make adjustments when needed).</P> +<P> In the wrapper code generated for each language, pointers are + handled through the use of special type descriptors and conversion + functions. For example, if you look at the wrapper code for Python, you + will see code like this:</P> +<DIV class="code"> +<PRE> +if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_Foo,1)) == -1) return NULL; +</PRE> +</DIV> +<P> In this code, <TT>SWIGTYPE_p_Foo</TT> is the type descriptor that + describes <TT>Foo *</TT>. The type descriptor is actually a pointer to + a structure that contains information about the type name to use in the + target language, a list of equivalent typenames (via typedef or + inheritance), and pointer value handling information (if applicable). + The <TT>SWIG_ConvertPtr()</TT> function is simply a utility function + that takes a pointer object in the target language and a + type-descriptor objects and uses this information to generate a C++ + pointer. However, the exact name and calling conventions of the + conversion function depends on the target language (see language + specific chapters for details).</P> +<P> The actual type code is in swigrun.swg, and gets inserted near the + top of the generated swig wrapper file. The phrase "a type X that can + cast into a type Y" means that given a type X, it can be converted into + a type Y. In other words, X is a derived class of Y or X is a typedef + of Y. The structure to store type information looks like this:</P> +<DIV class="code"> +<PRE> +/* Structure to store information on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name for this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* Linked list of types that can cast into this type */ + void *clientdata; /* Language specific type data */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; +</PRE> +</DIV> +<P> Each <TT>swig_type_info</TT> stores a linked list of types that it + is equivalent to. Each entry in this doubly linked list stores a + pointer back to another swig_type_info structure, along with a pointer + to a conversion function. This conversion function is used to solve the + above problem of the FooBar class, correctly returning a pointer to the + type we want.</P> +<P> The basic problem we need to solve is verifying and building + arguments passed to functions. So going back to the <TT> +SWIG_ConvertPtr()</TT> function example from above, we are expecting a <TT> +Foo *</TT> and need to check if <TT>obj0</TT> is in fact a <TT>Foo *</TT> +. From before, <TT>SWIGTYPE_p_Foo</TT> is just a pointer to the <TT> +swig_type_info</TT> structure describing <TT>Foo *</TT>. So we loop + through the linked list of <TT>swig_cast_info</TT> structures attached + to <TT>SWIGTYPE_p_Foo</TT>. If we see that the type of <TT>obj0</TT> is + in the linked list, we pass the object through the associated + conversion function and then return a positive. If we reach the end of + the linked list without a match, then <TT>obj0</TT> can not be + converted to a <TT>Foo *</TT> and an error is generated.</P> +<P> Another issue needing to be addressed is sharing type information + between multiple modules. More explicitly, we need to have ONE <TT> +swig_type_info</TT> for each type. If two modules both use the type, the + second module loaded must lookup and use the swig_type_info structure + from the module already loaded. Because no dynamic memory is used and + the circular dependencies of the casting information, loading the type + information is somewhat tricky, and not explained here. A complete + description is in the <TT>Lib/swiginit.swg</TT> file (and near the top + of any generated file).</P> +<P> Each module has one swig_module_info structure which looks like + this:</P> +<DIV class="code"> +<PRE> +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structs in this module */ + int size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; +</PRE> +</DIV> +<P> Each module stores an array of pointers to <TT>swig_type_info</TT> + structures and the number of types in this module. So when a second + module is loaded, it finds the <TT>swig_module_info</TT> structure for + the first module and searches the array of types. If any of its own + types are in the first module and have already been loaded, it uses + those <TT>swig_type_info</TT> structures rather than creating new ones. + These <TT>swig_module_info</TT> structures are chained together in a + circularly linked list.</P> +<H3><A name="Typemaps_runtime_type_checker_usage"></A>10.10.2 Usage</H3> +<P>This section covers how to use these functions from typemaps. To + learn how to call these functions from external files (not the + generated _wrap.c file), see the <A href="#external_run_time">External + access to the run-time system</A> section.</P> +<P>When pointers are converted in a typemap, the typemap code often + looks similar to this:</P> +<DIV class="code"> +<PRE> +%typemap(in) Foo * { + if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor)) == -1) return NULL; +} +</PRE> +</DIV> +<P> The most critical part is the typemap is the use of the <TT> +$1_descriptor</TT> special variable. When placed in a typemap, this is + expanded into the <TT>SWIGTYPE_*</TT> type descriptor object above. As + a general rule, you should always use <TT>$1_descriptor</TT> instead of + trying to hard-code the type descriptor name directly.</P> +<P> There is another reason why you should always use the <TT> +$1_descriptor</TT> variable. When this special variable is expanded, + SWIG marks the corresponding type as "in use." When type-tables and + type information is emitted in the wrapper file, descriptor information + is only generated for those datatypes that were actually used in the + interface. This greatly reduces the size of the type tables and + improves efficiency.</P> +<P> Occasionally, you might need to write a typemap that needs to + convert pointers of other types. To handle this, the special variable + macro <TT>$descriptor(type)</TT> covered earlier can be used to + generate the SWIG type descriptor name for any C datatype. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) Foo * { + if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor)) == -1) { + Bar *temp; + if ((SWIG_ConvertPtr($input, (void **) &temp, <B>$descriptor(Bar *)</B>) == -1) { + return NULL; + } + $1 = (Foo *) temp; + } +} +</PRE> +</DIV> +<P> The primary use of <TT>$descriptor(type)</TT> is when writing + typemaps for container objects and other complex data structures. There + are some restrictions on the argument---namely it must be a fully + defined C datatype. It can not be any of the special typemap variables.</P> +<P> In certain cases, SWIG may not generate type-descriptors like you + expect. For example, if you are converting pointers in some + non-standard way or working with an unusual combination of interface + files and modules, you may find that SWIG omits information for a + specific type descriptor. To fix this, you may need to use the <TT> +%types</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%types(int *, short *, long *, float *, double *); +</PRE> +</DIV> +<P> When <TT>%types</TT> is used, SWIG generates type-descriptor + information even if those datatypes never appear elsewhere in the + interface file.</P> +<P> Further details about the run-time type checking can be found in the + documentation for individual language modules. Reading the source code + may also help. The file <TT>Lib/swigrun.swg</TT> in the SWIG library + contains all of the source code for type-checking. This code is also + included in every generated wrapped file so you probably just look at + the output of SWIG to get a better sense for how types are managed.</P> +<H2><A name="Typemaps_overloading"></A>10.11 Typemaps and overloading</H2> +<P> In many target languages, SWIG fully supports C++ overloaded methods + and functions. For example, if you have a collection of functions like + this:</P> +<DIV class="code"> +<PRE> +int foo(int x); +int foo(double x); +int foo(char *s, int y); +</PRE> +</DIV> +<P> You can access the functions in a normal way from the scripting + interpreter:</P> +<DIV class="targetlang"> +<PRE> +# Python +foo(3) # foo(int) +foo(3.5) # foo(double) +foo("hello",5) # foo(char *, int) + +# Tcl +foo 3 # foo(int) +foo 3.5 # foo(double) +foo hello 5 # foo(char *, int) +</PRE> +</DIV> +<P> To implement overloading, SWIG generates a separate wrapper function + for each overloaded method. For example, the above functions would + produce something roughly like this:</P> +<DIV class="code"> +<PRE> +// wrapper pseudocode +_wrap_foo_0(argc, args[]) { // foo(int) + int arg1; + int result; + ... + arg1 = FromInteger(args[0]); + result = foo(arg1); + return ToInteger(result); +} + +_wrap_foo_1(argc, args[]) { // foo(double) + double arg1; + int result; + ... + arg1 = FromDouble(args[0]); + result = foo(arg1); + return ToInteger(result); +} + +_wrap_foo_2(argc, args[]) { // foo(char *, int) + char *arg1; + int arg2; + int result; + ... + arg1 = FromString(args[0]); + arg2 = FromInteger(args[1]); + result = foo(arg1,arg2); + return ToInteger(result); +} + +</PRE> +</DIV> +<P> Next, a dynamic dispatch function is generated:</P> +<DIV class="code"> +<PRE> +_wrap_foo(argc, args[]) { + if (argc == 1) { + if (IsInteger(args[0])) { + return _wrap_foo_0(argc,args); + } + if (IsDouble(args[0])) { + return _wrap_foo_1(argc,args); + } + } + if (argc == 2) { + if (IsString(args[0]) && IsInteger(args[1])) { + return _wrap_foo_2(argc,args); + } + } + error("No matching function!\n"); +} +</PRE> +</DIV> +<P> The purpose of the dynamic dispatch function is to select the + appropriate C++ function based on argument types---a task that must be + performed at runtime in most of SWIG's target languages.</P> +<P> The generation of the dynamic dispatch function is a relatively + tricky affair. Not only must input typemaps be taken into account + (these typemaps can radically change the types of arguments accepted), + but overloaded methods must also be sorted and checked in a very + specific order to resolve potential ambiguity. A high-level overview of + this ranking process is found in the "<A href="#SWIGPlus">SWIG and C++</A> +" chapter. What isn't mentioned in that chapter is the mechanism by + which it is implemented---as a collection of typemaps.</P> +<P> To support dynamic dispatch, SWIG first defines a general purpose + type hierarchy as follows:</P> +<DIV class="diagram"> +<PRE> +Symbolic Name Precedence Value +------------------------------ ------------------ +SWIG_TYPECHECK_POINTER 0 +SWIG_TYPECHECK_VOIDPTR 10 +SWIG_TYPECHECK_BOOL 15 +SWIG_TYPECHECK_UINT8 20 +SWIG_TYPECHECK_INT8 25 +SWIG_TYPECHECK_UINT16 30 +SWIG_TYPECHECK_INT16 35 +SWIG_TYPECHECK_UINT32 40 +SWIG_TYPECHECK_INT32 45 +SWIG_TYPECHECK_UINT64 50 +SWIG_TYPECHECK_INT64 55 +SWIG_TYPECHECK_UINT128 60 +SWIG_TYPECHECK_INT128 65 +SWIG_TYPECHECK_INTEGER 70 +SWIG_TYPECHECK_FLOAT 80 +SWIG_TYPECHECK_DOUBLE 90 +SWIG_TYPECHECK_COMPLEX 100 +SWIG_TYPECHECK_UNICHAR 110 +SWIG_TYPECHECK_UNISTRING 120 +SWIG_TYPECHECK_CHAR 130 +SWIG_TYPECHECK_STRING 140 +SWIG_TYPECHECK_BOOL_ARRAY 1015 +SWIG_TYPECHECK_INT8_ARRAY 1025 +SWIG_TYPECHECK_INT16_ARRAY 1035 +SWIG_TYPECHECK_INT32_ARRAY 1045 +SWIG_TYPECHECK_INT64_ARRAY 1055 +SWIG_TYPECHECK_INT128_ARRAY 1065 +SWIG_TYPECHECK_FLOAT_ARRAY 1080 +SWIG_TYPECHECK_DOUBLE_ARRAY 1090 +SWIG_TYPECHECK_CHAR_ARRAY 1130 +SWIG_TYPECHECK_STRING_ARRAY 1140 +</PRE> +</DIV> +<P> (These precedence levels are defined in <TT>swig.swg</TT>, a library + file that's included by all target language modules.)</P> +<P> In this table, the precedence-level determines the order in which + types are going to be checked. Low values are always checked before + higher values. For example, integers are checked before floats, single + values are checked before arrays, and so forth.</P> +<P> Using the above table as a guide, each target language defines a + collection of "typecheck" typemaps. The follow excerpt from the Python + module illustrates this:</P> +<DIV class="code"> +<PRE> +/* Python type checking rules */ +/* Note: %typecheck(X) is a macro for %typemap(typecheck,precedence=X) */ + +%typecheck(SWIG_TYPECHECK_INTEGER) + int, short, long, + unsigned int, unsigned short, unsigned long, + signed char, unsigned char, + long long, unsigned long long, + const int &, const short &, const long &, + const unsigned int &, const unsigned short &, const unsigned long &, + const long long &, const unsigned long long &, + enum SWIGTYPE, + bool, const bool & +{ + $1 = (PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) + float, double, + const float &, const double & +{ + $1 = (PyFloat_Check($input) || PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_CHAR) char { + $1 = (PyString_Check($input) && (PyString_Size($input) == 1)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + $1 = PyString_Check($input) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *ptr; + if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0) == -1) { + $1 = 0; + PyErr_Clear(); + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { + void *ptr; + if (SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 0) == -1) { + $1 = 0; + PyErr_Clear(); + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *ptr; + if (SWIG_ConvertPtr($input, (void **) &ptr, 0, 0) == -1) { + $1 = 0; + PyErr_Clear(); + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) PyObject * +{ + $1 = ($input != 0); +} +</PRE> +</DIV> +<P> It might take a bit of contemplation, but this code has merely + organized all of the basic C++ types, provided some simple + type-checking code, and assigned each type a precedence value.</P> +<P> Finally, to generate the dynamic dispatch function, SWIG uses the + following algorithm:</P> +<UL> +<LI>Overloaded methods are first sorted by the number of required + arguments.</LI> +<LI>Methods with the same number of arguments are then sorted by + precedence values of argument types.</LI> +<LI>Typecheck typemaps are then emitted to produce a dispatch function + that checks arguments in the correct order.</LI> +</UL> +<P> If you haven't written any typemaps of your own, it is unnecessary + to worry about the typechecking rules. However, if you have written new + input typemaps, you might have to supply a typechecking rule as well. + An easy way to do this is to simply copy one of the existing + typechecking rules. Here is an example,</P> +<DIV class="code"> +<PRE> +// Typemap for a C++ string +%typemap(in) std::string { + if (PyString_Check($input)) { + $1 = std::string(PyString_AsString($input)); + } else { + SWIG_exception(SWIG_TypeError, "string expected"); + } +} +// Copy the typecheck code for "char *". +%typemap(typecheck) std::string = char *; +</PRE> +</DIV> +<P> The bottom line: If you are writing new typemaps and you are using + overloaded methods, you will probably have to write typecheck code or + copy existing code. Since this is a relatively new SWIG feature, there + are few examples to work with. However, you might look at some of the + existing library files likes 'typemaps.i' for a guide.</P> +<P><B> Notes:</B></P> +<UL> +<LI>Typecheck typemaps are not used for non-overloaded methods. Because + of this, it is still always necessary to check types in any "in" + typemaps.</LI> +<LI>The dynamic dispatch process is only meant to be a heuristic. There + are many corner cases where SWIG simply can't disambiguate types to the + same degree as C++. The only way to resolve this ambiguity is to use + the %rename directive to rename one of the overloaded methods + (effectively eliminating overloading).</LI> +<LI> Typechecking may be partial. For example, if working with arrays, + the typecheck code might simply check the type of the first array + element and use that to dispatch to the correct function. Subsequent + "in" typemaps would then perform more extensive type-checking.</LI> +<LI>Make sure you read the section on overloading in the "<A href="#SWIGPlus"> +SWIG and C++</A>" chapter.</LI> +</UL> +<H2><A name="Typemaps_nn48"></A>10.12 More about <TT>%apply</TT> and <TT> +%clear</TT></H2> +<P> In order to implement certain kinds of program behavior, it is + sometimes necessary to write sets of typemaps. For example, to support + output arguments, one often writes a set of typemaps like this:</P> +<DIV class="code"> +<PRE> +%typemap(in,numinputs=0) int *OUTPUT (int temp) { + $1 = &temp; +} +%typemap(argout) int *OUTPUT { + // return value somehow +} +</PRE> +</DIV> +<P> To make it easier to apply the typemap to different argument types + and names, the <TT>%apply</TT> directive performs a copy of all + typemaps from one type to another. For example, if you specify this,</P> +<DIV class="code"> +<PRE> +%apply int *OUTPUT { int *retvalue, int32 *output }; +</PRE> +</DIV> +<P> then all of the <TT>int *OUTPUT</TT> typemaps are copied to <TT>int + *retvalue</TT> and <TT>int32 *output</TT>.</P> +<P> However, there is a subtle aspect of <TT>%apply</TT> that needs more + description. Namely, <TT>%apply</TT> does not overwrite a typemap rule + if it is already defined for the target datatype. This behavior allows + you to do two things:</P> +<UL> +<LI>You can specialize parts of a complex typemap rule by first defining + a few typemaps and then using <TT>%apply</TT> to incorporate the + remaining pieces.</LI> +<LI>Sets of different typemaps can be applied to the same datatype using + repeated <TT>%apply</TT> directives.</LI> +</UL> +<P> For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int *INPUT (int temp) { + temp = ... get value from $input ...; + $1 = &temp; +} + +%typemap(check) int *POSITIVE { + if (*$1 <= 0) { + SWIG_exception(SWIG_ValueError,"Expected a positive number!\n"); + return NULL; + } +} + +... +%apply int *INPUT { int *invalue }; +%apply int *POSITIVE { int *invalue }; +</PRE> +</DIV> +<P> Since <TT>%apply</TT> does not overwrite or replace any existing + rules, the only way to reset behavior is to use the <TT>%clear</TT> + directive. <TT>%clear</TT> removes all typemap rules defined for a + specific datatype. For example:</P> +<DIV class="code"> +<PRE> +%clear int *invalue; +</PRE> +</DIV> +<H2><A name="Typemaps_nn49"></A>10.13 Reducing wrapper code size</H2> +<P> Since the code supplied to a typemap is inlined directly into + wrapper functions, typemaps can result in a tremendous amount of code + bloat. For example, consider this typemap for an array:</P> +<DIV class="code"> +<PRE> +%typemap(in) float [ANY] { + int i; + if (!PySequence_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a sequence"); + return NULL; + } + if (PySequence_Length($input) != $1_dim0) { + PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements"); + return NULL; + } + $1 = (float) malloc($1_dim0*sizeof(float)); + for (i = 0; i < $1_dim0; i++) { + PyObject *o = PySequence_GetItem($input,i); + if (PyNumber_Check(o)) { + $1[i] = (float) PyFloat_AsDouble(o); + } else { + PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); + free(result); + return NULL; + } + } +} +</PRE> +</DIV> +<P> If you had a large interface with hundreds of functions all + accepting array parameters, this typemap would be replicated + repeatedly--generating a huge amount of code. A better approach might + be to consolidate some of the typemap into a function. For example:</P> +<DIV class="code"> +<PRE> +%{ +/* Define a helper function */ +static float * +convert_float_array(PyObject *input, int size) { + int i; + float *result; + if (!PySequence_Check(input)) { + PyErr_SetString(PyExc_ValueError,"Expected a sequence"); + return NULL; + } + if (PySequence_Length(input) != size) { + PyErr_SetString(PyExc_ValueError,"Size mismatch. "); + return NULL; + } + result = (float) malloc(size*sizeof(float)); + for (i = 0; i < size; i++) { + PyObject *o = PySequence_GetItem(input,i); + if (PyNumber_Check(o)) { + result[i] = (float) PyFloat_AsDouble(o); + } else { + PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); + free(result); + return NULL; + } + } + return result; +} +%} + +%typemap(in) float [ANY] { + $1 = convert_float_array($input, $1_dim0); + if (!$1) return NULL; +} +%} +</PRE> +</DIV> +<H2><A name="Typemaps_nn47"></A>10.14 Passing data between typemaps</H2> +<P> It is also important to note that the primary use of local variables + is to create stack-allocated objects for temporary use inside a wrapper + function (this is faster and less-prone to error than allocating data + on the heap). In general, the variables are not intended to pass + information between different types of typemaps. However, this can be + done if you realize that local names have the argument number appended + to them. For example, you could do this:</P> +<DIV class="code"> +<PRE> +%typemap(in) int *(int temp) { + temp = (int) PyInt_AsLong($input); + $1 = &temp; +} + +%typemap(argout) int * { + PyObject *o = PyInt_FromLong(temp$argnum); + ... +} +</PRE> +</DIV> +<P> In this case, the <TT>$argnum</TT> variable is expanded into the + argument number. Therefore, the code will reference the appropriate + local such as <TT>temp1</TT> and <TT>temp2</TT>. It should be noted + that there are plenty of opportunities to break the universe here and + that accessing locals in this manner should probably be avoided. At the + very least, you should make sure that the typemaps sharing information + have exactly the same types and names.</P> +<H2><A name="Typemaps_nn52"></A>10.15 C++ "this" pointer</H2> +<P> All the rules discussed for Typemaps apply to C++ as well as C. + However in addition C++ passes an extra parameter into every non-static + class method -- the <TT>this</TT> pointer. Occasionally it can be + useful to apply a typemap to this pointer (for example to check and + make sure <TT>this</TT> is non-null before deferencing). Actually, C + also has an the equivalent of the <TT>this</TT> pointer which is used + when accessing variables in a C struct.</P> +<P> In order to customise the <TT>this</TT> pointer handling, target a + variable named <TT>self</TT> in your typemaps. <TT>self</TT> is the + name SWIG uses to refer to the extra parameter in wrapped functions.</P> +<P> For example, if wrapping for Java generation:</P> +<DIV class="code"> +<PRE> +%typemap(check) SWIGTYPE *self %{ +if (!$1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "swigCPtr null"); + return $null; +} +%} +</PRE> +</DIV> +<P> In the above case, the <TT>$1</TT> variable is expanded into the + argument name that SWIG is using as the <TT>this</TT> pointer. SWIG + will then insert the check code before the actual C++ class method is + called, and will raise an exception rather than crash the Java virtual + machine. The generated code will look something like:</P> +<DIV class="code"> +<PRE> + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, + "invalid native object; delete() likely already called"); + return ; + } + (arg1)->wrappedFunction(...); +</PRE> +</DIV> +<P> Note that if you have a parameter named <TT>self</TT> then it will + also match the typemap. One work around is to create an interface file + that wraps the method, but give the argument a name other than <TT>self</TT> +.</P> +<H2><A name="Typemaps_nn51"></A>10.16 Where to go for more information?</H2> +<P> The best place to find out more information about writing typemaps + is to look in the SWIG library. Most language modules define all of + their default behavior using typemaps. These are found in files such as + <TT>python.swg</TT>, <TT>perl5.swg</TT>, <TT>tcl8.swg</TT> and so + forth. The <TT>typemaps.i</TT> file in the library also contains + numerous examples. You should look at these files to get a feel for how + to define typemaps of your own. Some of the language modules support + additional typemaps and further information is available in the + individual chapters for each target language. There you may also find + more hands-on practical examples.</P> +<HR NOSHADE> +<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> +<LI><A href="#Customization_nn4">Exception handling with longjmp()</A></LI> +<LI><A href="#Customization_nn5">Handling C++ exceptions</A></LI> +<LI><A href="#Customization_allowexcept">Exception handlers for + variables</A></LI> +<LI><A href="#Customization_nn6">Defining different exception handlers</A> +</LI> +<LI><A href="#Customization_exception_special_variables">Special + variables for %exception</A></LI> +<LI><A href="#Customization_nn7">Using The SWIG exception library</A></LI> +</UL> +</LI> +<LI><A href="#ownership">Object ownership and %newobject</A></LI> +<LI><A href="#features">Features and the %feature directive</A> +<UL> +<LI><A href="#Customization_feature_attributes">Feature attributes</A></LI> +<LI><A href="#Customization_feature_flags">Feature flags</A></LI> +<LI><A href="#Customization_clearing_features">Clearing features</A></LI> +<LI><A href="#Customization_features_default_args">Features and default + arguments</A></LI> +<LI><A href="#features_example">Feature example</A></LI> +</UL> +</LI> +</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 variable <TT>$action</TT> + is one of a few <A href="#Customization_exception_special_variables"> +%exception special variable</A> supported and 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="#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_exception_special_variables"></A>11.1.6 + Special variables for %exception</H3> +<P> The %exception directive supports a few special variables which are + placeholders for code substitution. The following table shows the + available special variables and details what the special variables are + replaced with.</P> +<TABLE summary="Special variables for %exception"> +<TR><TD>$action</TD><TD>The actual operation to be performed (a function + call, method invocation, variable access, etc.)</TD></TR> +<TR><TD>$symname</TD><TD>The symbol name used internally by SWIG</TD></TR> +<TR><TD>$overname</TD><TD>The extra mangling used in the symbol name for + overloaded method. Expands to nothing if the wrapped method is not + overloaded.</TD></TR> +<TR><TD>$wrapname</TD><TD>The language specific wrapper name (usually a + C function name exported from the shared object/dll)</TD></TR> +<TR><TD>$decl</TD><TD>The fully qualified C/C++ declaration of the + method being wrapped without the return type</TD></TR> +<TR><TD>$fulldecl</TD><TD>The fully qualified C/C++ declaration of the + method being wrapped including the return type</TD></TR> +</TABLE> +<P> The special variables are often used in situations where method + calls are logged. Exactly which form of the method call needs logging + is up to individual requirements, but the example code below shows all + the possible expansions, plus how an exception message could be + tailored to show the C++ method declaration:</P> +<DIV class="code"> +<PRE> +%exception Special::something { + log("symname: $symname"); + log("overname: $overname"); + log("wrapname: $wrapname"); + log("decl: $decl"); + log("fulldecl: $fulldecl"); + try { + $action + } + catch (MemoryError) { + croak("Out of memory in $decl"); + } +} +void log(const char *message); +struct Special { + void something(const char *c); + void something(int i); +}; +</PRE> +</DIV> +<P> Below shows the expansions for the 1st of the overloaded <TT> +something</TT> wrapper methods for Perl:</P> +<DIV class="code"> +<PRE> + log("symname: Special_something"); + log("overname: __SWIG_0"); + log("wrapname: _wrap_Special_something__SWIG_0"); + log("decl: Special::something(char const *)"); + log("fulldecl: void Special::something(char const *)"); + try { + (arg1)->something((char const *)arg2); + } + catch (MemoryError) { + croak("Out of memory in Special::something(char const *)"); + } +</PRE> +</DIV> +<H3><A name="Customization_nn7"></A>11.1.7 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="#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.</P> +<H3><A name="Customization_feature_attributes"></A>11.3.1 Feature + attributes</H3> +<P> The <TT>%feature</TT> directive also accepts XML style attributes in + the same way that typemaps do. 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="#exception_handling"> +Java exception handling</A> section.</P> +<H3><A name="Customization_feature_flags"></A>11.3.2 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("featurename") // enables feature +%feature("featurename", "1") // enables feature +%feature("featurename", "x") // enables feature +%feature("featurename", "0") // disables feature +%feature("featurename", "") // 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_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> +<P> As hinted above for <TT>%immutable</TT>, most feature flags can also + be specified via alternative syntax. The alternative syntax is just a + macro in the <TT>swig.swg</TT> Library file. The following shows the + alternative syntax for the imaginary <TT>featurename</TT> feature:</P> +<DIV class="code"> +<PRE> +%featurename // equivalent to %feature("featurename", "1") ie enables feature +%nofeaturename // equivalent to %feature("featurename", "0") ie disables feature +%clearfeaturename // equivalent to %feature("featurename", "") ie clears feature +</PRE> +</DIV> +<P> The concept of clearing features is discussed next.</P> +<H3><A name="Customization_clearing_features"></A>11.3.3 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> +<P> SWIG provides macros for disabling and clearing features. Many of + these can be found in the <TT>swig.swg</TT> library file. The typical + pattern is to define three macros; one to define the feature itself, + one to disable the feature and one to clear the feature. The three + macros below show this for the "except" feature:</P> +<DIV class="code"> +<PRE> +#define %exception %feature("except") +#define %noexception %feature("except","0") +#define %clearexception %feature("except","") +</PRE> +</DIV> +<H3><A name="Customization_features_default_args"></A>11.3.4 Features + and default arguments</H3> +<P> SWIG treats methods with default arguments as separate overloaded + methods as detailed in the <A href="#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_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.5 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> +<HR NOSHADE> +<H1><A name="Contract"></A>12 Contracts</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Contract_nn2">The %contract directive</A></LI> +<LI><A href="#Contract_nn3">%contract and classes</A></LI> +<LI><A href="#Contract_nn4">Constant aggregation and %aggregate_check</A> +</LI> +<LI><A href="#Contract_nn5">Notes</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> A common problem that arises when wrapping C libraries is that of + maintaining reliability and checking for errors. The fact of the matter + is that many C programs are notorious for not providing error checks. + Not only that, when you expose the internals of an application as a + library, it often becomes possible to crash it simply by providing bad + inputs or using it in a way that wasn't intended.</P> +<P> This chapter describes SWIG's support for software contracts. In the + context of SWIG, a contract can be viewed as a runtime constraint that + is attached to a declaration. For example, you can easily attach + argument checking rules, check the output values of a function and + more. When one of the rules is violated by a script, a runtime + exception is generated rather than having the program continue to + execute.</P> +<H2><A name="Contract_nn2"></A>12.1 The %contract directive</H2> +<P> Contracts are added to a declaration using the %contract directive. + Here is a simple example:</P> +<DIV class="code"> +<PRE> +%contract sqrt(double x) { +require: + x >= 0; +ensure: + sqrt >= 0; +} + +... +double sqrt(double); +</PRE> +</DIV> +<P> In this case, a contract is being added to the <TT>sqrt()</TT> + function. The <TT>%contract</TT> directive must always appear before + the declaration in question. Within the contract there are two + sections, both of which are optional. The <TT>require:</TT> section + specifies conditions that must hold before the function is called. + Typically, this is used to check argument values. The <TT>ensure:</TT> + section specifies conditions that must hold after the function is + called. This is often used to check return values or the state of the + program. In both cases, the conditions that must hold must be specified + as boolean expressions.</P> +<P> In the above example, we're simply making sure that sqrt() returns a + non-negative number (if it didn't, then it would be broken in some + way).</P> +<P> Once a contract has been specified, it modifies the behavior of the + resulting module. For example:</P> +<DIV class="shell"> +<PRE> +>>> example.sqrt(2) +1.4142135623730951 +>>> example.sqrt(-2) +Traceback (most recent call last): + File "<stdin>", line 1, in ? +RuntimeError: Contract violation: require: (arg1>=0) +>>> +</PRE> +</DIV> +<H2><A name="Contract_nn3"></A>12.2 %contract and classes</H2> +<P> The <TT>%contract</TT> directive can also be applied to class + methods and constructors. For example:</P> +<DIV class="code"> +<PRE> +%contract Foo::bar(int x, int y) { +require: + x > 0; +ensure: + bar > 0; +} + +%contract Foo::Foo(int a) { +require: + a > 0; +} + +class Foo { +public: + Foo(int); + int bar(int, int); +}; +</PRE> +</DIV> +<P> The way in which <TT>%contract</TT> is applied is exactly the same + as the <TT>%feature</TT> directive. Thus, any contract that you + specified for a base class will also be attached to inherited methods. + For example:</P> +<DIV class="code"> +<PRE> +class Spam : public Foo { +public: + int bar(int,int); // Gets contract defined for Foo::bar(int,int) +}; +</PRE> +</DIV> +<P> In addition to this, separate contracts can be applied to both the + base class and a derived class. For example:</P> +<DIV class="code"> +<PRE> +%contract Foo::bar(int x, int) { +require: + x > 0; +} + +%contract Spam::bar(int, int y) { +require: + y > 0; +} + +class Foo { +public: + int bar(int,int); // Gets Foo::bar contract. +}; + +class Spam : public Foo { +public: + int bar(int,int); // Gets Foo::bar and Spam::bar contract +}; +</PRE> +</DIV> +<P> When more than one contract is applied, the conditions specified in + a "require:" section are combined together using a logical-AND + operation. In other words conditions specified for the base class and + conditions specified for the derived class all must hold. In the above + example, this means that both the arguments to <TT>Spam::bar</TT> must + be positive.</P> +<H2><A name="Contract_nn4"></A>12.3 Constant aggregation and + %aggregate_check</H2> +<P> Consider an interface file that contains the following code:</P> +<DIV class="code"> +<PRE> +#define UP 1 +#define DOWN 2 +#define RIGHT 3 +#define LEFT 4 + +void move(SomeObject *, int direction, int distance); +</PRE> +</DIV> +<P> One thing you might want to do is impose a constraint on the + direction parameter to make sure it's one of a few accepted values. To + do that, SWIG provides an easy to use macro %aggregate_check() that + works like this:</P> +<DIV class="code"> +<PRE> +%aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT); +</PRE> +</DIV> +<P> This merely defines a utility function of the form</P> +<DIV class="code"> +<PRE> +int check_direction(int x); +</PRE> +</DIV> +<P> That checks the argument x to see if it is one of the values listed. + This utility function can be used in contracts. For example:</P> +<DIV class="code"> +<PRE> +%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT); + +%contract move(SomeObject *, int direction, in) { +require: + check_direction(direction); +} + +#define UP 1 +#define DOWN 2 +#define RIGHT 3 +#define LEFT 4 + +void move(SomeObject *, int direction, int distance); +</PRE> +</DIV> +<P> Alternatively, it can be used in typemaps and other directives. For + example:</P> +<DIV class="code"> +<PRE> +%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT); + +%typemap(check) int direction { + if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction"); +} + +#define UP 1 +#define DOWN 2 +#define RIGHT 3 +#define LEFT 4 + +void move(SomeObject *, int direction, int distance); +</PRE> +</DIV> +<P> Regrettably, there is no automatic way to perform similar checks + with enums values. Maybe in a future release.</P> +<H2><A name="Contract_nn5"></A>12.4 Notes</H2> +<P> Contract support was implemented by Songyan (Tiger) Feng and first + appeared in SWIG-1.3.20.</P> +<HR NOSHADE> +<H1><A name="Varargs"></A>13 Variable Length Arguments</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Varargs_nn2">Introduction</A></LI> +<LI><A href="#Varargs_nn3">The Problem</A></LI> +<LI><A href="#Varargs_nn4">Default varargs support</A></LI> +<LI><A href="#Varargs_nn5">Argument replacement using %varargs</A></LI> +<LI><A href="#Varargs_nn6">Varargs and typemaps</A></LI> +<LI><A href="#Varargs_nn7">Varargs wrapping with libffi</A></LI> +<LI><A href="#Varargs_nn8">Wrapping of va_list</A></LI> +<LI><A href="#Varargs_nn9">C++ Issues</A></LI> +<LI><A href="#Varargs_nn10">Discussion</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P><B> (a.k.a, "The horror. The horror.")</B></P> +<P> This chapter describes the problem of wrapping functions that take a + variable number of arguments. For instance, generating wrappers for the + C <TT>printf()</TT> family of functions.</P> +<P> This topic is sufficiently advanced to merit its own chapter. In + fact, support for varargs is an often requested feature that was first + added in SWIG-1.3.12. Most other wrapper generation tools have wisely + chosen to avoid this issue.</P> +<H2><A name="Varargs_nn2"></A>13.1 Introduction</H2> +<P> Some C and C++ programs may include functions that accept a variable + number of arguments. For example, most programmers are familiar with + functions from the C library such as the following:</P> +<DIV class="code"> +<PRE> +int printf(const char *fmt, ...) +int fprintf(FILE *, const char *fmt, ...); +int sprintf(char *s, const char *fmt, ...); +</PRE> +</DIV> +<P> Although there is probably little practical purpose in wrapping + these specific C library functions in a scripting language (what would + be the point?), a library may include its own set of special functions + based on a similar API. For example:</P> +<DIV class="code"> +<PRE> +int traceprintf(const char *fmt, ...); +</PRE> +</DIV> +<P> In this case, you may want to have some kind of access from the + target language.</P> +<P> Before describing the SWIG implementation, it is important to + discuss the common uses of varargs that you are likely to encounter in + real programs. Obviously, there are the <TT>printf()</TT> style output + functions as shown. Closely related to this would be <TT>scanf()</TT> + style input functions that accept a format string and a list of + pointers into which return values are placed. However, variable length + arguments are also sometimes used to write functions that accept a + NULL-terminated list of pointers. A good example of this would be a + function like this:</P> +<DIV class="code"> +<PRE> +int execlp(const char *path, const char *arg1, ...); +... + +/* Example */ +execlp("ls","ls","-l",NULL); +</PRE> +</DIV> +<P> In addition, varargs is sometimes used to fake default arguments in + older C libraries. For instance, the low level <TT>open()</TT> system + call is often declared as a varargs function so that it will accept two + or three arguments:</P> +<DIV class="code"> +<PRE> +int open(const char *path, int oflag, ...); +... + +/* Examples */ +f = open("foo", O_RDONLY); +g = open("bar", O_WRONLY | O_CREAT, 0644); +</PRE> +</DIV> +<P> Finally, to implement a varargs function, recall that you have to + use the C library functions defined in <TT><stdarg.h></TT>. For + example:</P> +<DIV class="code"> +<PRE> +List make_list(const char *s, ...) { + va_list ap; + List x; + ... + va_start(ap, s); + while (s) { + x.append(s); + s = va_arg(ap, const char *); + } + va_end(ap); + return x; +} +</PRE> +</DIV> +<H2><A name="Varargs_nn3"></A>13.2 The Problem</H2> +<P> Generating wrappers for a variable length argument function presents + a number of special challenges. Although C provides support for + implementing functions that receive variable length arguments, there + are no functions that can go in the other direction. Specifically, you + can't write a function that dynamically creates a list of arguments and + which invokes a varargs function on your behalf.</P> +<P> Although it is possible to write functions that accept the special + type <TT>va_list</TT>, this is something entirely different. You can't + take a <TT>va_list</TT> structure and pass it in place of the variable + length arguments to another varargs function. It just doesn't work.</P> +<P> The reason this doesn't work has to do with the way that function + calls get compiled. For example, suppose that your program has a + function call like this:</P> +<DIV class="code"> +<PRE> +printf("Hello %s. Your number is %d\n", name, num); +</PRE> +</DIV> +<P> When the compiler looks at this, it knows that you are calling <TT> +printf()</TT> with exactly three arguments. Furthermore, it knows that + the number of arguments as well are their types and sizes is<EM> never</EM> + going to change during program execution. Therefore, this gets turned + to machine code that sets up a three-argument stack frame followed by a + call to <TT>printf()</TT>.</P> +<P> In contrast, suppose you attempted to make some kind of wrapper + around <TT>printf()</TT> using code like this:</P> +<DIV class="code"> +<PRE> +int wrap_printf(const char *fmt, ...) { + va_list ap; + va_start(ap,fmt); + ... + printf(fmt,ap); + ... + va_end(ap); +}; +</PRE> +</DIV> +<P> Although this code might compile, it won't do what you expect. This + is because the call to <TT>printf()</TT> is compiled as a procedure + call involving only two arguments. However, clearly a two-argument + configuration of the call stack is completely wrong if your intent is + to pass an arbitrary number of arguments to the real <TT>printf()</TT>. + Needless to say, it won't work.</P> +<P> Unfortunately, the situation just described is exactly the problem + faced by wrapper generation tools. In general, the number of passed + arguments will not be known until run-time. To make matters even worse, + you won't know the types and sizes of arguments until run-time as well. + Needless to say, there is no obvious way to make the C compiler + generate code for a function call involving an unknown number of + arguments of unknown types.</P> +<P> In theory, it<EM> is</EM> possible to write a wrapper that does the + right thing. However, this involves knowing the underlying ABI for the + target platform and language as well as writing special purpose code + that manually constructed the call stack before making a procedure + call. Unfortunately, both of these tasks require the use of inline + assembly code. Clearly, that's the kind of solution you would much + rather avoid.</P> +<P> With this nastiness in mind, SWIG provides a number of solutions to + the varargs wrapping problem. Most of these solutions are compromises + that provide limited varargs support without having to resort to + assembly language. However, SWIG can also support real varargs wrapping + (with stack-frame manipulation) if you are willing to get hands dirty. + Keep reading.</P> +<H2><A name="Varargs_nn4"></A>13.3 Default varargs support</H2> +<P> When variable length arguments appear in an interface, the default + behavior is to drop the variable argument list entirely, replacing them + with a single NULL pointer. For example, if you had this function,</P> +<DIV class="code"> +<PRE> +void traceprintf(const char *fmt, ...); +</PRE> +</DIV> +<P> it would be wrapped as if it had been declared as follows:</P> +<DIV class="code"> +<PRE> +void traceprintf(const char *fmt); +</PRE> +</DIV> +<P> When the function is called inside the wrappers, it is called as + follows:</P> +<DIV class="code"> +<PRE> +traceprintf(arg1, NULL); +</PRE> +</DIV> +<P> Arguably, this approach seems to defeat the whole point of variable + length arguments. However, this actually provides enough support for + many simple kinds of varargs functions to still be useful. For + instance, you could make function calls like this (in Python):</P> +<DIV class="targetlang"> +<PRE> +>>> traceprintf("Hello World") +>>> traceprintf("Hello %s. Your number is %d\n" % (name, num)) +</PRE> +</DIV> +<P> Notice how string formatting is being done in Python instead of C.</P> +<H2><A name="Varargs_nn5"></A>13.4 Argument replacement using %varargs</H2> +<P> Instead of dropping the variable length arguments, an alternative + approach is to replace <TT>(...)</TT> with a set of suitable arguments. + SWIG provides a special <TT>%varargs</TT> directive that can be used to + do this. For example,</P> +<DIV class="code"> +<PRE> +%varargs(int mode = 0) open; +... +int open(const char *path, int oflags, ...); +</PRE> +</DIV> +<P> is equivalent to this:</P> +<DIV class="code"> +<PRE> +int open(const char *path, int oflags, int mode = 0); +</PRE> +</DIV> +<P> In this case, <TT>%varargs</TT> is simply providing more specific + information about the extra arguments that might be passed to a + function. If the parameters to a varargs function are of uniform type, <TT> +%varargs</TT> can also accept a numerical argument count as follows:</P> +<DIV class="code"> +<PRE> +%varargs(10,char *arg = NULL) execlp; +... +int execlp(const char *path, const char *arg1, ...); +</PRE> +</DIV> +<P> This would wrap <TT>execlp()</TT> as a function that accepted up to + 10 optional arguments. Depending on the application, this may be more + than enough for practical purposes.</P> +<P> Argument replacement is most appropriate in cases where the types of + the extra arguments is uniform and the maximum number of arguments is + known. When replicated argument replacement is used, at least one extra + argument is added to the end of the arguments when making the function + call. This argument serves as a sentinel to make sure the list is + properly terminated. It has the same value as that supplied to the <TT> +%varargs</TT> directive.</P> +<P> Argument replacement is not as useful when working with functions + that accept mixed argument types such as <TT>printf()</TT>. Providing + general purpose wrappers to such functions presents special problems + (covered shortly).</P> +<H2><A name="Varargs_nn6"></A>13.5 Varargs and typemaps</H2> +<P> Variable length arguments may be used in typemap specifications. For + example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (...) { + // Get variable length arguments (somehow) + ... +} + +%typemap(in) (const char *fmt, ...) { + // Multi-argument typemap +} +</PRE> +</DIV> +<P> However, this immediately raises the question of what "type" is + actually used to represent <TT>(...)</TT>. For lack of a better + alternative, the type of <TT>(...)</TT> is set to <TT>void *</TT>. + Since there is no way to dynamically pass arguments to a varargs + function (as previously described), the <TT>void *</TT> argument value + is intended to serve as a place holder for storing some kind of + information about the extra arguments (if any). In addition, the + default behavior of SWIG is to pass the <TT>void *</TT> value as an + argument to the function. Therefore, you could use the pointer to hold + a valid argument value if you wanted.</P> +<P> To illustrate, here is a safer version of wrapping <TT>printf()</TT> + in Python:</P> +<DIV class="code"> +<PRE> +%typemap(in) (const char *fmt, ...) { + $1 = "%s"; /* Fix format string to %s */ + $2 = (void *) PyString_AsString($input); /* Get string argument */ +}; +... +int printf(const char *fmt, ...); +</PRE> +</DIV> +<P> In this example, the format string is implicitly set to <TT>"%s"</TT> +. This prevents a program from passing a bogus format string to the + extension. Then, the passed input object is decoded and placed in the <TT> +void *</TT> argument defined for the <TT>(...)</TT> argument. When the + actual function call is made, the underlying wrapper code will look + roughly like this:</P> +<DIV class="code"> +<PRE> +wrap_printf() { + char *arg1; + void *arg2; + int result; + + arg1 = "%s"; + arg2 = (void *) PyString_AsString(arg2obj); + ... + result = printf(arg1,arg2); + ... +} +</PRE> +</DIV> +<P> Notice how both arguments are passed to the function and it does + what you would expect.</P> +<P> The next example illustrates a more advanced kind of varargs + typemap. Disclaimer: this requires special support in the target + language module and is not guaranteed to work with all SWIG modules at + this time. It also starts to illustrate some of the more fundamental + problems with supporting varargs in more generality.</P> +<P> If a typemap is defined for any form of <TT>(...)</TT>, many SWIG + modules will generate wrappers that accept a variable number of + arguments as input and will make these arguments available in some + form. The precise details of this depends on the language module being + used (consult the appropriate chapter for more details). However, + suppose that you wanted to create a Python wrapper for the <TT>execlp()</TT> + function shown earlier. To do this using a typemap instead of using <TT> +%varargs</TT>, you might first write a typemap like this:</P> +<DIV class="code"> +<PRE> +%typemap(in) (...)(char *args[10]) { + int i; + int argc; + for (i = 0; i < 10; i++) args[i] = 0; + argc = PyTuple_Size(varargs); + if (argc > 10) { + PyErr_SetString(PyExc_ValueError,"Too many arguments"); + return NULL; + } + for (i = 0; i < argc; i++) { + PyObject *o = PyTuple_GetItem(varargs,i); + if (!PyString_Check(o)) { + PyErr_SetString(PyExc_ValueError,"Expected a string"); + return NULL; + } + args[i] = PyString_AsString(o); + } + $1 = (void *) args; +} +</PRE> +</DIV> +<P> In this typemap, the special variable <TT>varargs</TT> is a tuple + holding all of the extra arguments passed (this is specific to the + Python module). The typemap then pulls this apart and sticks the values + into the array of strings <TT>args</TT>. Then, the array is assigned to + <TT>$1</TT> (recall that this is the <TT>void *</TT> variable + corresponding to <TT>(...)</TT>). However, this assignment is only half + of the picture----clearly this alone is not enough to make the function + work. To patch everything up, you have to rewrite the underlying action + code using the <TT>%feature</TT> directive like this:</P> +<DIV class="code"> +<PRE> +%feature("action") execlp { + char *args = (char **) arg3; + result = execlp(arg1, arg2, args[0], args[1], args[2], args[3], args[4], + args[5],args[6],args[7],args[8],args[9], NULL); +} + +int execlp(const char *path, const char *arg, ...); +</PRE> +</DIV> +<P> This patches everything up and creates a function that more or less + works. However, don't try explaining this to your coworkers unless you + know for certain that they've had several cups of coffee. If you really + want to elevate your guru status and increase your job security, + continue to the next section.</P> +<H2><A name="Varargs_nn7"></A>13.6 Varargs wrapping with libffi</H2> +<P> All of the previous examples have relied on features of SWIG that + are portable and which don't rely upon any low-level machine-level + details. In many ways, they have all dodged the real issue of variable + length arguments by recasting a varargs function into some weaker + variation with a fixed number of arguments of known types. In many + cases, this works perfectly fine. However, if you want more generality + than this, you need to bring out some bigger guns.</P> +<P> One way to do this is to use a special purpose library such as + libffi (<A href="http://sources.redhat.com/libffi/"> +http://sources.redhat.com/libffi</A>). libffi is a library that allows + you to dynamically construct call-stacks and invoke procedures in a + relatively platform independent manner. Details about the library can + be found in the libffi distribution and are not repeated here.</P> +<P> To illustrate the use of libffi, suppose that you<EM> really</EM> + wanted to create a wrapper for <TT>execlp()</TT> that accepted<EM> any</EM> + number of arguments. To do this, you might make a few adjustments to + the previous example. For example:</P> +<DIV class="code"> +<PRE> +/* Take an arbitrary number of extra arguments and place into an array + of strings */ + +%typemap(in) (...) { + char **argv; + int argc; + int i; + + argc = PyTuple_Size(varargs); + argv = (char **) malloc(sizeof(char *)*(argc+1)); + for (i = 0; i < argc; i++) { + PyObject *o = PyTuple_GetItem(varargs,i); + if (!PyString_Check(o)) { + PyErr_SetString(PyExc_ValueError,"Expected a string"); + free(argv); + return NULL; + } + argv[i] = PyString_AsString(o); + } + argv[i] = NULL; + $1 = (void *) argv; +} + +/* Rewrite the function call, using libffi */ + +%feature("action") execlp { + int i, vc; + ffi_cif cif; + ffi_type **types; + void **values; + char **args; + + vc = PyTuple_Size(varargs); + types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *)); + values = (void **) malloc((vc+3)*sizeof(void *)); + args = (char **) arg3; + + /* Set up path parameter */ + types[0] = &ffi_type_pointer; + values[0] = &arg1; + + /* Set up first argument */ + types[1] = &ffi_type_pointer; + values[1] = &arg2; + + /* Set up rest of parameters */ + for (i = 0; i <= vc; i++) { + types[2+i] = &ffi_type_pointer; + values[2+i] = &args[i]; + } + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3, + &ffi_type_uint, types) == FFI_OK) { + ffi_call(&cif, (void (*)()) execlp, &result, values); + } else { + PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); + free(types); + free(values); + free(arg3); + return NULL; + } + free(types); + free(values); + free(arg3); +} + +/* Declare the function. Whew! */ +int execlp(const char *path, const char *arg1, ...); +</PRE> +</DIV> +<P> Looking at this example, you may start to wonder if SWIG is making + life any easier. Given the amount of code involved, you might also + wonder why you didn't just write a hand-crafted wrapper! Either that or + you're wondering "why in the hell am I trying to wrap this varargs + function in the first place?!?" Obviously, those are questions you'll + have to answer for yourself.</P> +<P> As a more extreme example of libffi, here is some code that attempts + to wrap <TT>printf()</TT>,</P> +<DIV class="code"> +<PRE> +/* A wrapper for printf() using libffi */ + +%{ +/* Structure for holding passed arguments after conversion */ + typedef struct { + int type; + union { + int ivalue; + double dvalue; + void *pvalue; + } val; + } vtype; + enum { VT_INT, VT_DOUBLE, VT_POINTER }; +%} + +%typemap(in) (const char *fmt, ...) { + vtype *argv; + int argc; + int i; + + /* Format string */ + $1 = PyString_AsString($input); + + /* Variable length arguments */ + argc = PyTuple_Size(varargs); + argv = (vtype *) malloc(argc*sizeof(vtype)); + for (i = 0; i < argc; i++) { + PyObject *o = PyTuple_GetItem(varargs,i); + if (PyInt_Check(o)) { + argv[i].type = VT_INT; + argv[i].val.ivalue = PyInt_AsLong(o); + } else if (PyFloat_Check(o)) { + argv[i].type = VT_DOUBLE; + argv[i].val.dvalue = PyFloat_AsDouble(o); + } else if (PyString_Check(o)) { + argv[i].type = VT_POINTER; + argv[i].val.pvalue = (void *) PyString_AsString(o); + } else { + PyErr_SetString(PyExc_ValueError,"Unsupported argument type"); + free(argv); + return NULL; + } + } + $2 = (void *) argv; +} + +/* Rewrite the function call using libffi */ +%feature("action") printf { + int i, vc; + ffi_cif cif; + ffi_type **types; + void **values; + vtype *args; + + vc = PyTuple_Size(varargs); + types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *)); + values = (void **) malloc((vc+1)*sizeof(void *)); + args = (vtype *) arg2; + + /* Set up fmt parameter */ + types[0] = &ffi_type_pointer; + values[0] = &arg1; + + /* Set up rest of parameters */ + for (i = 0; i < vc; i++) { + switch(args[i].type) { + case VT_INT: + types[1+i] = &ffi_type_uint; + values[1+i] = &args[i].val.ivalue; + break; + case VT_DOUBLE: + types[1+i] = &ffi_type_double; + values[1+i] = &args[i].val.dvalue; + break; + case VT_POINTER: + types[1+i] = &ffi_type_pointer; + values[1+i] = &args[i].val.pvalue; + break; + default: + abort(); /* Whoa! We're seriously hosed */ + break; + } + } + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1, + &ffi_type_uint, types) == FFI_OK) { + ffi_call(&cif, (void (*)()) printf, &result, values); + } else { + PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); + free(types); + free(values); + free(args); + return NULL; + } + free(types); + free(values); + free(args); +} + +/* The function */ +int printf(const char *fmt, ...); +</PRE> +</DIV> +<P> Much to your amazement, it even seems to work if you try it:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> example.printf("Grade: %s %d/60 = %0.2f%%\n", "Dave", 47, 47.0*100/60) +Grade: Dave 47/60 = 78.33% +>>> +</PRE> +</DIV> +<P> Of course, there are still some limitations to consider:</P> +<DIV class="targetlang"> +<PRE> +>>> example.printf("la de da de da %s", 42) +Segmentation fault (core dumped) +</PRE> +</DIV> +<P> And, on this note, we leave further exploration of libffi to the + reader as an exercise. Although Python has been used as an example, + most of the techniques in this section can be extrapolated to other + language modules with a bit of work. The only details you need to know + is how the extra arguments are accessed in each target language. For + example, in the Python module, we used the special <TT>varargs</TT> + variable to get these arguments. Modules such as Tcl8 and Perl5 simply + provide an argument number for the first extra argument. This can be + used to index into an array of passed arguments to get values. Please + consult the chapter on each language module for more details.</P> +<H2><A name="Varargs_nn8"></A>13.7 Wrapping of va_list</H2> +<P> Closely related to variable length argument wrapping, you may + encounter functions that accept a parameter of type <TT>va_list</TT>. + For example:</P> +<DIV class="code"> +<PRE> +int vfprintf(FILE *f, const char *fmt, va_list ap); +</PRE> +</DIV> +<P> As far as we know, there is no obvious way to wrap these functions + with SWIG. This is because there is no documented way to assemble the + proper va_list structure (there are no C library functions to do it and + the contents of va_list are opaque). Not only that, the contents of a <TT> +va_list</TT> structure are closely tied to the underlying call-stack. + It's not clear that exporting a <TT>va_list</TT> would have any use or + that it would work at all.</P> +<H2><A name="Varargs_nn9"></A>13.8 C++ Issues</H2> +<P> Wrapping of C++ member functions that accept a variable number of + arguments presents a number of challenges. By far, the easiest way to + handle this is to use the <TT>%varargs</TT> directive. This is portable + and it fully supports classes much like the <TT>%rename</TT> directive. + For example:</P> +<DIV class="code"> +<PRE> +%varargs (10, char * = NULL) Foo::bar; + +class Foo { +public: + virtual void bar(char *arg, ...); // gets varargs above +}; + +class Spam: public Foo { +public: + virtual void bar(char *arg, ...); // gets varargs above +}; +</PRE> +</DIV> +<P> <TT>%varargs</TT> also works with constructors, operators, and any + other C++ programming construct that accepts variable arguments.</P> +<P> Doing anything more advanced than this is likely to involve a + serious world of pain. In order to use a library like libffi, you will + need to know the underlying calling conventions and details of the C++ + ABI. For instance, the details of how <TT>this</TT> is passed to member + functions as well as any hidden arguments that might be used to pass + additional information. These details are implementation specific and + may differ between compilers and even different versions of the same + compiler. Also, be aware that invoking a member function is further + complicated if it is a virtual method. In this case, invocation might + require a table lookup to obtain the proper function address (although + you might be able to obtain an address by casting a bound pointer to a + pointer to function as described in the C++ ARM section 18.3.4).</P> +<P> If you do decide to change the underlying action code, be aware that + SWIG always places the <TT>this</TT> pointer in <TT>arg1</TT>. Other + arguments are placed in <TT>arg2</TT>, <TT>arg3</TT>, and so forth. For + example:</P> +<DIV class="code"> +<PRE> +%feature("action") Foo::bar { + ... + result = arg1->bar(arg2, arg3, etc.); + ... +} +</PRE> +</DIV> +<P> Given the potential to shoot yourself in the foot, it is probably + easier to reconsider your design or to provide an alternative interface + using a helper function than it is to create a fully general wrapper to + a varargs C++ member function.</P> +<H2><A name="Varargs_nn10"></A>13.9 Discussion</H2> +<P> This chapter has provided a number of techniques that can be used to + address the problem of variable length argument wrapping. If you care + about portability and ease of use, the <TT>%varargs</TT> directive is + probably the easiest way to tackle the problem. However, using + typemaps, it is possible to do some very advanced kinds of wrapping.</P> +<P> One point of discussion concerns the structure of the libffi + examples in the previous section. Looking at that code, it is not at + all clear that this is the easiest way to solve the problem. However, + there are a number of subtle aspects of the solution to + consider--mostly concerning the way in which the problem has been + decomposed. First, the example is structured in a way that tries to + maintain separation between wrapper-specific information and the + declaration of the function itself. The idea here is that you might + structure your interface like this:</P> +<DIV class="code"> +<PRE> +%typemap(const char *fmt, ...) { + ... +} +%feature("action") traceprintf { + ... +} + +/* Include some header file with traceprintf in it */ +%include "someheader.h" +</PRE> +</DIV> +<P> Second, careful scrutiny will reveal that the typemaps involving <TT> +(...)</TT> have nothing whatsoever to do with the libffi library. In + fact, they are generic with respect to the way in which the function is + actually called. This decoupling means that it will be much easier to + consider other library alternatives for making the function call. For + instance, if libffi wasn't supported on a certain platform, you might + be able to use something else instead. You could use conditional + compilation to control this:</P> +<DIV class="code"> +<PRE> +#ifdef USE_LIBFFI +%feature("action") printf { + ... +} +#endif +#ifdef USE_OTHERFFI +%feature("action") printf { +... +} +#endif +</PRE> +</DIV> +<P> Finally, even though you might be inclined to just write a + hand-written wrapper for varargs functions, the techniques used in the + previous section have the advantage of being compatible with all other + features of SWIG such as exception handling.</P> +<P> As a final word, some C programmers seem to have the assumption that + the wrapping of variable length argument functions is an easily solved + problem. However, this section has hopefully dispelled some of these + myths. All things being equal, you are better off avoiding variable + length arguments if you can. If you can't avoid them, please consider + some of the simple solutions first. If you can't live with a simple + solution, proceed with caution. At the very least, make sure you + carefully read the section "A7.3.2 Function Calls" in Kernighan and + Ritchie and make sure you fully understand the parameter passing + conventions used for varargs. Also, be aware of the platform + dependencies and reliability issues that this will introduce. Good + luck.</P> +<HR NOSHADE> +<H1><A name="Warnings"></A>14 Warning Messages</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Warnings_nn2">Introduction</A></LI> +<LI><A href="#Warnings_suppression">Warning message suppression</A></LI> +<LI><A href="#Warnings_nn4">Enabling extra warnings</A></LI> +<LI><A href="#Warnings_nn5">Issuing a warning message</A></LI> +<LI><A href="#Warnings_symbolic_symbols">Symbolic symbols</A></LI> +<LI><A href="#Warnings_nn6">Commentary</A></LI> +<LI><A href="#Warnings_nn7">Warnings as errors</A></LI> +<LI><A href="#Warnings_nn8">Message output format</A></LI> +<LI><A href="#Warnings_nn9">Warning number reference</A> +<UL> +<LI><A href="#Warnings_nn10">Deprecated features (100-199)</A></LI> +<LI><A href="#Warnings_nn11">Preprocessor (200-299)</A></LI> +<LI><A href="#Warnings_nn12">C/C++ Parser (300-399)</A></LI> +<LI><A href="#Warnings_nn13">Types and typemaps (400-499)</A></LI> +<LI><A href="#Warnings_nn14">Code generation (500-599)</A></LI> +<LI><A href="#Warnings_nn15">Language module specific (800-899)</A></LI> +<LI><A href="#Warnings_nn16">User defined (900-999)</A></LI> +</UL> +</LI> +<LI><A href="#Warnings_nn17">History</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<H2><A name="Warnings_nn2"></A>14.1 Introduction</H2> +<P> During compilation, SWIG may generate a variety of warning messages. + For example:</P> +<DIV class="shell"> +<PRE> +example.i:16: Warning(501): Overloaded declaration ignored. bar(double) +example.i:15: Warning(501): Previous declaration is bar(int) +</PRE> +</DIV> +<P> Typically, warning messages indicate non-fatal problems with the + input where the generated wrapper code will probably compile, but it + may not work like you expect.</P> +<H2><A name="Warnings_suppression"></A>14.2 Warning message suppression</H2> +<P> All warning messages have a numeric code that is shown in the + warning message itself. To suppress the printing of a warning message, + a number of techniques can be used. First, you can run SWIG with the <TT> +-w</TT> command line option. For example:</P> +<DIV class="shell"> +<PRE> +% swig -python -w501 example.i +% swig -python -w501,505,401 example.i +</PRE> +</DIV> +<P> Alternatively, warnings can be suppressed by inserting a special + preprocessor pragma into the input file:</P> +<DIV class="code"> +<PRE> +%module example +#pragma SWIG nowarn=501 +#pragma SWIG nowarn=501,505,401 +</PRE> +</DIV> +<P> Finally, code-generation warnings can be disabled on a declaration + by declaration basis using the <TT>%warnfilter</TT> directive. For + example:</P> +<DIV class="code"> +<PRE> +%module example +%warnfilter(501) foo; +... +int foo(int); +int foo(double); // Silently ignored. +</PRE> +</DIV> +<P> The <TT>%warnfilter</TT> directive has the same semantics as other + declaration modifiers like <TT>%rename</TT>, <TT>%ignore</TT> and <TT> +%feature</TT>, see the <A href="#features">%feature directive</A> + section. For example, if you wanted to suppress a warning for a method + in a class hierarchy, you could do this:</P> +<DIV class="code"> +<PRE> +%warnfilter(501) Object::foo; +class Object { +public: + int foo(int); + int foo(double); // Silently ignored + ... +}; + +class Derived : public Object { +public: + int foo(int); + int foo(double); // Silently ignored + ... +}; +</PRE> +</DIV> +<P> Warnings can be suppressed for an entire class by supplying a class + name. For example:</P> +<DIV class="code"> +<PRE> +%warnfilter(501) Object; + +class Object { +public: + ... // All 501 warnings ignored in class +}; +</PRE> +</DIV> +<P> There is no option to suppress all SWIG warning messages. The + warning messages are there for a reason---to tell you that something + may be<EM> broken</EM> in your interface. Ignore the warning messages + at your own peril.</P> +<H2><A name="Warnings_nn4"></A>14.3 Enabling extra warnings</H2> +<P> Some warning messages are disabled by default and are generated only + to provide additional diagnostics. These warnings can be turned on + using the <TT>-Wextra</TT> option. For example:</P> +<DIV class="shell"> +<PRE> +% swig -Wextra -python example.i +</PRE> +</DIV> +<P> To selectively turn on extra warning messages, you can use the + directives and options in the previous section--simply add a "+" to all + warning numbers. For example:</P> +<DIV class="shell"> +<PRE> +% swig -w+309,+452 example.i +</PRE> +</DIV> +<P> or in your interface file use either</P> +<DIV class="code"> +<PRE> +#pragma SWIG nowarn=+309,+452 +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +%warnfilter(+309,+452) foo; +</PRE> +</DIV> +<P> Note: selective enabling of warnings with <TT>%warnfilter</TT> + overrides any global settings you might have made using <TT>-w</TT> or <TT> +#pragma</TT>.</P> +<P> You can of course also enable all warnings and suppress a select + few, for example:</P> +<DIV class="shell"> +<PRE> +% swig -Wextra -w309,452 example.i +</PRE> +</DIV> +<P> The warnings on the right take precedence over the warnings on the + left, so in the above example <TT>-Wextra</TT> adds numerous warnings + including 452, but then <TT>-w309,452</TT> overrides this and so 452 is + suppressesed.</P> +<P> If you would like all warnings to appear, regardless of the warning + filters used, then use the <TT>-Wall</TT> option. The <TT>-Wall</TT> + option also turns on the extra warnings that <TT>-Wextra</TT> adds, + however, it is subtely different. When <TT>-Wall</TT> is used, it also + disables all other warning filters, that is, any warnings suppressed or + added in <TT>%warnfilter</TT>, <TT>#pragma SWIG nowarn</TT> or the <TT> +-w</TT> option.</P> +<H2><A name="Warnings_nn5"></A>14.4 Issuing a warning message</H2> +<P> Warning messages can be issued from an interface file using a number + of directives. The <TT>%warn</TT> directive is the most simple:</P> +<DIV class="code"> +<PRE> +%warn "900:This is your last warning!" +</PRE> +</DIV> +<P> All warning messages are optionally prefixed by the warning number + to use. If you are generating your own warnings, make sure you don't + use numbers defined in the table at the end of this section.</P> +<P> The <TT>%ignorewarn</TT> directive is the same as <TT>%ignore</TT> + except that it issues a warning message whenever a matching declaration + is found. For example:</P> +<DIV class="code"> +<PRE> +%ignorewarn("362:operator= ignored") operator=; +</PRE> +</DIV> +<P> Warning messages can be associated with typemaps using the <TT> +warning</TT> attribute of a typemap declaration. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in, warning="901:You are really going to regret this") blah * { + ... +} +</PRE> +</DIV> +<P> In this case, the warning message will be printed whenever the + typemap is actually used.</P> +<H2><A name="Warnings_symbolic_symbols"></A>14.5 Symbolic symbols</H2> +<P> The <TT>swigwarn.swg</TT> file that is installed with SWIG contains + symbol constants that could also be used in <TT>%warnfilter</TT> and <TT> +#pragma SWIG nowarn</TT>. For example this file contains the following + line:</P> +<DIV class="code"> +<PRE> +%define SWIGWARN_TYPE_UNDEFINED_CLASS 401 %enddef +</PRE> +</DIV> +<P> so <TT>SWIGWARN_TYPE_UNDEFINED_CLASS</TT> could be used instead of + 401, for example:</P> +<DIV class="code"> +<PRE> +#pragma SWIG nowarn=SWIGWARN_TYPE_UNDEFINED_CLASS +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Foo; +</PRE> +</DIV> +<H2><A name="Warnings_nn6"></A>14.6 Commentary</H2> +<P> The ability to suppress warning messages is really only provided for + advanced users and is not recommended in normal use. You are advised to + modify your interface to fix the problems highlighted by the warnings + wherever possible instead of suppressing warnings.</P> +<P> Certain types of SWIG problems are errors. These usually arise due + to parsing errors (bad syntax) or semantic problems for which there is + no obvious recovery. There is no mechanism for suppressing error + messages.</P> +<H2><A name="Warnings_nn7"></A>14.7 Warnings as errors</H2> +<P> Warnings can be handled as errors by using the <TT>-Werror</TT> + command line option. This will cause SWIG to exit with a non successful + exit code if a warning is encountered.</P> +<H2><A name="Warnings_nn8"></A>14.8 Message output format</H2> +<P> The output format for both warnings and errors can be selected for + integration with your favourite IDE/editor. Editors and IDEs can + usually parse error messages and if in the appropriate format will + easily take you directly to the source of the error. The standard + format is used by default except on Windows where the Microsoft format + is used by default. These can be overridden using command line options, + for example:</P> +<DIV class="shell"> +<PRE> +$ swig -python -Fstandard example.i +example.i:4: Syntax error in input. +$ swig -python -Fmicrosoft example.i +example.i(4): Syntax error in input. +</PRE> +</DIV> +<H2><A name="Warnings_nn9"></A>14.9 Warning number reference</H2> +<H3><A name="Warnings_nn10"></A>14.9.1 Deprecated features (100-199)</H3> +<UL> +<LI>101. Deprecated <TT>%extern</TT> directive.</LI> +<LI>102. Deprecated <TT>%val</TT> directive.</LI> +<LI>103. Deprecated <TT>%out</TT> directive.</LI> +<LI>104. Deprecated <TT>%disabledoc</TT> directive.</LI> +<LI>105. Deprecated <TT>%enabledoc</TT> directive.</LI> +<LI>106. Deprecated <TT>%doconly</TT> directive.</LI> +<LI>107. Deprecated <TT>%style</TT> directive.</LI> +<LI>108. Deprecated <TT>%localstyle</TT> directive.</LI> +<LI>109. Deprecated <TT>%title</TT> directive.</LI> +<LI>110. Deprecated <TT>%section</TT> directive.</LI> +<LI>111. Deprecated <TT>%subsection</TT> directive.</LI> +<LI>112. Deprecated <TT>%subsubsection</TT> directive.</LI> +<LI>113. Deprecated <TT>%addmethods</TT> directive.</LI> +<LI>114. Deprecated <TT>%readonly</TT> directive.</LI> +<LI>115. Deprecated <TT>%readwrite</TT> directive.</LI> +<LI>116. Deprecated <TT>%except</TT> directive.</LI> +<LI>117. Deprecated <TT>%new</TT> directive.</LI> +<LI>118. Deprecated <TT>%typemap(except)</TT>.</LI> +<LI>119. Deprecated <TT>%typemap(ignore)</TT>.</LI> +<LI>120. Deprecated command line option (-runtime, -noruntime).</LI> +<LI>121. Deprecated <TT>%name</TT> directive.</LI> +</UL> +<H3><A name="Warnings_nn11"></A>14.9.2 Preprocessor (200-299)</H3> +<UL> +<LI>201. Unable to find 'filename'.</LI> +<LI>202. Could not evaluate 'expr'.</LI> +</UL> +<H3><A name="Warnings_nn12"></A>14.9.3 C/C++ Parser (300-399)</H3> +<UL> +<LI>301. <TT>class</TT> keyword used, but not in C++ mode.</LI> +<LI>302. Identifier '<EM>name</EM>' redefined (ignored).</LI> +<LI>303. <TT>%extend</TT> defined for an undeclared class '<EM>name</EM> +'.</LI> +<LI>304. Unsupported constant value (ignored).</LI> +<LI>305. Bad constant value (ignored).</LI> +<LI>306. '<EM>identifier</EM>' is private in this context.</LI> +<LI>307. Can't set default argument value (ignored)</LI> +<LI>308. Namespace alias '<EM>name</EM>' not allowed here. Assuming '<EM> +name</EM>'</LI> +<LI>309. [private | protected] inheritance ignored.</LI> +<LI>310. Template '<EM>name</EM>' was already wrapped as '<EM>name</EM>' + (ignored)</LI> +<LI>311. Template partial specialization not supported.</LI> +<LI>312. Nested classes not currently supported (ignored).</LI> +<LI>313. Unrecognized extern type "<EM>name</EM>" (ignored).</LI> +<LI>314. '<EM>identifier</EM>' is a<EM> lang</EM> keyword.</LI> +<LI>315. Nothing known about '<EM>identifier</EM>'.</LI> +<LI>316. Repeated %module directive.</LI> +<LI>317. Specialization of non-template '<EM>name</EM>'.</LI> +<LI>318. Instantiation of template<EM> name</EM> is ambiguous. Using<EM> + templ</EM> at<EM> file</EM>:<EM>line</EM></LI> +<LI>319. No access specifier given for base class<EM> name</EM> + (ignored).</LI> +<LI>320. Explicit template instantiation ignored.</LI> +<LI>321.<EM> identifier</EM> conflicts with a built-in name.</LI> +<LI>322. Redundant redeclaration of '<EM>name</EM>'.</LI> +<LI>350. operator new ignored.</LI> +<LI>351. operator delete ignored.</LI> +<LI>352. operator+ ignored.</LI> +<LI>353. operator- ignored.</LI> +<LI>354. operator* ignored.</LI> +<LI>355. operator/ ignored.</LI> +<LI>356. operator% ignored.</LI> +<LI>357. operator^ ignored.</LI> +<LI>358. operator& ignored.</LI> +<LI>359. operator| ignored.</LI> +<LI>360. operator~ ignored.</LI> +<LI>361. operator! ignored.</LI> +<LI>362. operator= ignored.</LI> +<LI>363. operator< ignored.</LI> +<LI>364. operator> ignored.</LI> +<LI>365. operator+= ignored.</LI> +<LI>366. operator-= ignored.</LI> +<LI>367. operator*= ignored.</LI> +<LI>368. operator/= ignored.</LI> +<LI>369. operator%= ignored.</LI> +<LI>370. operator^= ignored.</LI> +<LI>371. operator&= ignored.</LI> +<LI>372. operator|= ignored.</LI> +<LI>373. operator<< ignored.</LI> +<LI>374. operator>>ignored.</LI> +<LI>375. operator<<= ignored.</LI> +<LI>376. operator>>= ignored.</LI> +<LI>377. operator== ignored.</LI> +<LI>378. operator!= ignored.</LI> +<LI>379. operator<= ignored.</LI> +<LI>380. operator>= ignored.</LI> +<LI>381. operator&& ignored.</LI> +<LI>382. operator|| ignored.</LI> +<LI>383. operator++ ignored.</LI> +<LI>384. operator-- ignored.</LI> +<LI>385. operator, ignored.</LI> +<LI>386. operator-<* ignored.</LI> +<LI>387. operator-< ignored.</LI> +<LI>388. operator() ignored.</LI> +<LI>389. operator[] ignored.</LI> +<LI>390. operator+ ignored (unary).</LI> +<LI>391. operator- ignored (unary).</LI> +<LI>392. operator* ignored (unary).</LI> +<LI>393. operator& ignored (unary).</LI> +<LI>394. operator new[] ignored.</LI> +<LI>395. operator delete[] ignored.</LI> +</UL> +<H3><A name="Warnings_nn13"></A>14.9.4 Types and typemaps (400-499)</H3> +<UL> +<LI>401. Nothing known about class 'name'. Ignored.</LI> +<LI>402. Base class 'name' is incomplete.</LI> +<LI>403. Class 'name' might be abstract.</LI> +<LI>450. Deprecated typemap feature ($source/$target).</LI> +<LI>451. Setting const char * variable may leak memory.</LI> +<LI>452. Reserved</LI> +<LI>453. Can't apply (pattern). No typemaps are defined.</LI> +<LI>460. Unable to use type<EM> type</EM> as a function argument.</LI> +<LI>461. Unable to use return type<EM> type</EM> in function<EM> name</EM> +.</LI> +<LI>462. Unable to set variable of type<EM> type</EM>.</LI> +<LI>463. Unable to read variable of type<EM> type</EM>.</LI> +<LI>464. Unsupported constant value.</LI> +<LI>465. Unable to handle type<EM> type</EM>.</LI> +<LI>466. Unsupported variable type<EM> type</EM>.</LI> +<LI>467. Overloaded<EM> declaration</EM> not supported (no type checking + rule for '<EM>type</EM>')</LI> +<LI>468. No 'throw' typemap defined for exception type<EM> type</EM></LI> +<LI>469. No or improper directorin typemap defined for<EM> type</EM></LI> +<LI>470. Thread/reentrant unsafe wrapping, consider returning by value + instead.</LI> +<LI>471. Unable to use return type<EM> type</EM> in director method</LI> +<LI>474. Method<EM> method</EM> usage of the optimal attribute in the + out typemap at<EM> file</EM>:<EM>line</EM> ignored as the following + cannot be used to generate optimal code:<EM> code</EM></LI> +<LI>475. Multiple calls to<EM> method</EM> might be generated due to + optimal attribute usage in the out typemap at<EM> file</EM>:<EM>line</EM> +.</LI> +</UL> +<H3><A name="Warnings_nn14"></A>14.9.5 Code generation (500-599)</H3> +<UL> +<LI>501. Overloaded declaration ignored.<EM> decl</EM></LI> +<LI>502. Overloaded constructor ignored.<EM> decl</EM></LI> +<LI>503. Can't wrap '<EM>identifier</EM>' unless renamed to a valid + identifier.</LI> +<LI>504. Function<EM> name</EM> must have a return type.</LI> +<LI>505. Variable length arguments discarded.</LI> +<LI>506. Can't wrap varargs with keyword arguments enabled.</LI> +<LI>507. Adding native function<EM> name</EM> not supported (ignored).</LI> +<LI>508. Declaration of '<EM>name</EM>' shadows declaration accessible + via operator->() at<EM> file:line</EM>.</LI> +<LI>509. Overloaded<EM> declaration</EM> is shadowed by<EM> declaration</EM> + at<EM> file</EM>:<EM>line</EM>.</LI> +<LI>510. Friend function '<EM>name</EM>' ignored.</LI> +<LI>511. Can't use keyword arguments with overloaded functions.</LI> +<LI>512. Overloaded<EM> declaration</EM> const ignored. Non-const method + at<EM> file</EM>:<EM>line</EM> used.</LI> +<LI>513. Can't generate wrappers for unnamed struct/class.</LI> +<LI>514.</LI> +<LI>515.</LI> +<LI>516. Overloaded method<EM> declaration</EM> ignored. Method<EM> + declaration</EM> at<EM> file</EM>:<EM>line</EM> used.</LI> +<LI>517.</LI> +<LI>518. Portability warning: File<EM> file1</EM> will be overwritten by<EM> + file2</EM> on case insensitive filesystems such as Windows' FAT32 and + NTFS unless the class/module name is renamed.</LI> +<LI>519. %template() contains no name. Template method ignored:<EM> + declaration</EM></LI> +</UL> +<H3><A name="Warnings_nn15"></A>14.9.6 Language module specific + (800-899)</H3> +<UL> +<LI>801. Wrong name (corrected to '<EM>name</EM>'). (Ruby).</LI> +</UL> +<UL> +<LI>810. No jni typemap defined for<EM> type</EM> (Java).</LI> +<LI>811. No jtype typemap defined for<EM> type</EM> (Java).</LI> +<LI>812. No jstype typemap defined for<EM> type</EM> (Java).</LI> +<LI>813. Warning for<EM> classname</EM>: Base<EM> baseclass</EM> + ignored. Multiple inheritance is not supported in Java. (Java).</LI> +<LI>814.</LI> +<LI>815. No javafinalize typemap defined for<EM> type</EM> (Java).</LI> +<LI>816. No javabody typemap defined for<EM> type</EM> (Java).</LI> +<LI>817. No javaout typemap defined for<EM> type</EM> (Java).</LI> +<LI>818. No javain typemap defined for<EM> type</EM> (Java).</LI> +<LI>819. No javadirectorin typemap defined for<EM> type</EM> (Java).</LI> +<LI>820. No javadirectorout typemap defined for<EM> type</EM> (Java).</LI> +<LI>821.</LI> +<LI>822. Covariant return types not supported in Java. Proxy method will + return<EM> basetype</EM> (Java).</LI> +<LI>823. No javaconstruct typemap defined for<EM> type</EM> (Java).</LI> +<LI>824. Missing JNI descriptor in directorin typemap defined for<EM> + type</EM> (Java).</LI> +</UL> +<UL> +<LI>830. No ctype typemap defined for<EM> type</EM> (C#).</LI> +<LI>831. No cstype typemap defined for<EM> type</EM> (C#).</LI> +<LI>832. No cswtype typemap defined for<EM> type</EM> (C#).</LI> +<LI>833. Warning for<EM> classname</EM>: Base<EM> baseclass</EM> + ignored. Multiple inheritance is not supported in C#. (C#).</LI> +<LI>834.</LI> +<LI>835. No csfinalize typemap defined for<EM> type</EM> (C#).</LI> +<LI>836. No csbody typemap defined for<EM> type</EM> (C#).</LI> +<LI>837. No csout typemap defined for<EM> type</EM> (C#).</LI> +<LI>838. No csin typemap defined for<EM> type</EM> (C#).</LI> +<LI>839.</LI> +<LI>840.</LI> +<LI>841.</LI> +<LI>842. Covariant return types not supported in C#. Proxy method will + return<EM> basetype</EM> (C#).</LI> +<LI>843. No csconstruct typemap defined for<EM> type</EM> (C#).</LI> +<LI>844. C# exception may not be thrown - no $excode or excode attribute + in<EM> typemap</EM> typemap. (C#).</LI> +<LI>845. Unmanaged code contains a call to a + SWIG_CSharpSetPendingException method and C# code does not handle + pending exceptions via the canthrow attribute. (C#).</LI> +</UL> +<UL> +<LI>870. Warning for<EM> classname</EM>: Base<EM> baseclass</EM> + ignored. Multiple inheritance is not supported in PHP.</LI> +<LI>871. Unrecognized pragma<EM> pragma</EM>. (Php).</LI> +</UL> +<H3><A name="Warnings_nn16"></A>14.9.7 User defined (900-999)</H3> +<P> These numbers can be used by your own application.</P> +<H2><A name="Warnings_nn17"></A>14.10 History</H2> +<P> The ability to control warning messages was first added to + SWIG-1.3.12.</P> +<HR NOSHADE> +<H1><A name="Modules"></A>15 Working with Modules</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Modules_introduction">Modules Introduction</A></LI> +<LI><A href="#Modules_nn1">Basics</A></LI> +<LI><A href="#Modules_nn2">The SWIG runtime code</A></LI> +<LI><A href="#external_run_time">External access to the runtime</A></LI> +<LI><A href="#Modules_nn4">A word of caution about static libraries</A></LI> +<LI><A href="#Modules_nn5">References</A></LI> +<LI><A href="#Modules_nn6">Reducing the wrapper file size</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<H2><A name="Modules_introduction"></A>15.1 Modules Introduction</H2> +<P> Each invocation of SWIG requires a module name to be specified. The + module name is used to name the resulting target language extension + module. Exactly what this means and and what the name is used for + depends on the target language, for example the name can define a + target language namespace or merely be a useful name for naming files + or helper classes. Essentially, a module comprises target language + wrappers for a chosen collection of global variables/functions, + structs/classes and other C/C++ types.</P> +<P> The module name can be supplied in one of two ways. The first is to + specify it with the special <TT>%module</TT> directive. This directive + must appear at the beginning of the interface file. The general form of + this directive is:</P> +<DIV class="code"> +<PRE> +<TT>%module(option1="value1",option2="value2",...) modulename</TT> +</PRE> +</DIV> +<P> where the modulename is mandatory and the options add one or more + optional additional features. Typically no options are specified, for + example:</P> +<DIV class="code"> +<PRE> +<TT>%module mymodule</TT> +</PRE> +</DIV> +<P> The second way to specify the module name is with the <TT>-module</TT> + command line option, for example <TT>-module mymodule</TT>. If the + module name is supplied on the command line, it overrides the name + specified by the <TT>%module</TT> directive.</P> +<P> When first working with SWIG, users commonly start by creating a + single module. That is, you might define a single SWIG interface that + wraps some set of C/C++ code. You then compile all of the generated + wrapper code together and use it. For large applications, however, this + approach is problematic---the size of the generated wrapper code can be + rather large. Moreover, it is probably easier to manage the target + language interface when it is broken up into smaller pieces.</P> +<P> This chapter describes the problem of using SWIG in programs where + you want to create a collection of modules. Each module in the + collection is created via separate invocations of SWIG.</P> +<H2><A name="Modules_nn1"></A>15.2 Basics</H2> +<P> The basic usage case with multiple modules is when modules do not + have cross-references (ie. when wrapping multiple independent C APIs). + In that case, swig input files should just work out of the box - you + simply create multiple wrapper .cxx files, link them into your + application, and insert/load each in the scripting language runtime as + you would do for the single module case.</P> +<P> A bit more complex is the case in which modules need to share + information. For example, when one module extends the class of another + by deriving from it:</P> +<DIV class="code"> +<PRE> +// File: base.h +class base { +public: + int foo(); +}; +</PRE> +</DIV> <DIV class="code"> +<PRE> +// File: base_module.i +%module base_module + +%{ +#include "base.h" +%} +%include "base.h" +</PRE> +</DIV> <DIV class="code"> +<PRE> +// File: derived_module.i +%module derived_module + +%import "base_module.i" + +%inline %{ +class derived : public base { +public: + int bar(); +}; +%} +</PRE> +</DIV> +<P>To create the wrapper properly, module <TT>derived_module</TT> needs + to know about the <TT>base</TT> class and that its interface is covered + in another module. The line <TT>%import "base_module.i"</TT> lets SWIG + know exactly that. Oftentimes the <TT>.h</TT> file is passed to <TT> +%import</TT> instead of the <TT>.i</TT>, which unfortunately doesn't + work for all language modules. For example, Python requires the name of + module that the base class exists in so that the proxy classes can + fully inherit the base class's methods. Typically you will get a + warning when the module name is missing, eg:</P> +<DIV class="shell"> +<PRE> +derived_module.i:8: Warning(401): Base class 'base' ignored - unknown module name for base. Either import +the appropriate module interface file or specify the name of the module in the %import directive. +</PRE> +</DIV> +<P> It is sometimes desirable to import the header file rather than the + interface file and overcome the above warning. For example in the case + of the imported interface being quite large, it may be desirable to + simplify matters and just import a small header file of dependent + types. This can be done by specifying the optional <TT>module</TT> + attribute in the <TT>%import</TT> directive. The <TT>derived_module.i</TT> + file shown above could be replaced with the following:<DIV class="code"> +<PRE> +// File: derived_module.i +%module derived_module + +%import(module="base_module") "base.h" + +%inline %{ +class derived : public base { +public: + int bar(); +}; +</PRE> +</DIV></P> +<P> Note that "base_module" is the module name and is the same as that + specified in <TT>%module</TT> in <TT>base_module.i</TT> as well as the <TT> +%import</TT> in <TT>derived_module.i</TT>.</P> +<P> Another issue to beware of is that multiple dependent wrappers + should not be linked/loaded in parallel from multiple threads as SWIG + provides no locking - for more on that issue, read on.</P> +<H2><A name="Modules_nn2"></A>15.3 The SWIG runtime code</H2> +<P> Many of SWIG's target languages generate a set of functions commonly + known as the "SWIG runtime." These functions are primarily related to + the runtime type system which checks pointer types and performs other + tasks such as proper casting of pointer values in C++. As a general + rule, the statically typed target languages, such as Java, use the + language's built in static type checking and have no need for a SWIG + runtime. All the dynamically typed / interpreted languages rely on the + SWIG runtime.</P> +<P> The runtime functions are private to each SWIG-generated module. + That is, the runtime functions are declared with "static" linkage and + are visible only to the wrapper functions defined in that module. The + only problem with this approach is that when more than one SWIG module + is used in the same application, those modules often need to share type + information. This is especially true for C++ programs where SWIG must + collect and share information about inheritance relationships that + cross module boundaries.</P> +<P> To solve the problem of sharing information across modules, a + pointer to the type information is stored in a global variable in the + target language namespace. During module initialization, type + information is loaded into the global data structure of type + information from all modules.</P> +<P> There are a few trade offs with this approach. This type information + is global across all SWIG modules loaded, and can cause type conflicts + between modules that were not designed to work together. To solve this + approach, the SWIG runtime code uses a define SWIG_TYPE_TABLE to + provide a unique type table. This behavior can be enabled when + compiling the generated _wrap.cxx or _wrap.c file by adding + -DSWIG_TYPE_TABLE=myprojectname to the command line argument.</P> +<P> Then, only modules compiled with SWIG_TYPE_TABLE set to + myprojectname will share type information. So if your project has three + modules, all three should be compiled with + -DSWIG_TYPE_TABLE=myprojectname, and then these three modules will + share type information. But any other project's types will not + interfere or clash with the types in your module.</P> +<P> Another issue relating to the global type table is thread safety. If + two modules try and load at the same time, the type information can + become corrupt. SWIG currently does not provide any locking, and if you + use threads, you must make sure that modules are loaded serially. Be + careful if you use threads and the automatic module loading that some + scripting languages provide. One solution is to load all modules before + spawning any threads, or use SWIG_TYPE_TABLE to separate type tables so + they do not clash with each other.</P> +<P> Lastly, SWIG uses a #define SWIG_RUNTIME_VERSION, located in + Lib/swigrun.swg and near the top of every generated module. This number + gets incremented when the data structures change, so that SWIG modules + generated with different versions can peacefully coexist. So the type + structures are separated by the (SWIG_TYPE_TABLE, SWIG_RUNTIME_VERSION) + pair, where by default SWIG_TYPE_TABLE is empty. Only modules compiled + with the same pair will share type information.</P> +<H2><A name="external_run_time"></A>15.4 External access to the runtime</H2> +<P>As described in <A href="#runtime_type_checker">The run-time type + checker</A>, the functions <TT>SWIG_TypeQuery</TT>, <TT> +SWIG_NewPointerObj</TT>, and others sometimes need to be called. Calling + these functions from a typemap is supported, since the typemap code is + embedded into the <TT>_wrap.c</TT> file, which has those declarations + available. If you need to call the SWIG run-time functions from another + C file, there is one header you need to include. To generate the header + that needs to be included, run the following command:<DIV class="shell"> +<PRE> +$ swig -python -external-runtime <filename> +</PRE> +</DIV></P> +<P>The filename argument is optional and if it is not passed, then the + default filename will be something like <TT>swigpyrun.h</TT>, depending + on the language. This header file should be treated like any of the + other _wrap.c output files, and should be regenerated when the _wrap + files are. After including this header, your code will be able to call <TT> +SWIG_TypeQuery</TT>, <TT>SWIG_NewPointerObj</TT>, <TT>SWIG_ConvertPtr</TT> + and others. The exact argument parameters for these functions might + differ between language modules; please check the language module + chapters for more information.</P> +<P>Inside this header the functions are declared static and are included + inline into the file, and thus the file does not need to be linked + against any SWIG libraries or code (you might still need to link + against the language libraries like libpython-2.3). Data is shared + between this file and the _wrap.c files through a global variable in + the scripting language. It is also possible to copy this header file + along with the generated wrapper files into your own package, so that + you can distribute a package that can be compiled without SWIG + installed (this works because the header file is self-contained, and + does not need to link with anything).</P> +<P> This header will also use the -DSWIG_TYPE_TABLE described above, so + when compiling any code which includes the generated header file should + define the SWIG_TYPE_TABLE to be the same as the module whose types you + are trying to access.</P> +<H2><A name="Modules_nn4"></A>15.5 A word of caution about static + libraries</H2> +<P> When working with multiple SWIG modules, you should take care not to + use static libraries. For example, if you have a static library <TT> +libfoo.a</TT> and you link a collection of SWIG modules with that + library, each module will get its own private copy of the library code + inserted into it. This is very often<B> NOT</B> what you want and it + can lead to unexpected or bizarre program behavior. When working with + dynamically loadable modules, you should try to work exclusively with + shared libraries.</P> +<H2><A name="Modules_nn5"></A>15.6 References</H2> +<P> Due to the complexity of working with shared libraries and multiple + modules, it might be a good idea to consult an outside reference. John + Levine's "Linkers and Loaders" is highly recommended.</P> +<H2><A name="Modules_nn6"></A>15.7 Reducing the wrapper file size</H2> +<P> Using multiple modules with the <TT>%import</TT> directive is the + most common approach to modularising large projects. In this way a + number of different wrapper files can be generated, thereby avoiding + the generation of a single large wrapper file. There are a couple of + alternative solutions for reducing the size of a wrapper file through + the use of command line options and features.</P> +<P><B> -fcompact</B> +<BR> This command line option will compact the size of the wrapper file + without changing the code generated into the wrapper file. It simply + removes blank lines and joins lines of code together. This is useful + for compilers that have a maximum file size that can be handled.</P> +<P><B> -fvirtual</B> +<BR> This command line option will remove the generation of superfluous + virtual method wrappers. Consider the following inheritance hierarchy:</P> +<DIV class="code"> +<PRE> +struct Base { + virtual void method(); + ... +}; + +struct Derived : Base { + virtual void method(); + ... +}; +</PRE> +</DIV> +<P> Normally wrappers are generated for both methods, whereas this + command line option will suppress the generation of a wrapper for <TT> +Derived::method</TT>. Normal polymorphic behaviour remains as <TT> +Derived::method</TT> will still be called should you have a <TT>Derived</TT> + instance and call the wrapper for <TT>Base::method</TT>.</P> +<P><B> %feature("compactdefaultargs")</B> +<BR> This feature can reduce the number of wrapper methods when wrapping + methods with default arguments. The section on <A href="#SWIGPlus_default_args"> +default arguments</A> discusses the feature and its limitations.</P> +<HR NOSHADE> +<H1><A name="CCache"></A>16 Using SWIG with ccache - ccache-swig(1) + manpage</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#CCache_nn2">NAME</A></LI> +<LI><A href="#CCache_nn3">SYNOPSIS</A></LI> +<LI><A href="#CCache_nn4">DESCRIPTION</A></LI> +<LI><A href="#CCache_nn5">OPTIONS SUMMARY</A></LI> +<LI><A href="#CCache_nn6">OPTIONS</A></LI> +<LI><A href="#CCache_nn7">INSTALLATION</A></LI> +<LI><A href="#CCache_nn8">EXTRA OPTIONS</A></LI> +<LI><A href="#CCache_nn9">ENVIRONMENT VARIABLES</A></LI> +<LI><A href="#CCache_nn10">CACHE SIZE MANAGEMENT</A></LI> +<LI><A href="#CCache_nn11">CACHE COMPRESSION</A></LI> +<LI><A href="#CCache_nn12">HOW IT WORKS</A></LI> +<LI><A href="#CCache_nn13">USING CCACHE WITH DISTCC</A></LI> +<LI><A href="#CCache_nn14">SHARING A CACHE</A></LI> +<LI><A href="#CCache_nn15">HISTORY</A></LI> +<LI><A href="#CCache_nn16">DIFFERENCES FROM COMPILERCACHE</A></LI> +<LI><A href="#CCache_nn17">CREDITS</A></LI> +<LI><A href="#CCache_nn18">AUTHOR</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P></P> +<H2><A name="CCache_nn2"></A>16.1 NAME</H2> +<P> ccache-swig - a fast compiler cache</P> +<P></P> +<H2><A name="CCache_nn3"></A>16.2 SYNOPSIS</H2> +<P> ccache-swig [OPTION]</P> +<P> ccache-swig <compiler> [COMPILER OPTIONS]</P> +<P> <compiler> [COMPILER OPTIONS]</P> +<P></P> +<H2><A name="CCache_nn4"></A>16.3 DESCRIPTION</H2> +<P> ccache-swig is a compiler cache. It speeds up re-compilation of + C/C++/SWIG code by caching previous compiles and detecting when the + same compile is being done again. ccache-swig is ccache plus support + for SWIG. ccache and ccache-swig are used interchangeably in this + document.</P> +<P></P> +<H2><A name="CCache_nn5"></A>16.4 OPTIONS SUMMARY</H2> +<P> Here is a summary of the options to ccache-swig.</P> +<P></P> +<PRE> + +-s show statistics summary +-z zero statistics +-c run a cache cleanup +-C clear the cache completely +-F <n> set maximum files in cache +-M <n> set maximum size of cache (use G, M or K) +-h this help page +-V print version number + +</PRE> +<P></P> +<H2><A name="CCache_nn6"></A>16.5 OPTIONS</H2> +<P> These options only apply when you invoke ccache as "ccache-swig". + When invoked as a compiler none of these options apply. In that case + your normal compiler options apply and you should refer to your + compilers documentation.</P> +<P></P> +<DL> +<P> +<DT><STRONG><STRONG>-h</STRONG></STRONG></DT> +<DD> Print a options summary page +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>-s</STRONG></STRONG></DT> +<DD> Print the current statistics summary for the cache. The statistics + are stored spread across the subdirectories of the cache. Using + "ccache-swig -s" adds up the statistics across all subdirectories and + prints the totals. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>-z</STRONG></STRONG></DT> +<DD> Zero the cache statistics. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>-V</STRONG></STRONG></DT> +<DD> Print the ccache version number +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>-c</STRONG></STRONG></DT> +<DD> Clean the cache and re-calculate the cache file count and size + totals. Normally the -c option should not be necessary as ccache keeps + the cache below the specified limits at runtime and keeps statistics up + to date on each compile. This option is mostly useful if you manually + modify the cache contents or believe that the cache size statistics may + be inaccurate. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>-C</STRONG></STRONG></DT> +<DD> Clear the entire cache, removing all cached files. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>-F <maxfiles></STRONG></STRONG></DT> +<DD> This sets the maximum number of files allowed in the cache. The + value is stored inside the cache directory and applies to all future + compiles. Due to the way the value is stored the actual value used is + always rounded down to the nearest multiple of 16. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>-M <maxsize></STRONG></STRONG></DT> +<DD> This sets the maximum cache size. You can specify a value in + gigabytes, megabytes or kilobytes by appending a G, M or K to the + value. The default is gigabytes. The actual value stored is rounded + down to the nearest multiple of 16 kilobytes. +<P></P> +</DD> +</P> +</DL> +<P></P> +<H2><A name="CCache_nn7"></A>16.6 INSTALLATION</H2> +<P> There are two ways to use ccache. You can either prefix your compile + commands with "ccache-swig" or you can create a symbolic link between + ccache-swig and the names of your compilers. The first method is most + convenient if you just want to try out ccache or wish to use it for + some specific projects. The second method is most useful for when you + wish to use ccache for all your compiles.</P> +<P> To install for usage by the first method just copy ccache-swig to + somewhere in your path.</P> +<P> To install for the second method do something like this:</P> +<PRE> + + cp ccache-swig /usr/local/bin/ + ln -s /usr/local/bin/ccache-swig /usr/local/bin/gcc + ln -s /usr/local/bin/ccache-swig /usr/local/bin/g++ + ln -s /usr/local/bin/ccache-swig /usr/local/bin/cc + ln -s /usr/local/bin/ccache-swig /usr/local/bin/swig + +</PRE> + This will work as long as /usr/local/bin comes before the path to gcc + (which is usually in /usr/bin). After installing you may wish to run + "which gcc" to make sure that the correct link is being used. +<P> Note! Do not use a hard link, use a symbolic link. A hardlink will + cause "interesting" problems.</P> +<P></P> +<H2><A name="CCache_nn8"></A>16.7 EXTRA OPTIONS</H2> +<P> When run as a compiler front end ccache usually just takes the same + command line options as the compiler you are using. The only exception + to this is the option '--ccache-skip'. That option can be used to tell + ccache that the next option is definitely not a input filename, and + should be passed along to the compiler as-is.</P> +<P> The reason this can be important is that ccache does need to parse + the command line and determine what is an input filename and what is a + compiler option, as it needs the input filename to determine the name + of the resulting object file (among other things). The heuristic ccache + uses in this parse is that any string on the command line that exists + as a file is treated as an input file name (usually a C file). By using + --ccache-skip you can force an option to not be treated as an input + file name and instead be passed along to the compiler as a command line + option.</P> +<P></P> +<H2><A name="CCache_nn9"></A>16.8 ENVIRONMENT VARIABLES</H2> +<P> ccache uses a number of environment variables to control operation. + In most cases you won't need any of these as the defaults will be fine.</P> +<P></P> +<DL> +<P></P> +<P> +<DT><STRONG><STRONG>CCACHE_DIR</STRONG></STRONG></DT> +<DD> the CCACHE_DIR environment variable specifies where ccache will + keep its cached compiler output. The default is "$HOME/.ccache". +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_TEMPDIR</STRONG></STRONG></DT> +<DD> the CCACHE_TEMPDIR environment variable specifies where ccache will + put temporary files. The default is the same as CCACHE_DIR. Note that + the CCACHE_TEMPDIR path must be on the same filesystem as the + CCACHE_DIR path, so that renames of files between the two directories + can work. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_LOGFILE</STRONG></STRONG></DT> +<DD> If you set the CCACHE_LOGFILE environment variable then ccache will + write some log information on cache hits and misses in that file. This + is useful for tracking down problems. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_VERBOSE</STRONG></STRONG></DT> +<DD> If you set the CCACHE_VERBOSE environment variable then ccache will + display on stdout all the compiler invocations that it makes. This can + useful for debugging unexpected problems. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_PATH</STRONG></STRONG></DT> +<DD> You can optionally set CCACHE_PATH to a colon separated path where + ccache will look for the real compilers. If you don't do this then + ccache will look for the first executable matching the compiler name in + the normal PATH that isn't a symbolic link to ccache itself. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_CC</STRONG></STRONG></DT> +<DD> You can optionally set CCACHE_CC to force the name of the compiler + to use. If you don't do this then ccache works it out from the command + line. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_PREFIX</STRONG></STRONG></DT> +<DD> This option adds a prefix to the command line that ccache runs when + invoking the compiler. Also see the section below on using ccache with + distcc. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_DISABLE</STRONG></STRONG></DT> +<DD> If you set the environment variable CCACHE_DISABLE then ccache will + just call the real compiler, bypassing the cache completely. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_READONLY</STRONG></STRONG></DT> +<DD> the CCACHE_READONLY environment variable tells ccache to attempt to + use existing cached object files, but not to try to add anything new to + the cache. If you are using this because your CCACHE_DIR is read-only, + then you may find that you also need to set CCACHE_TEMPDIR as otherwise + ccache will fail to create the temporary files. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_CPP2</STRONG></STRONG></DT> +<DD> If you set the environment variable CCACHE_CPP2 then ccache will + not use the optimisation of avoiding the 2nd call to the pre-processor + by compiling the pre-processed output that was used for finding the + hash in the case of a cache miss. This is primarily a debugging option, + although it is possible that some unusual compilers will have problems + with the intermediate filename extensions used in this optimisation, in + which case this option could allow ccache to be used. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_NOCOMPRESS</STRONG></STRONG></DT> +<DD> If you set the environment variable CCACHE_NOCOMPRESS then there is + no compression used on files that go into the cache. However, this + setting has no effect on how files are retrieved from the cache, + compressed results will still be usable. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_NOSTATS</STRONG></STRONG></DT> +<DD> If you set the environment variable CCACHE_NOSTATS then ccache will + not update the statistics files on each compile. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_NLEVELS</STRONG></STRONG></DT> +<DD> The environment variable CCACHE_NLEVELS allows you to choose the + number of levels of hash in the cache directory. The default is 2. The + minimum is 1 and the maximum is 8. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_HARDLINK</STRONG></STRONG></DT> +<DD> If you set the environment variable CCACHE_HARDLINK then ccache + will attempt to use hard links from the cache directory when creating + the compiler output rather than using a file copy. Using hard links is + faster, but can confuse programs like 'make' that rely on modification + times. Hard links are never made for compressed cache files. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_RECACHE</STRONG></STRONG></DT> +<DD> This forces ccache to not use any cached results, even if it finds + them. New results are still cached, but existing cache entries are + ignored. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_UMASK</STRONG></STRONG></DT> +<DD> This sets the umask for ccache and all child processes (such as the + compiler). This is mostly useful when you wish to share your cache with + other users. Note that this also affects the file permissions set on + the object files created from your compilations. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_HASHDIR</STRONG></STRONG></DT> +<DD> This tells ccache to hash the current working directory when + calculating the hash that is used to distinguish two compiles. This + prevents a problem with the storage of the current working directory in + the debug info of a object file, which can lead ccache to give a cached + object file that has the working directory in the debug info set + incorrectly. This option is off by default as the incorrect setting of + this debug info rarely causes problems. If you strike problems with gdb + not using the correct directory then enable this option. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_UNIFY</STRONG></STRONG></DT> +<DD> If you set the environment variable CCACHE_UNIFY then ccache will + use the C/C++ unifier when hashing the pre-processor output if -g is + not used in the compile. The unifier is slower than a normal hash, so + setting this environment variable loses a little bit of speed, but it + means that ccache can take advantage of not recompiling when the + changes to the source code consist of reformatting only. Note that + using CCACHE_UNIFY changes the hash, so cached compiles with + CCACHE_UNIFY set cannot be used when CCACHE_UNIFY is not set and vice + versa. The reason the unifier is off by default is that it can give + incorrect line number information in compiler warning messages. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_EXTENSION</STRONG></STRONG></DT> +<DD> Normally ccache tries to automatically determine the extension to + use for intermediate C pre-processor files based on the type of file + being compiled. Unfortunately this sometimes doesn't work, for example + when using the aCC compiler on HP-UX. On systems like this you can use + the CCACHE_EXTENSION option to override the default. On HP-UX set this + environment variable to "i" if you use the aCC compiler. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_STRIPC</STRONG></STRONG></DT> +<DD> If you set the environment variable CCACHE_STRIPC then ccache will + strip the -c option when invoking the preprocessor. This option is + primarily for the Sun Workshop C++ compiler as without this option an + unwarranted warning is displayed: CC: Warning: "-E" redefines product + from "object" to "source (stdout)" when -E and -c is used together. +<P></P> +<P></P> +</DD> +<DT><STRONG><STRONG>CCACHE_SWIG</STRONG></STRONG></DT> +<DD> When using SWIG as the compiler and it does not have 'swig' in the + executable name, then the CCACHE_SWIG environment variable needs to be + set in order for ccache to work correctly with SWIG. The use of + CCACHE_CPP2 is also recommended for SWIG due to some preprocessor + quirks, however, use of CCACHE_CPP2 can often be skipped -- check your + generated code with and without this option set. Known problems are + using preprocessor directives within %inline blocks and the use of + '#pragma SWIG'. +<P></P> +</DD> +</P> +</DL> +<P></P> +<H2><A name="CCache_nn10"></A>16.9 CACHE SIZE MANAGEMENT</H2> +<P> By default ccache has a one gigabyte limit on the cache size and no + maximum number of files. You can set a different limit using the + "ccache -M" and "ccache -F" options, which set the size and number of + files limits.</P> +<P> When these limits are reached ccache will reduce the cache to 20% + below the numbers you specified in order to avoid doing the cache clean + operation too often.</P> +<P></P> +<H2><A name="CCache_nn11"></A>16.10 CACHE COMPRESSION</H2> +<P> By default on most platforms ccache will compress all files it puts + into the cache using the zlib compression. While this involves a + negligible performance slowdown, it significantly increases the number + of files that fit in the cache. You can turn off compression setting + the CCACHE_NOCOMPRESS environment variable.</P> +<P></P> +<H2><A name="CCache_nn12"></A>16.11 HOW IT WORKS</H2> +<P> The basic idea is to detect when you are compiling exactly the same + code a 2nd time and use the previously compiled output. You detect that + it is the same code by forming a hash of:</P> +<P></P> +<UL> +<LI> the pre-processor output from running the compiler with -E</LI> +<LI> the command line options</LI> +<LI> the real compilers size and modification time</LI> +<LI> any stderr output generated by the compiler</LI> +</UL> +<P> These are hashed using md4 (a strong hash) and a cache file is + formed based on that hash result. When the same compilation is done a + second time ccache is able to supply the correct compiler output + (including all warnings etc) from the cache.</P> +<P> ccache has been carefully written to always produce exactly the same + compiler output that you would get without the cache. If you ever + discover a case where ccache changes the output of your compiler then + please let me know.</P> +<P></P> +<H2><A name="CCache_nn13"></A>16.12 USING CCACHE WITH DISTCC</H2> +<P> distcc is a very useful program for distributing compilation across + a range of compiler servers. It is often useful to combine distcc with + ccache, so that compiles that are done are sped up by distcc, but that + ccache avoids the compile completely where possible.</P> +<P> To use distcc with ccache I recommend using the CCACHE_PREFIX + option. You just need to set the environment variable CCACHE_PREFIX to + 'distcc' and ccache will prefix the command line used with the compiler + with the command 'distcc'.</P> +<P></P> +<H2><A name="CCache_nn14"></A>16.13 SHARING A CACHE</H2> +<P> A group of developers can increase the cache hit rate by sharing a + cache directory. The hard links however cause unwanted side effects, as + all links to a cached file share the file's modification timestamp. + This results in false dependencies to be triggered by timestamp-based + build systems whenever another user links to an existing file. + Typically, users will see that their libraries and binaries are + relinked without reason. To share a cache without side effects, the + following conditions need to be met:</P> +<P></P> +<UL> +<LI> Use the same<STRONG> CCACHE_DIR</STRONG> environment variable + setting</LI> +<LI> Unset the<STRONG> CCACHE_HARDLINK</STRONG> environment variable</LI> +<LI> Make sure everyone sets the CCACHE_UMASK environment variable to + 002, this ensures that cached files are accessible to everyone in the + group.</LI> +<LI> Make sure that all users have write permission in the entire cache + directory (and that you trust all users of the shared cache).</LI> +<LI> Make sure that the setgid bit is set on all directories in the + cache. This tells the filesystem to inherit group ownership for new + directories. The command "chmod g+s `find $CCACHE_DIR -type d`" might + be useful for this.</LI> +<LI> Set<STRONG> CCACHE_NOCOMPRESS</STRONG> for all users, if there are + users with versions of ccache that do not support compression.</LI> +</UL> +<P></P> +<H2><A name="CCache_nn15"></A>16.14 HISTORY</H2> +<P> ccache was inspired by the compilercache shell script script written + by Erik Thiele and I would like to thank him for an excellent piece of + work. See <A href="http://www.erikyyy.de/compilercache/"> +http://www.erikyyy.de/compilercache/</A> for the Erik's scripts. + ccache-swig is a port of the original ccache with support added for use + with SWIG.</P> +<P> I wrote ccache because I wanted to get a bit more speed out of a + compiler cache and I wanted to remove some of the limitations of the + shell-script version.</P> +<P></P> +<H2><A name="CCache_nn16"></A>16.15 DIFFERENCES FROM COMPILERCACHE</H2> +<P> The biggest differences between Erik's compilercache script and + ccache are:</P> +<UL> +<LI> ccache is written in C, which makes it a bit faster (calling out to + external programs is mostly what slowed down the scripts).</LI> +<LI> ccache can automatically find the real compiler</LI> +<LI> ccache keeps statistics on hits/misses</LI> +<LI> ccache can do automatic cache management</LI> +<LI> ccache can cache compiler output that includes warnings. In many + cases this gives ccache a much higher cache hit rate.</LI> +<LI> ccache can handle a much wider ranger of compiler options</LI> +<LI> ccache avoids a double call to cpp on a cache miss</LI> +</UL> +<P></P> +<H2><A name="CCache_nn17"></A>16.16 CREDITS</H2> +<P> Thanks to the following people for their contributions to ccache</P> +<UL> +<LI> Erik Thiele for the original compilercache script</LI> +<LI> Luciano Rocha for the idea of compiling the pre-processor output to + avoid a 2nd cpp pass</LI> +<LI> Paul Russell for many suggestions and the debian packaging</LI> +</UL> +<P></P> +<H2><A name="CCache_nn18"></A>16.17 AUTHOR</H2> +<P> ccache was written by Andrew Tridgell <A href="http://samba.org/~tridge/"> +http://samba.org/~tridge/</A>. ccache was adapted to create ccache-swig + for use with SWIG by William Fulton.</P> +<P> If you wish to report a problem or make a suggestion then please + email the SWIG developers on the swig-devel mailing list, see <A href="http://www.swig.org/mail.html"> +http://www.swig.org/mail.html</A></P> +<P> ccache is released under the GNU General Public License version 2 or + later. Please see the file COPYING for license details.</P> +<P></P> +<HR NOSHADE> + +<!-- Hand-written HTML --> +<H1><A name="Allegrocl_nn1"></A>17 SWIG and Allegro Common Lisp</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Allegrocl_nn2">Basics</A> +<UL> +<LI><A href="#Allegrocl_nn3">Running Swig</A></LI> +<LI><A href="#Allegrocl_nn4">Command Line Options</A></LI> +<LI><A href="#Allegrocl_nn5">Inserting user code into generated files</A> +</LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn6">Wrapping Overview</A> +<UL> +<LI><A href="#Allegrocl_nn7">Function Wrapping</A></LI> +<LI><A href="#Allegrocl_nn8">Foreign Wrappers</A></LI> +<LI><A href="#Allegrocl_nn9">FFI Wrappers</A></LI> +<LI><A href="#Allegrocl_nn10">Non-overloaded Defuns</A></LI> +<LI><A href="#Allegrocl_nn11">Overloaded Defuns</A></LI> +<LI><A href="#Allegrocl_nn12">What about constant and variable access?</A> +</LI> +<LI><A href="#Allegrocl_nn13">Object Wrapping</A></LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn14">Wrapping Details</A> +<UL> +<LI><A href="#Allegrocl_nn15">Namespaces</A></LI> +<LI><A href="#Allegrocl_nn16">Constants</A></LI> +<LI><A href="#Allegrocl_nn17">Variables</A></LI> +<LI><A href="#Allegrocl_nn18">Enumerations</A></LI> +<LI><A href="#Allegrocl_nn19">Arrays</A></LI> +<LI><A href="#Allegrocl_nn20">Classes and Structs and Unions (oh my!)</A> +<UL> +<LI><A href="#Allegrocl_nn21">CLOS wrapping of</A></LI> +<LI><A href="#Allegrocl_nn22">CLOS Inheritance</A></LI> +<LI><A href="#Allegrocl_nn23">Member fields and functions</A></LI> +<LI><A href="#Allegrocl_nn24">Why not directly access C++ classes using + foreign types?</A></LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn25">Templates</A> +<UL> +<LI><A href="#Allegrocl_nn26">Generating wrapper code for templates</A></LI> +<LI><A href="#Allegrocl_nn27">Implicit Template instantiation</A></LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn28">Typedef, Templates, and Synonym Types</A> +<UL> +<LI><A href="#Allegrocl_nn29">Choosing a primary type</A></LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn30">Function overloading/Parameter defaulting</A> +</LI> +<LI><A href="#Allegrocl_nn31">Operator wrapping and Operator overloading</A> +</LI> +<LI><A href="#Allegrocl_nn32">Varargs</A></LI> +<LI><A href="#Allegrocl_nn33">C++ Exceptions</A></LI> +<LI><A href="#Allegrocl_nn34">Pass by value, pass by reference</A></LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn35">Typemaps</A> +<UL> +<LI><A href="#Allegrocl_nn36">Code Generation in the C++ Wrapper</A> +<UL> +<LI><A href="#Allegrocl_nn37">IN Typemap</A></LI> +<LI><A href="#Allegrocl_nn38">OUT Typemap</A></LI> +<LI><A href="#Allegrocl_nn39">CTYPE Typemap</A></LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn40">Code generation in Lisp wrappers</A> +<UL> +<LI><A href="#Allegrocl_nn41">LIN Typemap</A></LI> +<LI><A href="#Allegrocl_nn42">LOUT Typemap</A></LI> +<LI><A href="#Allegrocl_nn43">FFITYPE Typemap</A></LI> +<LI><A href="#Allegrocl_nn44">LISPTYPE Typemap</A></LI> +<LI><A href="#Allegrocl_nn45">LISPCLASS Typemap</A></LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn46">Modifying SWIG behavior using typemaps</A></LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn47">Identifier Converter functions</A> +<UL> +<LI><A href="#Allegrocl_nn48">Creating symbols in the lisp environment</A> +</LI> +<LI><A href="#Allegrocl_nn49">Existing identifier-converter functions</A> +<UL> +<LI><A href="#Allegrocl_nn50">identifier-convert-null</A></LI> +<LI><A href="#Allegrocl_nn51">identifier-convert-lispify</A></LI> +<LI><A href="#Allegrocl_nn52">Default identifier to symbol conversions</A> +</LI> +</UL> +</LI> +<LI><A href="#Allegrocl_nn53">Defining your own identifier-converter</A></LI> +<LI><A href="#Allegrocl_nn54">Instructing SWIG to use a particular + identifier-converter</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes SWIG's support of Allegro Common Lisp. + Allegro CL is a full-featured implementation of the Common Lisp + language standard that includes many vendor-specific enhancements and + add-on modules for increased usability.</P> +<P> One such module included in Allegro CL is the Foreign Functions + Interface (FFI). This module, tailored primarily toward interfacing + with C/C++ and, historically, Fortran, provides a means by which + compiled foreign code can be loaded into a running lisp environment and + executed. The interface supports the calling of foreign functions and + methods, allows for executing lisp routines from foreign code + (callbacks), and the passing of data between foreign and lisp code.</P> +<P> The goal of this module is to make it possible to quickly generate + the necessary foreign function definitions so one can make use of C/C++ + foreign libraries directly from lisp without the tedium of having to + code them by hand. When necessary, it will also generate further C/C++ + code that will need to be linked with the intended library for proper + interfacing from lisp. It has been designed with an eye toward + flexibility. Some foreign function calls may release the heap, while + other should not. Some foreign functions should automatically convert + lisp strings into native strings, while others should not. These + adjustments and many more are possible with the current module.</P> +<P> It is significant to note that, while this is a vendor-specific + module, we would like to acknowledge the current and ongoing work by + developers in the open source lisp community that are working on + similar interfaces to implementation-independent foreign function + interfaces (UFFI or CFFI, for example). Such work can only benefit the + lisp community, and we would not be unhappy to see some enterprising + folk use this work to add to it.</P> +<H2><A name="Allegrocl_nn2"></A>17.1 Basics</H2> +<H3><A name="Allegrocl_nn3"></A>17.1.1 Running Swig</H3> +<P> If you're reading this, you must have some library you need to + generate an interface for. In order for SWIG to do this work, however, + it needs a bit of information about how it should go about creating + your interface, and what you are interfacing to.</P> +<P> SWIG expects a description of what in the foreign interface you wish + to connect to. It must consisting of C/C++ declarations and special + SWIG directives. SWIG can be furnished with a header file, but an + interface can also be generated without library headers by supplying a + simple text file--called the interface file, which is typically named + with a <TT>.i</TT> extension--containing any foreign declarations of + identifiers you wish to use. The most common approach is to use a an + interface file with directives to parse the needed headers. A straight + parse of library headers will result in usable code, but SWIG + directives provides much freedom in how a user might tailor the + generated code to their needs or style of coding.</P> +<P> Note that SWIG does not require any function definitions; the + declarations of those functions is all that is necessary. Be careful + when tuning the interface as it is quite possible to generate code that + will not load or compile.</P> +<P> An example interface file is shown below. It makes use of two SWIG + directives, one of which requests that the declarations in a header + file be used to generate part of the interface, and also includes an + additional declaration to be added.</P> +<DIV class="code">example.i +<PRE> +%module example + +%include "header.h" + +int fact(int n); +</PRE> +</DIV> +<P>The contents of header.h are very simple:</P> +<DIV class="code">header.h +<PRE> +int fact(char *statement); // pass it a fact, and it will rate it. +</PRE> +</DIV> +<P>The contents of example.cl will look like this:</P> +<DIV class="targetlang">example.cl +<PRE> +(defpackage :example + (:use :common-lisp :swig :ff :excl)) + + ... helper routines for defining the interface ... + +(swig-in-package ()) + +(swig-defun ("fact") + ((PARM0_statement cl:string (* :char) )) + (:returning (:int ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_statement)) + (swig-ff-call SWIG_arg0))) + +(swig-defun ("fact") + ((PARM0_n cl:integer :int )) + (:returning (:int ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_n)) + (swig-ff-call SWIG_arg0))) + +(swig-dispatcher ("fact" :type :function :arities (1))) +</PRE> +</DIV> +<P> The generated file contains calls to internal swig helper functions. + In this case there are two calls to swig-defun. These calls will expand + into code that will make the appropriate definitions using the Allegro + FFI. Note also, that this code is<B> erroneous</B>. Function + overloading is not supported in C, and this code will not compile even + though SWIG did not complain.</P> +<P> In order to generate a C interface to Allegro CL using this code run + swig using the <TT>-allegrocl</TT> option, as below:</P> +<DIV class="shell"> +<PRE> +% swig -allegrocl example.i +</PRE> +</DIV> +<P> When building an interface to C++ code, include the <TT>-c++</TT> + option:</P> +<DIV class="shell"> +<PRE> +% swig -allegrocl -c++ example.i +</PRE> +</DIV> +<P> As a result of running one of the above commands, a file named <TT> +example.cl</TT> will be generated containing the lisp side of the + interface. As well, a file <TT>example_wrap.cxx</TT> is also generated, + containing C/C++ wrapper code to facilitate access to C++ methods, + enumeration values, and constant values. Wrapper functions are + necessary in C++ due to the lack of a standard for mangling the names + of symbols across all C++ compilers. These wrapper functions are + exported from the shared library as appropriate, using the C name + mangling convention. The lisp code that is generated will interface to + your foreign library through these wrappers.</P> +<P> It is possible to disable the creation of the .cxx file when + generating a C interface by using the -nocwrap command-line argument. + For interfaces that don't contain complex enum or constant expressions, + contain nested struct/union declarations, or doesn't need to use many + of the SWIG customization featuers, this will result in a more + streamlined, direct interface to the intended module.</P> +<P> The generated wrapper file is below. It contains very simple + wrappers by default, that simply pass the arguments to the actual + function.</P> +<DIV class="code">example_wrap.i +<PRE> + ... lots of SWIG internals ... + +EXPORT int ACL___fact__SWIG_0 (char *larg1) { + int lresult = (int)0 ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = larg1; + try { + result = (int)fact(arg1); + + lresult = result; + return lresult; + } catch (...) { + return (int)0; + } +} + + +EXPORT int ACL___fact__SWIG_1 (int larg1) { + int lresult = (int)0 ; + int arg1 ; + int result; + + arg1 = larg1; + try { + result = (int)fact(arg1); + + lresult = result; + return lresult; + } catch (...) { + return (int)0; + } +} +</PRE> +</DIV> +<P> And again, the generated lisp code. Note that it differs from what + is generated when parsing C code:</P> +<DIV class="targetlang"> +<PRE> + ... + +(swig-in-package ()) + +(swig-defmethod ("fact" "ACL___fact__SWIG_0" :type :function :arity 1) + ((PARM0_statement cl:string (* :char) )) + (:returning (:int ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_statement)) + (swig-ff-call SWIG_arg0))) + +(swig-defmethod ("fact" "ACL___fact__SWIG_1" :type :function :arity 1) + ((PARM0_n cl:integer :int )) + (:returning (:int ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_n)) + (swig-ff-call SWIG_arg0))) + +(swig-dispatcher ("fact" :type :function :arities (1))) +</PRE> +</DIV> +<P>In this case, the interface generates two swig-defmethod forms and a + swig-dispatcher form. This provides a single functional interface for + all overloaded routines. A more detailed description of this features + is to be found in the section titled<B> Function overloading/Parameter + defaulting</B>.</P> +<P> In order to load a C++ interface, you will need to build a shared + library from example_wrap.cxx. Be sure to link in the actual library + you created the interface for, as well as any other dependent shared + libraries. For example, if you intend to be able to call back into + lisp, you will also need to link in the Allegro shared library. The + library you create from the C++ wrapper will be what you then load into + Allegro CL.</P> +<H3><A name="Allegrocl_nn4"></A>17.1.2 Command Line Options</H3> +<P> There are three Allegro CL specific command-line option:</P> +<DIV class="shell"> +<PRE> +swig -allegrocl [ options ] filename + + -identifier-converter [name] - Binds the variable swig:*swig-identifier-convert* + in the generated .cl file to <TT>name</TT>. + This function is used to generate symbols + for the lisp side of the interface. + + -cwrap - [default] Generate a .cxx file containing C wrapper function when + wrapping C code. The interface generated is similar to what is + done for C++ code. + -nocwrap - Explicitly turn off generation of .cxx wrappers for C code. Reasonable + for modules with simple interfaces. Can not handle all legal enum + and constant constructs, or take advantage of SWIG customization features. + + -isolate - With this command-line argument, all lisp helper functions are defined + in a unique package named <TT>swig.<module-name></TT> rather than + <TT>swig</TT>. This prevents conflicts when the module is + intended to be used with other swig generated interfaces that may, + for instance, make use of different identifier converters. +</PRE> +</DIV> +<P> See <A href="#Allegrocl_nn47">Section 17.5 Identifier converter + functions</A> for more details.</P> +<H3><A name="Allegrocl_nn5"></A>17.1.3 Inserting user code into + generated files</H3> +<P> It is often necessary to include user-defined code into the + automatically generated interface files. For example, when building a + C++ interface, example_wrap.cxx will likely not compile unless you add + a <TT>#include "header.h"</TT> directive. This can be done using the + SWIG <TT>%insert(section) %{ ...code... %}</TT> directive:</P> +<DIV class="code"> +<PRE> +%module example + +%{ +#include "header.h" +%} + +%include "header.h" + +int fact(int n); +</PRE> +</DIV> +<P> Additional sections have been added for inserting into the generated + lisp interface file</P> +<UL> +<LI><TT>lisphead</TT> - inserts before type declarations</LI> +<LI><TT>lisp</TT> - inserts after type declarations according to where + it appears in the .i file</LI> +</UL> +<P> Note that the block <TT>%{ ... %}</TT> is effectively a shortcut for + <TT>%insert("header") %{ ... %}</TT>.</P> +<H2><A name="Allegrocl_nn6"></A>17.2 Wrapping Overview</H2> +<P> New users to SWIG are encouraged to read <A href="#SWIG">SWIG Basics</A> +, and <A href="#SWIGPlus">SWIG and C++</A>, for those interested in + generating an interface to C++.</P> +<H3><A name="Allegrocl_nn7"></A>17.2.1 Function Wrapping</H3> +<P> Writing lisp code that directly invokes functions at the foreign + function interface level can be cumbersome. Data must often be + translated between lisp and foreign types, data extracted from objects, + foreign objects allocated and freed upon completion of the foreign + call. Dealing with pointers can be unwieldy when it comes to keeping + them distinct from other valid integer values.</P> +<P> We make an attempt to ease some of these burdens by making the + interface to foreign code much more lisp-like, rather than C like. How + this is done is described in later chapters. The layers themselves, + appear as follows:</P> +<DIV class="diagram"> +<PRE> + ______________ + | | (foreign side) + | Foreign Code | What we're generating an interface to. + |______________| + | + | + _______v______ + | | (foreign side) + | Wrapper code | extern "C" wrappers calling C++ + |______________| functions and methods. + | + . . . - - + - - . . . + _______v______ + | | (lisp side) + | FFI Layer | Low level lisp interface. ff:def-foreign-call, + |______________| ff:def-foreign-variable + | + +---------------------------- + _______v______ _______v______ + | | | | (lisp side) + | Defuns | | Defmethods | wrapper for overloaded + |______________| |______________| functions or those with + (lisp side) | defaulted arguments + Wrapper for non-overloaded | + functions and methods _______v______ + | | (lisp side) + | Defuns | dispatch function + |______________| to overloads based + on arity + </PRE> +</DIV> +<H3><A name="Allegrocl_nn8"></A>17.2.2 Foreign Wrappers</H3> +<P> These wrappers are as generated by SWIG default. The types of + function parameters can be transformed in place using the CTYPE + typemap. This is use for converting pass-by-value parameters to + pass-by-reference where necessary. All wrapper parameters are then + bound to local variables for possible transformation of values (see LIN + typemap). Return values can be transformed via the OUT typemap.</P> +<H3><A name="Allegrocl_nn9"></A>17.2.3 FFI Wrappers</H3> +<P> These are the generated ff:def-foreign-call forms. No typemaps are + applicable to this layer, but the <TT>%ffargs</TT> directive is + available for use in .i files, to specify which keyword arguments + should be specified for a given function.</P> +<DIV class="code">ffargs.i: +<PRE> +%module ffargs + +%ffargs(strings_convert="nil",call_direct="t") foo; +%ffargs(strings_convert="nil",release_heap=":never",optimize_for_space="t") bar; + +int foo(float f1, float f2); +int foo(float f1, char c2); + +void bar(void *lisp_fn); + +char *xxx(); + </PRE> +</DIV> +<P>Generates:</P> +<DIV class="targetlang">ffargs.cl: +<PRE> +(swig-in-package ()) + +(swig-defmethod ("foo" "ACL___foo__SWIG_0" :type :function :arity 2) + ((PARM0_f1 cl:single-float :float ) + (PARM1_f2 cl:single-float :float )) + (:returning (:int ) + :call-direct t + :strings-convert nil) + (let ((SWIG_arg0 PARM0_f1)) + (let ((SWIG_arg1 PARM1_f2)) + (swig-ff-call SWIG_arg0 SWIG_arg1)))) + +(swig-defmethod ("foo" "ACL___foo__SWIG_1" :type :function :arity 2) + ((PARM0_f1 cl:single-float :float ) + (PARM1_c2 cl:character :char character)) + (:returning (:int ) + :call-direct t + :strings-convert nil) + (let ((SWIG_arg0 PARM0_f1)) + (let ((SWIG_arg1 PARM1_c2)) + (swig-ff-call SWIG_arg0 SWIG_arg1)))) + +(swig-dispatcher ("foo" :type :function :arities (2))) +(swig-defun ("bar" "ACL___bar__SWIG_0" :type :function) + ((PARM0_lisp_fn (* :void) )) + (:returning (:void ) + :release-heap :never + :optimize-for-space t + :strings-convert nil) + (let ((SWIG_arg0 PARM0_lisp_fn)) + (swig-ff-call SWIG_arg0))) + + +(swig-defun ("xxx" "ACL___xxx__SWIG_0" :type :function) + (:void) + (:returning ((* :char) ) + :strings-convert t) + (swig-ff-call)) + </PRE> +</DIV><DIV class="code"> +<PRE>%ffargs(strings_convert="t");</PRE> +</DIV> +<P> Is the only default value specified in <TT>allegrocl.swg</TT> to + force the muffling of warnings about automatic string conversion when + defining ff:def-foreign-call's.</P> +<H3><A name="Allegrocl_nn10"></A>17.2.4 Non-overloaded Defuns</H3> +<P> These are simple defuns. There is no typechecking of arguments. + Parameters are bound to local variables for possible transformation of + values, such as pulling values out of instance slots or allocating + temporary stack allocated structures, via the <TT>lin</TT> typemap. + These arguments are then passed to the foreign-call (where typechecking + may occur). The return value from this function can be manipulated via + the <TT>lout</TT> typemap.</P> +<H3><A name="Allegrocl_nn11"></A>17.2.5 Overloaded Defuns</H3> +<P> In the case of overloaded functions, mulitple layers are generated. + First, all the overloads for a given name are separated out into groups + based on arity, and are wrapped in defmethods. Each method calls a + distinct wrapper function, but are themselves distinguished by the + types of their arguments (see <TT>lispclass</TT> typemap). These are + further wrapped in a dispatching function (defun) which will invoke the + appropriate generic-function based on arity. This provides a single + functional interface to all overloads. The return value from this + function can be manipulated via the <TT>lout</TT> typemap.</P> +<H3><A name="Allegrocl_nn12"></A>17.2.6 What about constant and variable + access?</H3> +<P> Along with the described functional layering, when creating a .cxx + wrapper, this module will generate getter and--if not + immutable--setter, functions for variables and constants. If the + -nocwrap option is used, <TT>defconstant</TT> and <TT> +ff:def-foreign-variable</TT> forms will be generated for accessing + constants and global variables. These, along with the <TT>defuns</TT> + listed above are the intended API for calling into the foreign module.</P> +<H3><A name="Allegrocl_nn13"></A>17.2.7 Object Wrapping</H3> +<P> All non-primitive types (Classes, structs, unions, and typedefs + involving same) have a corresponding foreign-type defined on the lisp + side via ff:def-foreign-type.</P> +<P> All non-primitive types are further represented by a CLOS class, + created via defclass. An attempt is made to create the same class + hierarchy, with all classes inheriting directly or indirectly from + ff:foreign-pointer. Further, wherever it is apparent, all pointers + returned from foreign code are wrapped in a CLOS instance of the + appropriate class. For ff:def-foreign-calls that have been defined to + expect a :foreign-address type as argument, these CLOS instances can + legally be passed and the pointer to the C++ object automatically + extracted. This is a natural feature of Allegro's foreign function + interface.</P> +<H2><A name="Allegrocl_nn14"></A>17.3 Wrapping Details</H2> +<P> In this section is described how particular C/C++ constructs are + translated into lisp.</P> +<H3><A name="Allegrocl_nn15"></A>17.3.1 Namespaces</H3> +<P> C++ namespaces are translated into Lisp packages by SWIG. The Global + namespace is mapped to a package named by the <TT>%module</TT> + directive or the <TT>-module</TT> command-line argument. Further + namespaces are generated by the <TT>swig-defpackage</TT> utility + function and given names based on Allegro CLs nested namespace + convention. For example:</P> +<DIV class="code">foo.i: +<PRE> +%module foo + +%{ +#include "foo.h" +%} + +%include "foo.h" + +namespace car { + ... + namespace tires { + int do_something(int n); + } +} + </PRE> +</DIV> +<P>Generates the following code.</P> +<DIV class="targetlang">foo.cl +<PRE> +(defpackage :foo + (:use :common-lisp :swig :ff :excl)) + +... + +(swig-defpackage ("car")) +(swig-defpackage ("car" "tires")) + +... + +(swig-in-package ("car" "tires")) +(swig-defun ("do_something" "ACL_car_tires__do_something__SWIG_0" :type :function) + ((PARM0_n :int )) + (:returning (:int ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_n)) + (swig-ff-call SWIG_arg0))) + </PRE> +</DIV> +<P> The above interface file would cause packages foo, foo.car, and + foo.car.tires to be created. One would find the function wrapper for + do_something defined in the foo.car.tires package(*).</P> +<P>(<B>*</B>) Except for the package named by the module, all namespace + names are passed to the identifier-converter-function as strings with a + <TT>:type</TT> of <TT>:namespace</TT>. It is the job of this function + to generate the desired symbol, accounting for case preferences, + additional naming cues, etc.</P> +<P> Note that packages created by <TT>swig-defpackage</TT> do not use + the COMMON-LISP or EXCL package. This reduces possible conflicts when + defining foreign types via the SWIG interface in<B> all but the + toplevel modules package</B>. This may lead to confusion if, for + example, the current package is <TT>foo.car.tires</TT> and you attempt + to use a common-lisp function such as <TT>(car '(1 2 3)</TT>.</P> +<H3><A name="Allegrocl_nn16"></A>17.3.2 Constants</H3> +<P> Constants, as declared by the preprocessor #define macro or SWIG <TT> +%constant</TT> directive, are included in SWIGs parse tree when it can + be determined that they are, or could be reduced to, a literal value. + Such values are translated into defconstant forms in the generated lisp + wrapper when the -nocwrap command-line options is used. Else, wrapper + functions are generated as in the case of variable access (see section + below).</P> +<P> Here are examples of simple preprocessor constants when using + -nocwrap.</P> +<DIV class="code"> +<PRE> +#define A 1 => (swig-defconstant "A" 1) +#define B 'c' => (swig-defconstant "B" #\c) +#define C B => (swig-defconstant "C" #\c) +#define D 1.0e2 => (swig-defconstant "D" 1.0d2) +#define E 2222 => (swig-defconstant "E" 2222) +#define F (unsigned int)2222 => no code generated +#define G 1.02e2f => (swig-defconstant "G" 1.02f2) +#define H foo => no code generated + </PRE> +</DIV> +<P> Note that where SWIG is unable to determine if a constant is a + literal, no node is added to the SWIG parse tree, and so no values can + be generated.</P> +<P> For preprocessor constants containing expressions which can be + reduced to literal values, nodes are created, but with no + simplification of the constant value. A very very simple infix to + prefix converter has been implemented that tries to do the right thing + for simple cases, but does not for more complex expressions. If the + literal parser determines that something is wrong, a warning will be + generated and the literal expression will be included in the generated + code, but commented out.</P> +<DIV class="code"> +<PRE> +#define I A + E => (swig-defconstant "I" (+ 1 2222)) +#define J 1|2 => (swig-defconstant "J" (logior 1 2)) +#define Y 1 + 2 * 3 + 4 => (swig-defconstant "Y" (* (+ 1 2) (+ 3 4))) +#define Y1 (1 + 2) * (3 + 4) => (swig-defconstant "Y1" (* (+ 1 2) (+ 3 4))) +#define Y2 1 * 2 + 3 * 4 => (swig-defconstant "Y2" (* 1 (+ 2 3) 4)) ;; WRONG +#define Y3 (1 * 2) + (3 * 4) => (swig-defconstant "Y3" (* 1 (+ 2 3) 4)) ;; WRONG +#define Z 1 + 2 - 3 + 4 * 5 => (swig-defconstant "Z" (* (+ 1 (- 2 3) 4) 5)) ;; WRONG + </PRE> +</DIV> +<P> Users are cautioned to get to know their constants before use, or + not use the <TT>-nocwrap</TT> command-line option.</P> +<H3><A name="Allegrocl_nn17"></A>17.3.3 Variables</H3> +<P> For C wrapping, a def-foreign-variable call is generated for access + to global variables.</P> +<P> When wrapping C++ code, both global and member variables, getter + wrappers are generated for accessing their value, and if not immutable, + setter wrappers as well. In the example below, note the lack of a + setter wrapper for global_var, defined as const.</P> +<DIV class="code">vars.h +<PRE> +namespace nnn { + int const global_var = 2; + float glob_float = 2.0; +} + </PRE> +</DIV> +<P> Generated code:</P> +<DIV class="targetlang">vars.cl +<PRE> +(swig-in-package ("nnn")) +(swig-defun ("global_var" "ACL_nnn__global_var_get__SWIG_0" :type :getter) + (:void) + (:returning (:int ) + :strings-convert t) + (swig-ff-call)) + + +(swig-defun ("glob_float" "ACL_nnn__glob_float_set__SWIG_0" :type :setter) + ((PARM0_glob_float :float )) + (:returning (:void ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_glob_float)) + (swig-ff-call SWIG_arg0))) + + +(swig-defun ("glob_float" "ACL_nnn__glob_float_get__SWIG_0" :type :getter) + (:void) + (:returning (:float ) + :strings-convert t) + (swig-ff-call)) + </PRE> +</DIV> +<P> Note also, that where applicable, setter wrappers are implemented as + setf methods on the getter function, providing a lispy interface to the + foreign code.</P> +<DIV class="targetlang"> +<PRE> +user> (load "globalvar.dll") +; Foreign loading globalvar.dll. +t +user> (load "globalvar.cl") +; Loading c:\mikel\src\swig\test\globalvar.cl +t +user> +globalvar> (globalvar.nnn::global_var) +2 +globalvar> (globalvar.nnn::glob_float) +2.0 +globalvar> (setf (globalvar.nnn::glob_float) 3.0) +3.0 +globalvar> (globalvar.nnn::glob_float) +3.0 + </PRE> +</DIV> +<H3><A name="Allegrocl_nn18"></A>17.3.4 Enumerations</H3> +<P> In C, an enumeration value is an integer value, while in C++ an + enumeration value is implicitly convertible to an integer value, but + can also be distinguished by it's enum type. For each enum declaration + a def-foreign-type is generated, assigning the enum a default type of + :int. Users may adjust the foreign type of enums via SWIG <TT>typemaps</TT> +.</P> +<P> Enum values are a bit trickier as they can be initialized using any + valid C/C++ expression. In C with the -nocwrap command-line option, we + handle the typical cases (simple integer initialization) and generate a + defconstant form for each enum value. This has the advantage of it not + being necessary to probe into foreign space to retrieve enum values. + When generating a .cxx wrapper file, a more general solution is + employed. A wrapper variable is created in the module_wrap.cxx file, + and a ff:def-foreign-variable call is generated to retrieve it's value + into lisp.</P> +<P>For example, the following header file<DIV class="code">enum.h: +<PRE> +enum COL { RED, GREEN, BLUE }; +enum FOO { FOO1 = 10, FOO2, FOO3 }; + </PRE> +</DIV></P> +<P> In -nocwrap mode, generates</P> +<DIV class="targetlang">enum.cl: +<PRE> +(swig-def-foreign-type "COL" :int) +(swig-defconstant "RED" 0) +(swig-defconstant "GREEN" (+ #.(swig-insert-id "RED" () :type :constant) 1)) +(swig-defconstant "BLUE" (+ #.(swig-insert-id "GREEN" () :type :constant) 1)) + +(swig-def-foreign-type "FOO" :int) +(swig-defconstant "FOO1" 10) +(swig-defconstant "FOO2" (+ #.(swig-insert-id "FOO1" () :type :constant) 1)) +(swig-defconstant "FOO3" (+ #.(swig-insert-id "FOO2" () :type :constant) 1)) + </PRE> +</DIV> +<P>And when generating a .cxx wrapper<DIV class="code">enum_wrap.cxx: +<PRE> +EXPORT const int ACL_ENUM___RED__SWIG_0 = RED; +EXPORT const int ACL_ENUM___GREEN__SWIG_0 = GREEN; +EXPORT const int ACL_ENUM___BLUE__SWIG_0 = BLUE; +EXPORT const int ACL_ENUM___FOO1__SWIG_0 = FOO1; +EXPORT const int ACL_ENUM___FOO2__SWIG_0 = FOO2; +EXPORT const int ACL_ENUM___FOO3__SWIG_0 = FOO3; + </PRE> +</DIV></P> +<P> and</P> +<DIV class="targetlang">enum.cl: +<PRE> +(swig-def-foreign-type "COL" :int) +(swig-defvar "RED" "ACL_ENUM___RED__SWIG_0" :type :constant) +(swig-defvar "GREEN" "ACL_ENUM___GREEN__SWIG_0" :type :constant) +(swig-defvar "BLUE" "ACL_ENUM___BLUE__SWIG_0" :type :constant) + +(swig-def-foreign-type "FOO" :int) +(swig-defvar "FOO1" "ACL_ENUM___FOO1__SWIG_0" :type :constant) +(swig-defvar "FOO2" "ACL_ENUM___FOO2__SWIG_0" :type :constant) +(swig-defvar "FOO3" "ACL_ENUM___FOO3__SWIG_0" :type :constant) + + </PRE> +</DIV> +<H3><A name="Allegrocl_nn19"></A>17.3.5 Arrays</H3> +<P> One limitation in the Allegro CL foreign-types module, is that, + without macrology, expressions may not be used to specify the + dimensions of an array declaration. This is not a horrible drawback + unless it is necessary to allocate foreign structures based on the + array declaration using ff:allocate-fobject. When it can be determined + that an array bound is a valid numeric value, SWIG will include this in + the generated array declaration on the lisp side, otherwise the value + will be included, but commented out.</P> +<P> Below is a comprehensive example, showing a number of legal C/C++ + array declarations and how they are translated into foreign-type + specifications in the generated lisp code.</P> +<DIV class="code">array.h +<PRE> +#define MAX_BUF_SIZE 1024 + +namespace FOO { + int global_var1[13]; + float global_var2[MAX_BUF_SIZE]; + +} + +enum COLOR { RED = 10, GREEN = 20, BLUE, PURPLE = 50, CYAN }; + +namespace BAR { + char global_var3[MAX_BUF_SIZE + 1]; + float global_var4[MAX_BUF_SIZE][13]; + signed short global_var5[MAX_BUF_SIZE + MAX_BUF_SIZE]; + + int enum_var5[GREEN]; + int enum_var6[CYAN]; + + COLOR enum_var7[CYAN][MAX_BUF_SIZE]; +} + </PRE> +</DIV> +<P> Generates:</P> +<DIV class="targetlang">array.cl +<PRE> +(in-package #.*swig-module-name*) + +(swig-defpackage ("FOO")) +(swig-defpackage ("BAR")) + +(swig-in-package ()) +(swig-def-foreign-type "COLOR" :int) +(swig-defvar "RED" "ACL_ENUM___RED__SWIG_0" :type :constant) +(swig-defvar "GREEN" "ACL_ENUM___GREEN__SWIG_0" :type :constant) +(swig-defvar "BLUE" "ACL_ENUM___BLUE__SWIG_0" :type :constant) +(swig-defvar "PURPLE" "ACL_ENUM___PURPLE__SWIG_0" :type :constant) +(swig-defvar "CYAN" "ACL_ENUM___CYAN__SWIG_0" :type :constant) + +(swig-in-package ()) + +(swig-defconstant "MAX_BUF_SIZE" 1024) +(swig-in-package ("FOO")) + +(swig-defun ("global_var1" "ACL_FOO__global_var1_get__SWIG_0" :type :getter) + (:void) + (:returning ((* :int) ) + :strings-convert t) + (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call))) + + +(swig-defun ("global_var2" "ACL_FOO__global_var2_set__SWIG_0" :type :setter) + ((global_var2 (:array :float 1024) )) + (:returning (:void ) + :strings-convert t) + (let ((SWIG_arg0 global_var2)) + (swig-ff-call SWIG_arg0))) + + +(swig-in-package ()) +(swig-in-package ("BAR")) +(swig-defun ("global_var3" "ACL_BAR__global_var3_set__SWIG_0" :type :setter) + ((global_var3 (:array :char #|1024+1|#) )) + (:returning (:void ) + :strings-convert t) + (let ((SWIG_arg0 global_var3)) + (swig-ff-call SWIG_arg0))) + + +(swig-defun ("global_var4" "ACL_BAR__global_var4_set__SWIG_0" :type :setter) + ((global_var4 (:array (:array :float 13) 1024) )) + (:returning (:void ) + :strings-convert t) + (let ((SWIG_arg0 global_var4)) + (swig-ff-call SWIG_arg0))) + + +(swig-defun ("global_var4" "ACL_BAR__global_var4_get__SWIG_0" :type :getter) + (:void) + (:returning ((* (:array :float 13)) ) + :strings-convert t) + (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call))) + + +(swig-defun ("global_var5" "ACL_BAR__global_var5_set__SWIG_0" :type :setter) + ((global_var5 (:array :short #|1024+1024|#) )) + (:returning (:void ) + :strings-convert t) + (let ((SWIG_arg0 global_var5)) + (swig-ff-call SWIG_arg0))) + + +(swig-defun ("enum_var5" "ACL_BAR__enum_var5_set__SWIG_0" :type :setter) + ((enum_var5 (:array :int #|GREEN|#) )) + (:returning (:void ) + :strings-convert t) + (let ((SWIG_arg0 enum_var5)) + (swig-ff-call SWIG_arg0))) + + +(swig-defun ("enum_var6" "ACL_BAR__enum_var6_set__SWIG_0" :type :setter) + ((enum_var6 (:array :int #|CYAN|#) )) + (:returning (:void ) + :strings-convert t) + (let ((SWIG_arg0 enum_var6)) + (swig-ff-call SWIG_arg0))) + + +(swig-defun ("enum_var7" "ACL_BAR__enum_var7_set__SWIG_0" :type :setter) + ((enum_var7 (:array (:array #.(swig-insert-id "COLOR" ()) 1024) #|CYAN|#) )) + (:returning (:void ) + :strings-convert t) + (let ((SWIG_arg0 enum_var7)) + (swig-ff-call SWIG_arg0))) + + +(swig-defun ("enum_var7" "ACL_BAR__enum_var7_get__SWIG_0" :type :getter) + (:void) + (:returning ((* (:array #.(swig-insert-id "COLOR" ()) 1024)) ) + :strings-convert t) + (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call))) + </PRE> +</DIV> +<H3><A name="Allegrocl_nn20"></A>17.3.6 Classes and Structs and Unions + (oh my!)</H3> +<H4><A name="Allegrocl_nn21"></A>17.3.6.1 CLOS wrapping of</H4> +<P> Classes, unions, and structs are all treated the same way by the + interface generator. For any of these objects, a def-foreign-type and a + defclass form are generated. For every function that returns an object + (or pointer/reference) of C/C++ type <TT>X</TT>, the wrapping defun (or + defmethod) on the Lisp side will automatically wrap the pointer + returned in an instance of the apropriate class. This makes it much + easier to write and debug code than if pointers were passed around as a + jumble of integer values.</P> +<H4><A name="Allegrocl_nn22"></A>17.3.6.2 CLOS Inheritance</H4> +<P> The CLOS class schema generated by the interface mirrors the + inheritance of the classes in foreign code, with the ff:foreign-pointer + class at its root. ff:foreign-pointer is a thin wrapper for pointers + that is made available by the foreign function interface. It's key + benefit is that it may be passed as an argument to any + ff:def-foreign-call that is expecting a pointer as the parameter.</P> +<H4><A name="Allegrocl_nn23"></A>17.3.6.3 Member fields and functions</H4> +<P> All public fields will have accessor getter/setter functions + generated for them, as appropriate. All public member functions will + have wrapper functions generated.</P> +<P> We currently ignore anything that isn't <TT>public</TT> (i.e. <TT> +private</TT> or <TT>protected</TT>), because the C++ compiler won't + allow the wrapper functions to access such fields. Likewise, the + interface does nothing for <TT>friend</TT> directives,</P> +<H4><A name="Allegrocl_nn24"></A>17.3.6.4 Why not directly access C++ + classes using foreign types?</H4> +<P> The def-foreign-type generated by the SWIG interface is currently + incomplete. We can reliably generate the object layout of simple + structs and unions; they can be allocated via ff:allocate-fobject, and + their member variables accessed directly using the various + ff:fslot-value-* functions. However, the layout of C++ classes is more + complicated. Different compilers adjust class layout based on + inheritance patterns, and the presence of virtual member functions. The + size of member function pointers vary across compilers as well. As a + result, it is recommended that users of any generated interface not + attempt to access C++ instances via the foreign type system, but + instead use the more robust wrapper functions.</P> +<H3><A name="Allegrocl_nn25"></A>17.3.7 Templates</H3> +<H4><A name="Allegrocl_nn26"></A>17.3.7.1 Generating wrapper code for + templates</H4> +<P> SWIG provides support for dealing with templates, but by default, it + will not generate any member variable or function wrappers for + templated classes. In order to create these wrappers, you need to + explicitly tell SWIG to instantiate them. This is done via the <A href="#SWIGPlus_nn30"> +<TT>%template</TT></A> directive.</P> +<H4><A name="Allegrocl_nn27"></A>17.3.7.2 Implicit Template + instantiation</H4> +<P> While no wrapper code is generated for accessing member variables, + or calling member functions, type code is generated to include these + templated classes in the foreign-type and CLOS class schema.</P> +<H3><A name="Allegrocl_nn28"></A>17.3.8 Typedef, Templates, and Synonym + Types</H3> +<P> In C/C++ it is possible, via typedef, to have many names refer to + the same <TT>type</TT>. In general, this is not a problem, though it + can lead to confusion. Assume the below C++ header file:</P> +<DIV class="code">synonyms.h +<PRE> +class A { + int x; + int y; +}; + +typedef A Foo; + +A *xxx(int i); /* sets A->x = A->y = i */ +Foo *yyy(int i); /* sets Foo->x = Foo->y = i */ + +int zzz(A *inst = 0); /* return inst->x + inst->y */ + </PRE> +</DIV> +<P> The function <TT>zzz</TT> is an overloaded functions; the foreign + function call to it will be wrapped in a generic-function whose + argument will be checked against a type of <TT>A</TT>. Assuming a + simple implementation, a call to <TT>xxx(1)</TT> will return a pointer + to an A object, which will be wrapped in a CLOS instance of class <TT>A</TT> +, and a call to <TT>yyy(1)</TT> will result in a CLOS instance of type <TT> +Foo</TT> being returned. Without establishing a clear type relationship + between <TT>Foo</TT> and <TT>A</TT>, an attempt to call <TT>zzz(yyy(1))</TT> + will result in an error.</P> +<P> We resolve this issue, by noting synonym relationships between types + while generating the interface. A Primary type is selected (more on + this below) from the candidate list of synonyms. For all other + synonyms, intead of generating a distinct CLOS class definition, we + generate a form that expands to:</P> +<DIV class="targetlang"> <TT>(setf (find-class <synonym>) <primary>)</TT> +</DIV> +<P> The result is that all references to synonym types in foreign code, + are wrapped in the same CLOS wrapper, and, in particular, method + specialization in wrapping generic functions works as expected.</P> +<P> Given the above header file, synonym.h, a Lisp session would appear + as follows:</P> +<DIV class="targetlang"> +<PRE> +CL-USER> (load "synonym.dll") +; Foreign loading synonym.dll. +t +CL-USER> (load "synonym.cl") +; Loading c:\mikel\src\swig\test\synonym.cl +t +CL-USER> +synonym> (setf a (xxx 3)) +#<A nil #x3261a0 @ #x207299da> +synonym> (setf foo (yyy 10)) +#<A nil #x3291d0 @ #x2072e982> +synonym> (zzz a) +6 +synonym> (zzz foo) +20 +synonym> + </PRE> +</DIV> +<H4><A name="Allegrocl_nn29"></A>17.3.8.1 Choosing a primary type</H4> +<P> The choice of a primary type is selected by the following criteria + from a set of synonym types.</P> +<UL> +<LI> If a synonym type has a class definition, it is the primary type.</LI> +<LI> If a synonym type is a class template and has been explicitly + instantiated via <TT>%template</TT>, it is the primary type.</LI> +<LI> For all other sets of synonymous types, the synonym which is parsed + first becomes the primary type.</LI> +</UL> +<H3><A name="Allegrocl_nn30"></A>17.3.9 Function overloading/Parameter + defaulting</H3> +<P> For each possible argument combination, a distinct wrapper function + is created in the .cxx file. On the Lisp side, a generic functions is + defined for each possible arity the overloaded/defaulted call may have. + Each distinct wrapper is then called from within a defmethod on the + appropriate generic function. These are further wrapped inside a + dispatch function that checks the number of arguments it is called with + and passes them via apply to the appropriate generic-function. This + allows for a single entry point to overloaded functions on the lisp + side.</P> +<P>Example:</P> +<DIV class="code">overload.h: +<PRE> + +class A { + public: + int x; + int y; +}; + +float xxx(int i, int x = 0); /* return i * x */ +float xxx(A *inst, int x); /* return x + A->x + A->y */ + </PRE> +</DIV> +<P>Creates the following three wrappers, for each of the possible + argument combinations</P> +<DIV class="code">overload_wrap.cxx +<PRE> +EXPORT void ACL___delete_A__SWIG_0 (A *larg1) { + A *arg1 = (A *) 0 ; + + arg1 = larg1; + try { + delete arg1; + + } catch (...) { + + } +} + + +EXPORT float ACL___xxx__SWIG_0 (int larg1, int larg2) { + float lresult = (float)0 ; + int arg1 ; + int arg2 ; + float result; + + arg1 = larg1; + arg2 = larg2; + try { + result = (float)xxx(arg1,arg2); + + lresult = result; + return lresult; + } catch (...) { + return (float)0; + } +} + + +EXPORT float ACL___xxx__SWIG_1 (int larg1) { + float lresult = (float)0 ; + int arg1 ; + float result; + + arg1 = larg1; + try { + result = (float)xxx(arg1); + + lresult = result; + return lresult; + } catch (...) { + return (float)0; + } +} + + +EXPORT float ACL___xxx__SWIG_2 (A *larg1, int larg2) { + float lresult = (float)0 ; + A *arg1 = (A *) 0 ; + int arg2 ; + float result; + + arg1 = larg1; + arg2 = larg2; + try { + result = (float)xxx(arg1,arg2); + + lresult = result; + return lresult; + } catch (...) { + return (float)0; + } +} + </PRE> +</DIV> +<P> And the following foreign-function-call and method definitions on + the lisp side:</P> +<DIV class="targetlang">overload.cl +<PRE> +(swig-defmethod ("xxx" "ACL___xxx__SWIG_0" :type :function :arity 2) + ((PARM0_i cl:integer :int ) + (PARM1_x cl:integer :int )) + (:returning (:float ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_i)) + (let ((SWIG_arg1 PARM1_x)) + (swig-ff-call SWIG_arg0 SWIG_arg1)))) + +(swig-defmethod ("xxx" "ACL___xxx__SWIG_1" :type :function :arity 1) + ((PARM0_i cl:integer :int )) + (:returning (:float ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_i)) + (swig-ff-call SWIG_arg0))) + +(swig-defmethod ("xxx" "ACL___xxx__SWIG_2" :type :function :arity 2) + ((PARM0_inst #.(swig-insert-id "A" () :type :class) (* #.(swig-insert-id "A" ())) ) + (PARM1_x cl:integer :int )) + (:returning (:float ) + :strings-convert t) + (let ((SWIG_arg0 PARM0_inst)) + (let ((SWIG_arg1 PARM1_x)) + (swig-ff-call SWIG_arg0 SWIG_arg1)))) + +(swig-dispatcher ("xxx" :type :function :arities (1 2))) + </PRE> +</DIV> +<P>And their usage in a sample lisp session:</P> +<DIV class="targetlang"> +<PRE> +overload> (setf a (new_A)) +#<A nil #x329268 @ #x206cf612> +overload> (setf (A_x a) 10) +10 +overload> (setf (A_y a) 20) +20 +overload> (xxx 1) +0.0 +overload> (xxx 3 10) +30.0 +overload> (xxx a 1) +31.0 +overload> (xxx a 2) +32.0 +overload> + </PRE> +</DIV> +<H3><A name="Allegrocl_nn31"></A>17.3.10 Operator wrapping and Operator + overloading</H3> +<P> Wrappers to defined C++ Operators are automatically renamed, using <TT> +%rename</TT>, to the following defaults:</P> +<DIV class="code"> +<PRE> +/* name conversion for overloaded operators. */ +#ifdef __cplusplus +%rename(__add__) *::operator+; +%rename(__pos__) *::operator+(); +%rename(__pos__) *::operator+() const; + +%rename(__sub__) *::operator-; +%rename(__neg__) *::operator-() const; +%rename(__neg__) *::operator-(); + +%rename(__mul__) *::operator*; +%rename(__deref__) *::operator*(); +%rename(__deref__) *::operator*() const; + +%rename(__div__) *::operator/; +%rename(__mod__) *::operator%; +%rename(__logxor__) *::operator^; +%rename(__logand__) *::operator&; +%rename(__logior__) *::operator|; +%rename(__lognot__) *::operator~(); +%rename(__lognot__) *::operator~() const; + +%rename(__not__) *::operator!(); +%rename(__not__) *::operator!() const; + +%rename(__assign__) *::operator=; + +%rename(__add_assign__) *::operator+=; +%rename(__sub_assign__) *::operator-=; +%rename(__mul_assign__) *::operator*=; +%rename(__div_assign__) *::operator/=; +%rename(__mod_assign__) *::operator%=; +%rename(__logxor_assign__) *::operator^=; +%rename(__logand_assign__) *::operator&=; +%rename(__logior_assign__) *::operator|=; + +%rename(__lshift__) *::operator<<; +%rename(__lshift_assign__) *::operator<<=; +%rename(__rshift__) *::operator>>; +%rename(__rshift_assign__) *::operator>>=; + +%rename(__eq__) *::operator==; +%rename(__ne__) *::operator!=; +%rename(__lt__) *::operator<; +%rename(__gt__) *::operator>; +%rename(__lte__) *::operator<=; +%rename(__gte__) *::operator>=; + +%rename(__and__) *::operator&&; +%rename(__or__) *::operator||; + +%rename(__preincr__) *::operator++(); +%rename(__postincr__) *::operator++(int); +%rename(__predecr__) *::operator--(); +%rename(__postdecr__) *::operator--(int); + +%rename(__comma__) *::operator,(); +%rename(__comma__) *::operator,() const; + +%rename(__member_ref__) *::operator->; +%rename(__member_func_ref__) *::operator->*; + +%rename(__funcall__) *::operator(); +%rename(__aref__) *::operator[]; + </PRE> +</DIV> +<P> Name mangling occurs on all such renamed identifiers, so that + wrapper name generated by <TT>B::operator=</TT> will be <TT>B___eq__</TT> +, i.e. <TT><class-or-namespace>_</TT> has been added. Users may modify + these default names by adding <TT>%rename</TT> directives in their own + .i files.</P> +<P> Operator overloading can be achieved by adding functions based on + the mangled names of the function. In the following example, a class B + is defined with a Operator== method defined. The swig <TT>%extend</TT> + directive is used to add an overload method on Operator==.</P> +<DIV class="code">opoverload.h +<PRE> +class B { + public: + int x; + int y; + bool operator==(B const& other) const; +}; + </PRE> +</DIV> +<P> and</P> +<DIV class="code">opoverload.i +<PRE> +%module opoverload + +%{ +#include <fstream> +#include "opoverload.h" +%} + +%{ +bool B___eq__(B const *inst, int const x) +{ + // insert the function definition into the wrapper code before + // the wrapper for it. + // ... do stuff ... +} +%} + +%include "opoverload.h" + +%extend B { + public: + bool __eq__(int const x) const; +}; + </PRE> +</DIV> +<P> Either operator can be called via a single call to the dispatch + function:</P> +<DIV class="targetlang"> +<PRE> +opoverload> (B___eq__ x1 x2) +nil +opoverload> (B___eq__ x1 3) +nil +opoverload> + </PRE> +</DIV> +<H3><A name="Allegrocl_nn32"></A>17.3.11 Varargs</H3> +<P> Variable length argument lists are not supported, by default. If + such a function is encountered, a warning will generated to stderr. + Varargs are supported via the SWIG <TT>%vararg</TT> directive. This + directive allows you to specify a (finite) argument list which will be + inserted into the wrapper in place of the variable length argument + indicator. As an example, consider the function <TT>printf()</TT>. It's + declaration would appear as follows:</P> +<P> See the following section on <A href="#Varargs">Variable Length + arguments</A> provides examples on how <TT>%vararg</TT> can be used, + along with other ways such functions can be wrapped.</P> +<H3><A name="Allegrocl_nn33"></A>17.3.12 C++ Exceptions</H3> +<P> Each C++ wrapper includes a handler to catch any exceptions that may + be thrown while in foreign code. This helps prevent simple C++ errors + from killing the entire lisp process. There is currently no mechanism + to have these exceptions forwarded to the lisp condition system, nor + has any explicit support of the exception related SWIG typemaps been + implemented.</P> +<H3><A name="Allegrocl_nn34"></A>17.3.13 Pass by value, pass by + reference</H3> +<P> Allegro CL does not support the passing of non-primitive foreign + structures by value. As a result, SWIG must automatically detect and + convert function parameters and return values to pointers whenever + necessary. This is done via the use of <TT>typemaps</TT>, and should + not require any fine tuning by the user, even for newly defined types.</P> +<H2><A name="Allegrocl_nn35"></A>17.4 Typemaps</H2> +<P> SWIG Typemaps provide a powerful tool for automatically generating + code to handle various menial tasks required of writing an interface to + foreign code. The purpose of this section is to describe each of the + typemaps used by the Allegro CL module. Please read the chapter on <A href="#Typemaps"> +Typemaps</A> for more information.</P> +<H3><A name="Allegrocl_nn36"></A>17.4.1 Code Generation in the C++ + Wrapper</H3> +<P> Every C++ wrapper generated by SWIG takes the following form:</P> +<DIV class="diagram"> +<PRE> +return-val wrapper-name(parm0, parm1, ..., parmN) +{ + return-val lresult; /* return value from wrapper */ + <local-declaration> + ... results; /* return value from function call */ + + <binding locals to parameters> + + try { + result = function-name(local0, local1, ..., localN); + + <convert and bind result to lresult> + + return lresult; + catch (...) { + return (int)0; + } + </PRE> +</DIV> +<H4><A name="Allegrocl_nn37"></A>17.4.1.1 IN Typemap</H4> +<P> the <TT>in</TT> typemap is used to generate code to convert + parameters passed to C++ wrapper functions into the arguments desired + for the call being wrapped. That is, it fills in the code for the <TT> +<binding locals to parameters></TT> section above. We use this map to + automatically convert parameters passed by reference to the wrapper + function into by-value arguments for the wrapped call, and also to + convert boolean values, which are passed as integers from lisp (by + default), into the appropriate type for the language of code being + wrapped.</P> +<P>These are the default specifications for the IN typemap. Here, <TT> +$input</TT> refers to the parameter code is being generated for, and <TT> +$1</TT> is the local variable to which it is being assigned. The default + settings of this typemap are as follows:</P> +<DIV class="code"> +<PRE> +%typemap(in) bool "$1 = (bool)$input;"; +%typemap(in) char, unsigned char, signed char, + short, signed short, unsigned short, + int, signed int, unsigned int, + long, signed long, unsigned long, + float, double, long double, char *, void *, void, + enum SWIGTYPE, SWIGTYPE *, + SWIGTYPE[ANY], SWIGTYPE & "$1 = $input;"; +%typemap(in) SWIGTYPE "$1 = *$input;"; + </PRE> +</DIV> +<H4><A name="Allegrocl_nn38"></A>17.4.1.2 OUT Typemap</H4> +<P> The <TT>out</TT> typemap is used to generate code to form the return + value of the wrapper from the return value of the wrapped function. + This code is placed in the <convert and bind result to lresult> section + of the above code diagram. It's default mapping is as follows:</P> +<DIV class="code"> +<PRE> +%typemap(out) bool "$result = (int)$1;"; +%typemap(out) char, unsigned char, signed char, + short, signed short, unsigned short, + int, signed int, unsigned int, + long, signed long, unsigned long, + float, double, long double, char *, void *, void, + enum SWIGTYPE, SWIGTYPE *, + SWIGTYPE[ANY], SWIGTYPE & "$result = $1;"; +%typemap(out) SWIGTYPE "$result = new $1_type($1);"; + </PRE> +</DIV> +<H4><A name="Allegrocl_nn39"></A>17.4.1.3 CTYPE Typemap</H4> +<P> This typemap is not used for code generation, but purely for the + transformation of types in the parameter list of the wrapper function. + It's primary use is to handle by-value to by-reference conversion in + the wrappers parameter list. Its default settings are:</P> +<DIV class="code"> +<PRE> +%typemap(ctype) bool "int"; +%typemap(ctype) char, unsigned char, signed char, + short, signed short, unsigned short, + int, signed int, unsigned int, + long, signed long, unsigned long, + float, double, long double, char *, void *, void, + enum SWIGTYPE, SWIGTYPE *, + SWIGTYPE[ANY], SWIGTYPE & "$1_ltype"; +%typemap(ctype) SWIGTYPE "$&1_type"; + </PRE> +</DIV> +<P> These three typemaps are specifically employed by the the Allegro CL + interface generator. SWIG also implements a number of other typemaps + that can be used for generating code in the C/C++ wrappers. You can + read about these <A href="#Typemaps_nn25">common typemaps</A> here.</P> +<H3><A name="Allegrocl_nn40"></A>17.4.2 Code generation in Lisp wrappers</H3> +<P> A number of custom typemaps have also been added to facilitate the + generation of code in the lisp side of the interface. These are + described below. The basic code generation structure is applied as a + series of nested expressions, one for each parameter, then one for + manipulating the return value, and last, the foreign function call + itself.</P> +<P> Note that the typemaps below use fully qualified symbols where + necessary. Users writing their own typemaps should do likewise. See the + explanation in the last paragraph of <A href="#Allegrocl_nn15">16.3.1 + Namespaces</A> for details.</P> +<H4><A name="Allegrocl_nn41"></A>17.4.2.1 LIN Typemap</H4> +<P> The LIN typemap allows for the manipulating the lisp objects passed + as arguments to the wrapping defun before passing them to the foreign + function call. For example, when passing lisp strings to foreign code, + it is often necessary to copy the string into a foreign structure of + type (:char *) of appropriate size, and pass this copy to the foreign + call. Using the LIN typemap, one could arrange for the stack-allocation + of a foreign char array, copy your string into it, and not have to + worry about freeing the copy after the function returns.</P> +<P>The LIN typemap accepts the following <TT>$variable</TT> references.</P> +<UL> +<LI><TT>$in</TT> - expands to the name of the parameter being applied to + this typemap</LI> +<LI><TT>$out</TT> - expands to the name of the local variable assigned + to this typemap</LI> +<LI><TT>$in_fftype</TT> - the foreign function type of the C type.</LI> +<LI><TT>$*in_fftype</TT> - the foreign function type of the C type with + one pointer removed. If there is no pointer, then $*in_fftype is the + same as $in_fftype.</LI> +<LI><TT>$body</TT> - very important. Instructs SWIG where subsequent + code generation steps should be inserted into the current typemap. + Leaving out a <TT>$body</TT> reference will result in lisp wrappers + that do very little by way of calling into foreign code. Not + recommended.</LI> +</UL> +<DIV class="code"> +<PRE> +%typemap(lin) SWIGTYPE "(cl:let (($out $in))\n $body)"; + </PRE> +</DIV> +<H4><A name="Allegrocl_nn42"></A>17.4.2.2 LOUT Typemap</H4> +<P> The LOUT typemap is the means by which we effect the wrapping of + foreign pointers in CLOS instances. It is applied after all LIN + typemaps, and immediately before the actual foreign-call.</P> +<P>The LOUT typemap uses the following $variable</P> +<UL> +<LI><TT>$lclass</TT> - Expands to the CLOS class that represents + foreign-objects of the return type matching this typemap.</LI> +<LI><TT>$body</TT> - Same as for the LIN map. Place this variable where + you want the foreign-function call to occur.</LI> +<LI><TT>$ldestructor</TT> - Expands to the symbol naming the destructor + for this class ($lclass) of object. Allows you to insert finalization + or automatic garbage collection into the wrapper code (see default + mappings below).</LI> +</UL> +<DIV class="code"> +<PRE> +%typemap(lout) bool, char, unsigned char, signed char, + short, signed short, unsigned short, + int, signed int, unsigned int, + long, signed long, unsigned long, + float, double, long double, char *, void *, void, + enum SWIGTYPE "$body"; +%typemap(lout) SWIGTYPE[ANY], SWIGTYPE *, + SWIGTYPE & "(cl:make-instance '$lclass :foreign-address $body)"; +%typemap(lout) SWIGTYPE "(cl:let* ((address $body)\n + (ACL_result (cl:make-instance '$lclass :foreign-address address)))\n + (cl:unless (cl::zerop address)\n + (excl:schedule-finalization ACL_result #'$ldestructor))\n + ACL_result)"; + </PRE> +</DIV> +<H4><A name="Allegrocl_nn43"></A>17.4.2.3 FFITYPE Typemap</H4> +<P> The FFITYPE typemap works as a helper for a body of code that + converts C/C++ type specifications into Allegro CL foreign-type + specifications. These foreign-type specifications appear in + ff:def-foreing-type declarations, and in the argument list and return + values of ff:def-foreign-calls. You would modify this typemap if you + want to change how the FFI passes through arguments of a given type. + For example, if you know that a particular compiler represents booleans + as a single byte, you might add an entry for:</P> +<DIV class="code"> +<PRE> +%typemap(ffitype) bool ":unsigned-char"; + </PRE> +</DIV> +<P> Note that this typemap is pure type transformation, and is not used + in any code generations step the way the LIN and LOUT typemaps are. The + default mappings for this typemap are:</P> +<DIV class="code"> +<PRE> +%typemap(ffitype) bool ":int"; +%typemap(ffitype) char ":char"; +%typemap(ffitype) unsigned char ":unsigned-char"; +%typemap(ffitype) signed char ":char"; +%typemap(ffitype) short, signed short ":short"; +%typemap(ffitype) unsigned short ":unsigned-short"; +%typemap(ffitype) int, signed int ":int"; +%typemap(ffitype) unsigned int ":unsigned-int"; +%typemap(ffitype) long, signed long ":long"; +%typemap(ffitype) unsigned long ":unsigned-long"; +%typemap(ffitype) float ":float"; +%typemap(ffitype) double ":double"; +%typemap(ffitype) char * "(* :char)"; +%typemap(ffitype) void * "(* :void)"; +%typemap(ffitype) void ":void"; +%typemap(ffitype) enum SWIGTYPE ":int"; +%typemap(ffitype) SWIGTYPE & "(* :void)"; + </PRE> +</DIV> +<H4><A name="Allegrocl_nn44"></A>17.4.2.4 LISPTYPE Typemap</H4> +<P> This is another type only transformation map, and is used to provide + the lisp-type, which is the optional third argument in argument + specifier in a ff:def-foreign-call form. Specifying a lisp-type allows + the foreign call to perform type checking on the arguments passed in. + The default entries in this typemap are:</P> +<DIV class="code"> +<PRE> +%typemap(lisptype) bool "cl:boolean"; +%typemap(lisptype) char "cl:character"; +%typemap(lisptype) unsigned char "cl:integer"; +%typemap(lisptype) signed char "cl:integer"; + </PRE> +</DIV> +<H4><A name="Allegrocl_nn45"></A>17.4.2.5 LISPCLASS Typemap</H4> +<P> The LISPCLASS typemap is used to generate the method signatures for + the generic-functions which wrap overloaded functions and functions + with defaulted arguments. The default entries are:</P> +<DIV class="code"> +<PRE> +%typemap(lispclass) bool "t"; +%typemap(lispclass) char "cl:character"; +%typemap(lispclass) unsigned char, signed char, + short, signed short, unsigned short, + int, signed int, unsigned int, + long, signed long, unsigned long, + enum SWIGTYPE "cl:integer"; +%typemap(lispclass) float "cl:single-float"; +%typemap(lispclass) double "cl:double-float"; +%typemap(lispclass) char * "cl:string"; + </PRE> +</DIV> +<H3><A name="Allegrocl_nn46"></A>17.4.3 Modifying SWIG behavior using + typemaps</H3> +<P> The following example shows how we made use of the above typemaps to + add support for the wchar_t type.</P> +<DIV class="code"> +<PRE> +%typecheck(SWIG_TYPECHECK_UNICHAR) wchar_t { $1 = 1; }; + +%typemap(in) wchar_t "$1 = $input;"; +%typemap(lin) wchar_t "(cl:let (($out (cl:char-code $in)))\n $body)"; +%typemap(lin) wchar_t* "(excl:with-native-string + ($out $in + :external-format #+little-endian :fat-le + #-little-endian :fat)\n + $body)" + +%typemap(out) wchar_t "$result = $1;"; +%typemap(lout) wchar_t "(cl:code-char $body)"; +%typemap(lout) wchar_t* "(excl:native-to-string $body + :external-format #+little-endian :fat-le + #-little-endian :fat)"; + +%typemap(ffitype) wchar_t ":unsigned-short"; +%typemap(lisptype) wchar_t ""; +%typemap(ctype) wchar_t "wchar_t"; +%typemap(lispclass) wchar_t "cl:character"; +%typemap(lispclass) wchar_t* "cl:string"; + </PRE> +</DIV> +<H2><A name="Allegrocl_nn47"></A>17.5 Identifier Converter functions</H2> +<H3><A name="Allegrocl_nn48"></A>17.5.1 Creating symbols in the lisp + environment</H3> +<P> Various symbols must be generated in the lisp environment to which + class definitions, functions, constants, variables, etc. must be bound. + Rather than force a particular convention for naming these symbols, an + identifier (to symbol) conversion function is used. A user-defined + identifier-converter can then implement any symbol naming, + case-modifying, scheme desired.</P> +<P> In generated SWIG code, whenever some interface object must be + referenced by its lisp symbol, a macro is inserted that calls the + identifier-converter function to generate the appropriate symbol + reference. It is therefore expected that the identifier-converter + function reliably return the same (eq) symbol given the same set of + arguments.</P> +<H3><A name="Allegrocl_nn49"></A>17.5.2 Existing identifier-converter + functions</H3> +<P>Two basic identifier routines have been defined.</P> +<H4><A name="Allegrocl_nn50"></A>17.5.2.1 identifier-convert-null</H4> +<P> No modification of the identifier string is performed. Based on + other arguments, the identifier may be concatenated with other strings, + from which a symbol will be created.</P> +<H4><A name="Allegrocl_nn51"></A>17.5.2.2 identifier-convert-lispify</H4> +<P> All underscores in the identifier string are converted to hyphens. + Otherwise, identifier-convert-lispify performs the same symbol + transformations.</P> +<H4><A name="Allegrocl_nn52"></A>17.5.2.3 Default identifier to symbol + conversions</H4> +<P> Check the definitions of the above two default identifier-converters + in <TT>Lib/allegrocl/allegrocl.swg</TT> for default naming conventions.</P> +<H3><A name="Allegrocl_nn53"></A>17.5.3 Defining your own + identifier-converter</H3> +<P> A user-defined identifier-converter function should conform to the + following specification:</P> +<DIV class="targetlang"> +<PRE> +(defun identifier-convert-fn (id &key type class arity) ...body...) +result ==> symbol or (setf symbol) +</PRE> +</DIV> +<P>The <TT>ID</TT> argument is a string representing an identifier in + the foreign environment.</P> +<P> The :type keyword argument provides more information on the type of + identifier. It's value is a symbol. This allows the + identifier-converter to apply different heuristics when mapping + different types of identifiers to symbols. SWIG will generate calls to + your identifier-converter using the following types.</P> +<UL> +<LI>:class - names a CLOS class.</LI> +<LI>:constant - names a defconstant</LI> +<LI>:constructor - names a function for creating a foreign object</LI> +<LI>:destructor - names a function for freeing a foreign object</LI> +<LI>:function - names a CLOS wrapping defmethod or defun.</LI> +<LI>:ff-operator - names a foreign call defined via ff:def-foreign-call</LI> +<LI>:getter - getter function</LI> +<LI>:namespace - names a C++ namespace</LI> +<LI>:setter - names a setter function. May return a (setf symbol) + reference</LI> +<LI>:operator - names a C++ operator, such as Operator=, Operator*.</LI> +<LI>:slot - names a slot in a struct/class/union declaration.</LI> +<LI>:type - names a foreign-type defined via ff:def-foreign-type.</LI> +<LI>:variable - names a variable defined via ff:def-foreign-variable.</LI> +</UL> +<P> The :class keyword argument is a string naming a foreign class. When + non-nil, it indicates that the current identifier has scope in the + specified class.</P> +<P> The :arity keyword argument only appears in swig:swig-defmethod + forms generated for overloaded functions. It's value is an integer + indicating the number of arguments passed to the routine indicated by + this identifier.</P> +<H3><A name="Allegrocl_nn54"></A>17.5.4 Instructing SWIG to use a + particular identifier-converter</H3> +<P> By default, SWIG will use identifier-converter-null. To specify + another convert function, use the <TT>-identifier-converter</TT> + command-line argument. The value should be a string naming the function + you wish the interface to use instead, when generating symbols. ex:</P> +<DIV class="code"> +<PRE> +% swig -allegrocl -c++ -module mymodule -identifier-converter my-identifier-converter +</PRE> +</DIV><HR NOSHADE> +<H1><A name="CSharp"></A>18 SWIG and C#</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#csharp_introduction">Introduction</A></LI> +<LI><A href="#csharp_differences_java">Differences to the Java module</A> +</LI> +<LI><A href="#CSharp_arrays">C# Arrays</A> +<UL> +<LI><A href="#CSharp_arrays_swig_library">The SWIG C arrays library</A></LI> +<LI><A href="#CSharp_arrays_pinvoke_default_array_marshalling">Managed + arrays using P/Invoke default array marshalling</A></LI> +<LI><A href="#CSharp_arrays_pinning">Managed arrays using pinning</A></LI> +</UL> +</LI> +<LI><A href="#csharp_exceptions">C# Exceptions</A> +<UL> +<LI><A href="#csharp_exception_example_check_typemap">C# exception + example using "check" typemap</A></LI> +<LI><A href="#csharp_exception_example_percent_exception">C# exception + example using %exception</A></LI> +<LI><A href="#csharp_exception_example_exception_specifications">C# + exception example using exception specifications</A></LI> +<LI><A href="#csharp_custom_application_exception">Custom C# + ApplicationException example</A></LI> +</UL> +</LI> +<LI><A href="#csharp_directors">C# Directors</A> +<UL> +<LI><A href="#csharp_directors_example">Directors example</A></LI> +<LI><A href="#csharp_directors_implementation">Directors implementation</A> +</LI> +<LI><A href="#csharp_director_caveats">Director caveats</A></LI> +</UL> +</LI> +<LI><A href="#csharp_typemap_examples">C# Typemap examples</A> +<UL> +<LI><A href="#csharp_memory_management_member_variables">Memory + management when returning references to member variables</A></LI> +<LI><A href="#csharp_memory_management_objects">Memory management for + objects passed to the C++ layer</A></LI> +<LI><A href="#csharp_date_marshalling">Date marshalling using the csin + typemap and associated attributes</A></LI> +<LI><A href="#csharp_date_properties">A date example demonstrating + marshalling of C# properties</A></LI> +<LI><A href="#csharp_partial_classes">Turning wrapped classes into + partial classes</A></LI> +<LI><A href="#csharp_extending_proxy_class">Extending proxy classes with + additional C# code</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<H2><A name="csharp_introduction"></A>18.1 Introduction</H2> +<P> The purpose of the C# module is to offer an automated way of + accessing existing C/C++ code from .NET languages. The wrapper code + implementation uses C# and the Platform Invoke (PInvoke) interface to + access natively compiled C/C++ code. The PInvoke interface has been + chosen over Microsoft's Managed C++ interface as it is portable to both + Microsoft Windows and non-Microsoft platforms. PInvoke is part of the + ECMA/ISO C# specification. It is also better suited for robust + production environments due to the Managed C++ flaw called the <A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vcconMixedDLLLoadingProblem.asp"> +Mixed DLL Loading Problem</A>. Swig C# works equally well on + non-Microsoft operating systems such as Linux, Solaris and Apple Mac + using <A href="http://www.mono-project.com/">Mono</A> and <A href="http://www.dotgnu.org/pnet.html"> +Portable.NET</A>.</P> +<P> To get the most out of this chapter an understanding of interop is + required. The <A href="http://msdn.microsoft.com">Microsoft Developer + Network (MSDN)</A> has a good reference guide in a section titled + "Interop Marshaling". Monodoc, available from the Mono project, has a + very useful section titled <A href="http://www.mono-project.com/Interop_with_Native_Libraries"> +Interop with native libraries</A>.</P> +<H2><A name="csharp_differences_java"></A>18.2 Differences to the Java + module</H2> +<P> The C# module is very similar to the Java module, so until some more + complete documentation has been written, please use the <A href="#Java"> +Java documentation</A> as a guide to using SWIG with C#. The C# module + has the same major SWIG features as the Java module. The rest of this + section should be read in conjunction with the Java documentation as it + lists the main differences. The most notable differences to Java are + the following:</P> +<UL> +<LI> When invoking SWIG use the <TT>-csharp</TT> command line option + instead of <TT>-java</TT>.</LI> +<LI> The <TT>-nopgcpp</TT> command line option does not exist.</LI> +<LI> The <TT>-package</TT> command line option does not exist.</LI> +<LI> The <TT>-namespace <name></TT> commandline option will generate all + code into the namespace specified by <TT><name></TT>. C# supports + nested namespaces that are not lexically nested, so nested namespaces + will of course also work. For example: <TT>-namespace com.bloggs.widget</TT> +, will generate code into C# namespaces:<DIV class="code"> +<PRE> +namespace com.bloggs.widget { + ... +} +</PRE> +</DIV> Note that by default, the generated C# classes have no namespace + and the module name is unrelated to namespaces. The module name is just + like in Java and is merely used to name some of the generated classes.</LI> +<LI> The <TT>-dllimport <name></TT> commandline option specifies the + name of the DLL for the <TT>DllImport</TT> attribute for every PInvoke + method. If this commandline option is not given, the <TT>DllImport</TT> + DLL name is the same as the module name. This option is useful for when + one wants to invoke SWIG multiple times on different modules, yet + compile all the resulting code into a single DLL.</LI> +<LI> C/C++ variables are wrapped with C# properties and not JavaBean + style getters and setters.</LI> +<LI> Global constants are generated into the module class. There is no + constants interface.</LI> +<LI> There is no implementation for type unsafe enums - not deemed + necessary.</LI> +<LI> The default enum wrapping approach is proper C# enums, not typesafe + enums. +<BR> Note that %csconst(0) will be ignored when wrapping C/C++ enums + with proper C# enums. This is because C# enum items must be initialised + from a compile time constant. If an enum item has an initialiser and + the initialiser doesn't compile as C# code, then the %csconstvalue + directive must be used as %csconst(0) will have no effect. If it was + used, it would generate an illegal runtime initialisation via a PInvoke + call.</LI> +<LI> C# doesn't support the notion of throws clauses. Therefore there is + no 'throws' typemap attribute support for adding exception classes to a + throws clause. Likewise there is no need for an equivalent to <TT> +%javaexception</TT>. In fact, throwing C# exceptions works quite + differently, see <A href="#csharp_exceptions">C# Exceptions</A> below.</LI> +<LI> The majority of the typemaps are in csharp.swg, not java.swg.</LI> +<LI> +<P>Typemap equivalent names:</P> +<DIV class="code"> +<PRE> +jni -> ctype +jtype -> imtype +jstype -> cstype +javain -> csin +javaout -> csout +javadirectorin -> csdirectorin +javadirectorout -> csdirectorout +javainterfaces -> csinterfaces and csinterfaces_derived +javabase -> csbase +javaclassmodifiers -> csclassmodifiers +javacode -> cscode +javaimports -> csimports +javabody -> csbody +javafinalize -> csfinalize +javadestruct -> csdestruct +javadestruct_derived -> csdestruct_derived +</PRE> +</DIV></LI> +<LI> +<P>Additional typemaps:</P> +<DIV class="code"> +<PRE> +csvarin C# code property set typemap +csvarout C# code property get typemap +csattributes C# attributes for attaching to proxy classes/enums +</PRE> +</DIV></LI> +<LI> +<P>Feature equivalent names:</P> +<DIV class="code"> +<PRE> +%javaconst -> %csconst +%javaconstvalue -> %csconstvalue +%javamethodmodifiers -> %csmethodmodifiers +</PRE> +</DIV></LI> +<LI> +<P>Pragma equivalent names:</P> +<DIV class="code"> +<PRE> +%pragma(java) -> %pragma(csharp) +jniclassbase -> imclassbase +jniclassclassmodifiers -> imclassclassmodifiers +jniclasscode -> imclasscode +jniclassimports -> imclassimports +jniclassinterfaces -> imclassinterfaces +</PRE> +</DIV></LI> +<LI> +<P>Special variable equivalent names:</P> +<DIV class="code"> +<PRE> +$javaclassname -> $csclassname +$&javaclassname -> $&csclassname +$*javaclassname -> $*csclassname +$javainput -> $csinput +$jnicall -> $imcall +</PRE> +</DIV></LI> +<LI> +<P> Unlike the "javain" typemap, the "csin" typemap does not support the + 'pgcpp' attribute as the C# module does not have a premature garbage + collection prevention parameter. The "csin" typemap supports additional + optional attributes called 'cshin' and 'terminator'. The 'cshin' + attribute should contain the parameter type and name whenever a <A href="#java_constructor_helper_function"> +constructor helper function</A> is generated due to the 'pre' or 'post' + attributes. The 'terminator' attribute normally just contains a closing + brace for when the 'pre' attribute contains an opening brace, such as + when a C# <TT>using</TT> or <TT>fixed</TT> block is started. Note that + 'pre', 'post', 'terminator' and 'cshin' attributes are not used for + marshalling the property set. Please see the <A href="#csharp_date_marshalling"> +Date marshalling example</A> and <A href="#csharp_date_properties">Date + marshalling of properties example</A> for further understanding of + these "csin" applicable attributes.</P> +</LI> +<LI> +<P> Support for asymmetric type marshalling. The 'ctype', 'imtype' and + 'cstype' typemaps support an optional <TT>out</TT> attribute which is + used for output types. If this typemap attribute is specified, then the + type specified in the attribute is used for output types and the type + specified in the typemap itself is used for the input type. If this + typemap attribute is not specified, then the type used for both input + and output is the type specified in the typemap. An example shows that <TT> +char *</TT> could be marshalled in different ways,</P> +<DIV class="code"> +<PRE> +%typemap(imtype, out="IntPtr") char * "string" +char * function(char *); +</PRE> +</DIV> +<P> The output type is thus IntPtr and the input type is string. The + resulting intermediary C# code is:</P> +<DIV class="code"> +<PRE> +public static extern IntPtr function(string jarg1); +</PRE> +</DIV></LI> +<LI> +<P> Support for type attributes. The 'imtype' and 'cstype' typemaps can + have an optional <TT>inattributes</TT> and <TT>outattributes</TT> + typemap attribute. There are C# attributes and typemap attributes, + don't get confused!! The C# attributes specified in these typemap + attributes are generated wherever the type is used in the C# wrappers. + These can be used to specify any C# attribute associated with a C/C++ + type, but are more typically used for the C# <TT>MarshalAs</TT> + attribute. For example:</P> +<DIV class="code"> +<PRE> +%typemap(imtype, + inattributes="[MarshalAs(UnmanagedType.LPStr)]", + outattributes="[return: MarshalAs(UnmanagedType.LPStr)]") const char * "String" + +const char * GetMsg() {} +void SetMsg(const char *msg) {} +</PRE> +</DIV> +<P> The intermediary class will then have the marshalling as specified + by everything in the 'imtype' typemap:</P> +<DIV class="code"> +<PRE> +class examplePINVOKE { + ... + [DllImport("example", EntryPoint="CSharp_GetMsg")] + [return: MarshalAs(UnmanagedType.LPStr)] + public static extern String GetMsg(); + + [DllImport("example", EntryPoint="CSharp_SetMsg")] + public static extern void SetMsg([MarshalAs(UnmanagedType.LPStr)]String jarg1); +} +</PRE> +</DIV> +<P> Note that the <TT>DllImport</TT> attribute is always generated, + irrespective of any additional attributes specified.</P> +<P> These attributes are associated with the C/C++ parameter type or + return type, which is subtly different to the attribute features and + typemaps covered next. Note that all these different C# attributes can + be combined so that a method has more than one attribute.</P> +</LI> +<LI> +<P> Support for attaching C# attributes to wrapped methods and + variables. This is done using the <TT>%csattributes</TT> feature, see <A +href="#features">%feature directives</A>. Note that C# attributes are + attached to proxy classes and enums using the <TT>csattributes</TT> + typemap. For example, imagine we have a custom attribute class, <TT> +ThreadSafeAttribute</TT>, for labelling thread safety. The following + SWIG code shows how to attach this C# attribute to some methods and the + class declaration itself:</P> +<DIV class="code"> +<PRE> +%typemap(csattributes) AClass "[ThreadSafe]" +%csattributes AClass::AClass(double d) "[ThreadSafe(false)]" +%csattributes AClass::AMethod() "[ThreadSafe(true)]" + +%inline %{ +class AClass { +public: + AClass(double a) {} + void AMethod() {} +}; +%} +</PRE> +</DIV> +<P> will generate a C# proxy class:</P> +<DIV class="code"> +<PRE> +[ThreadSafe] +public class AClass : IDisposable { + ... + [ThreadSafe(false)] + public AClass(double a) ... + + [ThreadSafe(true)] + public void AMethod() ... +} +</PRE> +</DIV> +<P> If C# attributes need adding to the <TT>set</TT> or <TT>get</TT> + part of C# properties, when wrapping C/C++ variables, they can be added + using the 'csvarin' and 'csvarout' typemaps respectively. Note that the + type used for the property is specified in the 'cstype' typemap. If the + 'out' attribute exists in this typemap, then the type used is from the + 'out' attribute.</P> +</LI> +<LI> +<P> The intermediary classname has <TT>PINVOKE</TT> appended after the + module name instead of <TT>JNI</TT>, for example <TT>modulenamePINVOKE</TT> +.</P> +</LI> +<LI> +<P> The <TT>%csmethodmodifiers</TT> feature can also be applied to + variables as well as methods. In addition to the default <TT>public</TT> + modifier that SWIG generates when <TT>%csmethodmodifiers</TT> is not + specified, the feature will also replace the <TT>virtual</TT>/<TT>new</TT> +/<TT>override</TT> modifiers that SWIG thinks is appropriate. This + feature is useful for some obscure cases where SWIG might get the <TT> +virtual</TT>/<TT>new</TT>/<TT>override</TT> modifiers incorrect, for + example with multiple inheritance.</P> +</LI> +<LI> <A name="csharp_module_directive"></A> +<P> The name of the intermediary class can be changed from its default, + that is, the module name with PINVOKE appended after it. The module + directive attribute <TT>imclassname</TT> is used to achieve this:</P> +<DIV class="code"> +<PRE> +%module (imclassname="name") modulename +</PRE> +</DIV> +<P> If <TT>name</TT> is the same as <TT>modulename</TT> then the module + class name gets changed from <TT>modulename</TT> to <TT> +modulenameModule</TT>.</P> +</LI> +<LI> There is no additional 'premature garbage collection prevention + parameter' as the marshalling of the <TT>HandleRef</TT> object takes + care of ensuring a reference to the proxy class is held until the + unmanaged call completed.</LI> +</UL> +<P><B> <TT>$dllimport</TT></B> +<BR> This is a C# only special variable that can be used in typemaps, + pragmas, features etc. The special variable will get translated into + the value specified by the <TT>-dllimport</TT> commandline option if + specified, otherwise it is equivalent to the<B> $module</B> special + variable.</P> +<P><B> <TT>$imclassname</TT></B> +<BR> This special variable expands to the intermediary class name. For + C# this is usually the same as '$modulePINVOKE' ('$moduleJNI' for + Java), unless the imclassname attribute is specified in the <A href="#csharp_module_directive"> +%module directive</A>.</P> +<P> The directory <TT>Examples/csharp</TT> has a number of simple + examples. Visual Studio .NET 2003 solution and project files are + available for compiling with the Microsoft .NET C# compiler on Windows. + If your SWIG installation went well on a Unix environment and your C# + compiler was detected, you should be able to type <TT>make</TT> in each + example directory, then <TT>ilrun runme.exe</TT> (Portable.NET C# + compiler) or <TT>mono runme.exe</TT> (Mono C# compiler) to run the + examples. Windows users can also get the examples working using a <A href="http://www.cygwin.com"> +Cygwin</A> or <A href="http://www.mingw.org">MinGW</A> environment for + automatic configuration of the example makefiles. Any one of the three + C# compilers (Portable.NET, Mono or Microsoft) can be detected from + within a Cygwin or Mingw environment if installed in your path.</P> +<H2><A name="CSharp_arrays"></A>18.3 C# Arrays</H2> +<P> There are various ways to pass arrays from C# to C/C++. The default + wrapping treats arrays as pointers and as such simple type wrapper + classes are generated, eg <TT>SWIGTYPE_p_int</TT> when wrapping the C + type <TT>int []</TT> or <TT>int *</TT>. This gives a rather restricted + use of the underlying unmanaged code and the most practical way to use + arrays is to enhance or customise with one of the following three + approaches; namely the SWIG C arrays library, P/Invoke default array + marshalling or pinned arrays.</P> +<H3><A name="CSharp_arrays_swig_library"></A>18.3.1 The SWIG C arrays + library</H3> +<P> The C arrays library keeps all the array memory in the unmanaged + layer. The library is available to all language modules and is + documented in the <A href="#Library_carrays">carrays.i library</A> + section. Please refer to this section for details, but for convenience, + the C# usage for the two examples outlined there is shown below.</P> +<P> For the <TT>%array_functions</TT> example, the equivalent usage + would be:</P> +<DIV class="code"> +<PRE> +SWIGTYPE_p_double a = example.new_doubleArray(10); // Create an array +for (int i=0; i<10; i++) + example.doubleArray_setitem(a,i,2*i); // Set a value +example.print_array(a); // Pass to C +example.delete_doubleArray(a); // Destroy array +</PRE> +</DIV> +<P> and for the <TT>%array_class</TT> example, the equivalent usage + would be:</P> +<DIV class="code"> +<PRE> +doubleArray c = new doubleArray(10); // Create double[10] +for (int i=0; i<10; i++) + c.setitem(i, 2*i); // Assign values +example.print_array(c.cast()); // Pass to C +</PRE> +</DIV> +<H3><A name="CSharp_arrays_pinvoke_default_array_marshalling"></A>18.3.2 + Managed arrays using P/Invoke default array marshalling</H3> +<P> In the P/Invoke default marshalling scheme, one needs to designate + whether the invoked function will treat a managed array parameter as + input, output, or both. When the function is invoked, the CLR allocates + a separate chunk of memory as big as the given managed array, which is + automatically released at the end of the function call. If the array + parameter is marked as being input, the content of the managed array is + copied into this buffer when the call is made. Correspondingly, if the + array parameter is marked as being output, the contents of the reserved + buffer are copied back into the managed array after the call returns. A + pointer to to this buffer is passed to the native function.</P> +<P> The reason for allocating a separate buffer is to leave the CLR free + to relocate the managed array object during garbage collection. If the + overhead caused by the copying is causing a significant performance + penalty, consider pinning the managed array and passing a direct + reference as described in the next section.</P> +<P> For more information on the subject, see the <A href="http://msdn.microsoft.com/en-us/library/z6cfh6e6(VS.80).aspx"> +Default Marshaling for Arrays</A> article on MSDN.</P> +<P> The P/Invoke default marshalling is supported by the <TT> +arrays_csharp.i</TT> library via the INPUT, OUTPUT and INOUT typemaps. + Let's look at some example usage. Consider the following C function:</P> +<DIV class="code"> +<PRE> +void myArrayCopy(int *sourceArray, int *targetArray, int nitems); +</PRE> +</DIV> +<P> We can now instruct SWIG to use the default marshalling typemaps by</P> +<DIV class="code"> +<PRE> +%include "arrays_csharp.i" + +%apply int INPUT[] {int *sourceArray} +%apply int OUTPUT[] {int *targetArray} +</PRE> +</DIV> +<P> As a result, we get the following method in the module class:</P> +<DIV class="code"> +<PRE> +public static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) { + examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems); +} +</PRE> +</DIV> +<P> If we look beneath the surface at the corresponding intermediary + class code, we see that SWIG has generated code that uses attributes + (from the System.Runtime.InteropServices namespace) to tell the CLR to + use default marshalling for the arrays:</P> +<DIV class="code"> +<PRE> +[DllImport("example", EntryPoint="CSharp_myArrayCopy")] +public static extern void myArrayCopy([In, MarshalAs(UnmanagedType.LPArray)]int[] jarg1, + [Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2, int jarg3); +</PRE> +</DIV> +<P> As an example of passing an inout array (i.e. the target function + will both read from and write to the array), consider this C function + that swaps a given number of elements in the given arrays:</P> +<DIV class="code"> +<PRE> +void myArraySwap(int *array1, int *array2, int nitems); +</PRE> +</DIV> +<P> Now, we can instruct SWIG to wrap this by</P> +<DIV class="code"> +<PRE> +%include "arrays_csharp.i" + +%apply int INOUT[] {int *array1} +%apply int INOUT[] {int *array2} +</PRE> +</DIV> +<P> This results in the module class method</P> +<DIV class="code"> +<PRE> + public static void myArraySwap(int[] array1, int[] array2, int nitems) { + examplePINVOKE.myArraySwap(array1, array2, nitems); + } +</PRE> +</DIV> +<P> and intermediate class method</P> +<DIV class="code"> +<PRE> + [DllImport("example", EntryPoint="CSharp_myArraySwap")] + public static extern void myArraySwap([In, Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg1, + [In, Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2, int jarg3); +</PRE> +</DIV> +<H3><A name="CSharp_arrays_pinning"></A>18.3.3 Managed arrays using + pinning</H3> +<P> It is also possible to pin a given array in memory (i.e. fix its + location in memory), obtain a direct pointer to it, and then pass this + pointer to the wrapped C/C++ function. This approach involves no + copying, but it makes the work of the garbage collector harder as the + managed array object can not be relocated before the fix on the array + is released. You should avoid fixing arrays in memory in cases where + the control may re-enter the managed side via a callback and/or another + thread may produce enough garbage to trigger garbage collection.</P> +<P> For more information, see the <A href="http://msdn.microsoft.com/en-us/library/f58wzh21(VS.80).aspx"> +fixed statement</A> in the C# language reference.</P> +<P> Now let's look at an example using pinning, thus avoiding the CLR + making copies of the arrays passed as parameters. The <TT> +arrays_csharp.i</TT> library file again provides the required support + via the <TT>FIXED</TT> typemaps. Let's use the same function from the + previous section:</P> +<DIV class="code"> +<PRE> +void myArrayCopy(int *sourceArray, int *targetArray, int nitems); +</PRE> +</DIV> +<P> We now need to declare the module class method unsafe, as we are + using pointers:</P> +<DIV class="code"> +<PRE> +%csmethodmodifiers myArrayCopy "public unsafe"; + </PRE> +</DIV> +<P> Apply the appropriate typemaps to the array parameters:</P> +<DIV class="code"> +<PRE> +%include "arrays_csharp.i" + +%apply int FIXED[] {int *sourceArray} +%apply int FIXED[] {int *targetArray} +</PRE> +</DIV> +<P> Notice that there is no need for separate in, out or inout typemaps + as is the case when using P/Invoke default marshalling.</P> +<P> As a result, we get the following method in the module class:</P> +<DIV class="code"> +<PRE> + public unsafe static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) { + fixed ( int *swig_ptrTo_sourceArray = sourceArray ) { + fixed ( int *swig_ptrTo_targetArray = targetArray ) { + { + examplePINVOKE.myArrayCopy((IntPtr)swig_ptrTo_sourceArray, (IntPtr)swig_ptrTo_targetArray, nitems); + } + } + } + } +</PRE> +</DIV> +<P> On the method signature level the only difference to the version + using P/Invoke default marshalling is the "unsafe" quantifier, which is + required because we are handling pointers.</P> +<P> Also the intermediate class method looks a little different from the + default marshalling example - the method is expecting an IntPtr as the + parameter type.</P> +<DIV class="code"> +<PRE> +[DllImport("example", EntryPoint="CSharp_myArrayCopy")] +public static extern void myArrayCopy(IntPtr jarg1, IntPtr jarg2, int jarg3); +</PRE> +</DIV> +<H2><A name="csharp_exceptions"></A>18.4 C# Exceptions</H2> +<P> It is possible to throw a C# Exception from C/C++ code. SWIG already + provides the framework for throwing C# exceptions if it is able to + detect that a C++ exception could be thrown. Automatically detecting + that a C++ exception could be thrown is only possible when a C++ + exception specification is used, see <A href="#SWIGPlus_exception_specifications"> +Exception specifications</A>. The <A href="#exception">Exception + handling with %exception</A> section details the <TT>%exception</TT> + feature. Customised code for handling exceptions with or without a C++ + exception specification is possible and the details follow. However + anyone wishing to do this should be familiar with the contents of the + sections referred to above.</P> +<P> Unfortunately a C# exception cannot simply be thrown from unmanaged + code for a variety of reasons. Most notably being that throwing a C# + exception results in exceptions being thrown across the C PInvoke + interface and C does not understand exceptions. The design revolves + around a C# exception being constructed and stored as a pending + exception, to be thrown only when the unmanaged code has completed. + Implementing this is a tad involved and there are thus some unusual + typemap constructs. Some practical examples follow and they should be + read in conjunction with the rest of this section.</P> +<P> First some details about the design that must be followed. Each + typemap or feature that generates<B> unmanaged code</B> supports an + attribute called <TT>canthrow</TT>. This is simply a flag which when + set indicates that the code in the typemap/feature has code which might + want to throw a C# exception. The code in the typemap/feature can then + raise a C# exception by calling one of the C functions, <TT> +SWIG_CSharpSetPendingException()</TT> or <TT> +SWIG_CSharpSetPendingExceptionArgument()</TT>. When called, the function + makes a callback into the managed world via a delegate. The callback + creates and stores an exception ready for throwing when the unmanaged + code has finished. The typemap/feature unmanaged code is then expected + to force an immediate return from the unmanaged wrapper function, so + that the pending managed exception can then be thrown. The support code + has been carefully designed to be efficient as well as thread-safe. + However to achieve the goal of efficiency requires some optional code + generation in the<B> managed code</B> typemaps. Code to check for + pending exceptions is generated if and only if the unmanaged code has + code to set a pending exception, that is if the <TT>canthrow</TT> + attribute is set. The optional managed code is generated using the <TT> +excode</TT> typemap attribute and <TT>$excode</TT> special variable in + the relevant managed code typemaps. Simply, if any relevant unmanaged + code has the <TT>canthrow</TT> attribute set, then any occurrences of <TT> +$excode</TT> is replaced with the code in the <TT>excode</TT> attribute. + If the <TT>canthrow</TT> attribute is not set, then any occurrences of <TT> +$excode</TT> are replaced with nothing.</P> +<P> The prototypes for the <TT>SWIG_CSharpSetPendingException()</TT> and + <TT>SWIG_CSharpSetPendingExceptionArgument()</TT> functions are</P> +<DIV class="code"> +<PRE> +static void SWIG_CSharpSetPendingException(SWIG_CSharpExceptionCodes code, + const char *msg); + +static void SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpExceptionArgumentCodes code, + const char *msg, + const char *param_name); +</PRE> +</DIV> +<P> The first parameter defines which .NET exceptions can be thrown:</P> +<DIV class="code"> +<PRE> +typedef enum { + SWIG_CSharpApplicationException, + SWIG_CSharpArithmeticException, + SWIG_CSharpDivideByZeroException, + SWIG_CSharpIndexOutOfRangeException, + SWIG_CSharpInvalidCastException, + SWIG_CSharpInvalidOperationException, + SWIG_CSharpIOException, + SWIG_CSharpNullReferenceException, + SWIG_CSharpOutOfMemoryException, + SWIG_CSharpOverflowException, + SWIG_CSharpSystemException +} SWIG_CSharpExceptionCodes; + +typedef enum { + SWIG_CSharpArgumentException, + SWIG_CSharpArgumentNullException, + SWIG_CSharpArgumentOutOfRangeException, +} SWIG_CSharpExceptionArgumentCodes; +</PRE> +</DIV> +<P> where, for example, <TT>SWIG_CSharpApplicationException</TT> + corresponds to the .NET exception, <TT>ApplicationException</TT>. The <TT> +msg</TT> and <TT>param_name</TT> parameters contain the C# exception + message and parameter name associated with the exception.</P> +<P> The <TT>%exception</TT> feature in C# has the <TT>canthrow</TT> + attribute set. The <TT>%csnothrowexception</TT> feature is like <TT> +%exception</TT>, but it does not have the <TT>canthrow</TT> attribute + set so should only be used when a C# exception is not created.</P> +<H3><A name="csharp_exception_example_check_typemap"></A>18.4.1 C# + exception example using "check" typemap</H3> +<P> Lets say we have the following simple C++ method:</P> +<DIV class="code"> +<PRE> +void positivesonly(int number); +</PRE> +</DIV> +<P> and we want to check that the input <TT>number</TT> is always + positive and if not throw a C# <TT>ArgumentOutOfRangeException</TT>. + The "check" typemap is designed for checking input parameters. Below + you will see the <TT>canthrow</TT> attribute is set because the code + contains a call to <TT>SWIG_CSharpSetPendingExceptionArgument()</TT>. + The full example follows:</P> +<DIV class="code"> +<PRE> +%module example + +%typemap(check, canthrow=1) int number %{ +if ($1 < 0) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, + "only positive numbers accepted", "number"); + return $null; +} +// SWIGEXCODE is a macro used by many other csout typemaps +%define SWIGEXCODE + "\n if ($modulePINVOKE.SWIGPendingException.Pending)" + "\n throw $modulePINVOKE.SWIGPendingException.Retrieve();" +%enddef +%typemap(csout, excode=SWIGEXCODE) void { + $imcall;$excode + } +%} + +%inline %{ + +void positivesonly(int number) { +} + +%} +</PRE> +</DIV> +<P> When the following C# code is executed:</P> +<DIV class="code"> +<PRE> +public class runme { + static void Main() { + example.positivesonly(-1); + } +} +</PRE> +</DIV> +<P> The exception is thrown:</P> +<DIV class="code"> +<PRE> +Unhandled Exception: System.ArgumentOutOfRangeException: only positive numbers accepted +Parameter name: number +in <0x00034> example:positivesonly (int) +in <0x0000c> runme:Main () +</PRE> +</DIV> +<P> Now let's analyse the generated code to gain a fuller understanding + of the typemaps. The generated unmanaged C++ code is:</P> +<DIV class="code"> +<PRE> +SWIGEXPORT void SWIGSTDCALL CSharp_positivesonly(int jarg1) { + int arg1 ; + + arg1 = (int)jarg1; + + if (arg1 < 0) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, + "only positive numbers accepted", "number"); + return ; + } + + positivesonly(arg1); + +} +</PRE> +</DIV> +<P> This largely comes from the "check" typemap. The managed code in the + module class is:</P> +<DIV class="code"> +<PRE> +public class example { + public static void positivesonly(int number) { + examplePINVOKE.positivesonly(number); + if (examplePINVOKE.SWIGPendingException.Pending) + throw examplePINVOKE.SWIGPendingException.Retrieve(); + } + +} +</PRE> +</DIV> +<P> This comes largely from the "csout" typemap.</P> +<P> The "csout" typemap is the same as the default void "csout" typemap + so is not strictly necessary for the example. However, it is shown to + demonstrate what managed output code typemaps should contain, that is, + a <TT>$excode</TT> special variable and an <TT>excode</TT> attribute. + Also note that <TT>$excode</TT> is expanded into the code held in the <TT> +excode</TT> attribute. The <TT>$imcall</TT> as always expands into <TT> +examplePINVOKE.positivesonly(number)</TT>. The exception support code in + the intermediary class, <TT>examplePINVOKE</TT>, is not shown, but is + contained within the inner classes, <TT>SWIGPendingException</TT> and <TT> +SWIGExceptionHelper</TT> and is always generated. These classes can be + seen in any of the generated wrappers. However, all that is required of + a user is as demonstrated in the "csin" typemap above. That is, is to + check <TT>SWIGPendingException.Pending</TT> and to throw the exception + returned by <TT>SWIGPendingException.Retrieve()</TT>.</P> +<P> If the "check" typemap did not exist, then the following module + class would instead be generated:</P> +<DIV class="code"> +<PRE> +public class example { + public static void positivesonly(int number) { + examplePINVOKE.positivesonly(number); + } + +} +</PRE> +</DIV> +<P> Here we see the pending exception checking code is omitted. In fact, + the code above would be generated if the <TT>canthrow</TT> attribute + was not in the "check" typemap, such as:</P> +<DIV class="code"> +<PRE> +%typemap(check) int number %{ +if ($1 < 0) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, + "only positive numbers accepted", "number"); + return $null; +} +%} +</PRE> +</DIV> +<P> Note that if SWIG detects you have used <TT> +SWIG_CSharpSetPendingException()</TT> or <TT> +SWIG_CSharpSetPendingExceptionArgument()</TT> without setting the <TT> +canthrow</TT> attribute you will get a warning message similar to</P> +<DIV class="code"> +<PRE> +example.i:21: Warning(845): Unmanaged code contains a call to a SWIG_CSharpSetPendingException +method and C# code does not handle pending exceptions via the canthrow attribute. +</PRE> +</DIV> +<P> Actually it will issue this warning for any function beginning with <TT> +SWIG_CSharpSetPendingException</TT>.</P> +<H3><A name="csharp_exception_example_percent_exception"></A>18.4.2 C# + exception example using %exception</H3> +<P> Let's consider a similar, but more common example that throws a C++ + exception from within a wrapped function. We can use <TT>%exception</TT> + as mentioned in <A href="#exception">Exception handling with %exception</A> +.</P> +<DIV class="code"> +<PRE> +%exception negativesonly(int value) %{ +try { + $action +} catch (std::out_of_range e) { + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what()); +} +%} + +%inline %{ +#include <stdexcept> +void negativesonly(int value) { + if (value >= 0) + throw std::out_of_range("number should be negative"); +} +%} +</PRE> +</DIV> +<P> The generated unmanaged code this time catches the C++ exception and + converts it into a C# <TT>ApplicationException</TT>.</P> +<DIV class="code"> +<PRE> +SWIGEXPORT void SWIGSTDCALL CSharp_negativesonly(int jarg1) { + int arg1 ; + + arg1 = (int)jarg1; + + try { + negativesonly(arg1); + + } catch (std::out_of_range e) { + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what()); + return ; + } + +} +</PRE> +</DIV> +<P> The managed code generated does check for the pending exception as + mentioned earlier as the C# version of <TT>%exception</TT> has the <TT> +canthrow</TT> attribute set by default:</P> +<DIV class="code"> +<PRE> + public static void negativesonly(int value) { + examplePINVOKE.negativesonly(value); + if (examplePINVOKE.SWIGPendingException.Pending) + throw examplePINVOKE.SWIGPendingException.Retrieve(); + } +</PRE> +</DIV> +<H3><A name="csharp_exception_example_exception_specifications"></A> +18.4.3 C# exception example using exception specifications</H3> +<P> When C++ exception specifications are used, SWIG is able to detect + that the method might throw an exception. By default SWIG will + automatically generate code to catch the exception and convert it into + a managed <TT>ApplicationException</TT>, as defined by the default + "throws" typemaps. The following example has a user supplied "throws" + typemap which is used whenever an exception specification contains a <TT> +std::out_of_range</TT>, such as the <TT>evensonly</TT> method below.</P> +<DIV class="code"> +<PRE> +%typemap(throws, canthrow=1) std::out_of_range { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, $1.what(), NULL); + return $null; +} + +%inline %{ +#include <stdexcept> +void evensonly(int input) throw (std::out_of_range) { + if (input%2 != 0) + throw std::out_of_range("number is not even"); +} +%} +</PRE> +</DIV> +<P> Note that the type for the throws typemap is the type in the + exception specification. SWIG generates a try catch block with the + throws typemap code in the catch handler.</P> +<DIV class="code"> +<PRE> +SWIGEXPORT void SWIGSTDCALL CSharp_evensonly(int jarg1) { + int arg1 ; + + arg1 = (int)jarg1; + try { + evensonly(arg1); + } + catch(std::out_of_range &_e) { + { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, (&_e)->what(), NULL); + return ; + } + } + +} +</PRE> +</DIV> +<P> Multiple catch handlers are generated should there be more than one + exception specifications declared.</P> +<H3><A name="csharp_custom_application_exception"></A>18.4.4 Custom C# + ApplicationException example</H3> +<P> This example involves a user defined exception. The conventional + .NET exception handling approach is to create a custom <TT> +ApplicationException</TT> and throw it in your application. The goal in + this example is to convert the STL <TT>std::out_of_range</TT> exception + into one of these custom .NET exceptions.</P> +<P> The default exception handling is quite easy to use as the <TT> +SWIG_CSharpSetPendingException()</TT> and <TT> +SWIG_CSharpSetPendingExceptionArgument()</TT> methods are provided by + SWIG. However, for a custom C# exception, the boiler plate code that + supports these functions needs replicating. In essence this consists of + some C/C++ code and C# code. The C/C++ code can be generated into the + wrapper file using the <TT>%insert(runtime)</TT> directive and the C# + code can be generated into the intermediary class using the <TT> +imclasscode</TT> pragma as follows:</P> +<DIV class="code"> +<PRE> +%insert(runtime) %{ + // Code to handle throwing of C# CustomApplicationException from C/C++ code. + // The equivalent delegate to the callback, CSharpExceptionCallback_t, is CustomExceptionDelegate + // and the equivalent customExceptionCallback instance is customDelegate + typedef void (SWIGSTDCALL* CSharpExceptionCallback_t)(const char *); + CSharpExceptionCallback_t customExceptionCallback = NULL; + + extern "C" SWIGEXPORT + void SWIGSTDCALL CustomExceptionRegisterCallback(CSharpExceptionCallback_t customCallback) { + customExceptionCallback = customCallback; + } + + // Note that SWIG detects any method calls named starting with + // SWIG_CSharpSetPendingException for warning 845 + static void SWIG_CSharpSetPendingExceptionCustom(const char *msg) { + customExceptionCallback(msg); + } +%} + +%pragma(csharp) imclasscode=%{ + class CustomExceptionHelper { + // C# delegate for the C/C++ customExceptionCallback + public delegate void CustomExceptionDelegate(string message); + static CustomExceptionDelegate customDelegate = + new CustomExceptionDelegate(SetPendingCustomException); + + [DllImport("$dllimport", EntryPoint="CustomExceptionRegisterCallback")] + public static extern + void CustomExceptionRegisterCallback(CustomExceptionDelegate customCallback); + + static void SetPendingCustomException(string message) { + SWIGPendingException.Set(new CustomApplicationException(message)); + } + + static CustomExceptionHelper() { + CustomExceptionRegisterCallback(customDelegate); + } + } + static CustomExceptionHelper exceptionHelper = new CustomExceptionHelper(); +%} +</PRE> +</DIV> +<P> The method stored in the C# delegate instance, <TT>customDelegate</TT> + is what gets called by the C/C++ callback. However, the equivalent to + the C# delegate, that is the C/C++ callback, needs to be assigned + before any unmanaged code is executed. This is achieved by putting the + initialisation code in the intermediary class. Recall that the + intermediary class contains all the PInvoke methods, so the static + variables in the intermediary class will be initialised before any of + the PInvoke methods in this class are called. The <TT>exceptionHelper</TT> + static variable ensures the C/C++ callback is initialised with the + value in <TT>customDelegate</TT> by calling the <TT> +CustomExceptionRegisterCallback</TT> method in the <TT> +CustomExceptionHelper</TT> static constructor. Once this has been done, + unmanaged code can make callbacks into the managed world as <TT> +customExceptionCallback</TT> will be initialised with a valid + callback/delegate. Any calls to <TT> +SWIG_CSharpSetPendingExceptionCustom()</TT> will make the callback to + create the pending exception in the same way that <TT> +SWIG_CSharpSetPendingException()</TT> and <TT> +SWIG_CSharpSetPendingExceptionArgument()</TT> does. In fact the method + has been similarly named so that SWIG can issue the warning about + missing <TT>canthrow</TT> attributes as discussed earlier. It is an + invaluable warning as it is easy to forget the <TT>canthrow</TT> + attribute when writing typemaps/features.</P> +<P> The <TT>SWIGPendingException</TT> helper class is not shown, but is + generated as an inner class into the intermediary class. It stores the + pending exception in Thread Local Storage so that the exception + handling mechanism is thread safe.</P> +<P> The boiler plate code above must be used in addition to a + handcrafted <TT>CustomApplicationException</TT>:</P> +<DIV class="code"> +<PRE> +// Custom C# Exception +class CustomApplicationException : System.ApplicationException { + public CustomApplicationException(string message) + : base(message) { + } +} +</PRE> +</DIV> +<P> and the SWIG interface code:</P> +<DIV class="code"> +<PRE> +%typemap(throws, canthrow=1) std::out_of_range { + SWIG_CSharpSetPendingExceptionCustom($1.what()); + return $null; +} + +%inline %{ +void oddsonly(int input) throw (std::out_of_range) { + if (input%2 != 1) + throw std::out_of_range("number is not odd"); +} +%} +</PRE> +</DIV> +<P> The "throws" typemap now simply calls our new <TT> +SWIG_CSharpSetPendingExceptionCustom()</TT> function so that the + exception can be caught, as such:</P> +<DIV class="code"> +<PRE> +try { + example.oddsonly(2); +} catch (CustomApplicationException e) { + ... +} +</PRE> +</DIV> +<H2><A name="csharp_directors"></A>18.5 C# Directors</H2> +<P> The SWIG directors feature adds extra code to the generated C# proxy + classes that enable these classes to be used in cross-language + polymorphism. Essentially, it enables unmanaged C++ code to call back + into managed code for virtual methods so that a C# class can derive + from a wrapped C++ class.</P> +<P> The following sections provide information on the C# director + implementation and contain most of the information required to use the + C# directors. However, the <A href="#java_directors">Java directors</A> + section should also be read in order to gain more insight into + directors.</P> +<H3><A name="csharp_directors_example"></A>18.5.1 Directors example</H3> +<P> Imagine we are wrapping a C++ base class, <TT>Base</TT>, from which + we would like to inherit in C#. Such a class is shown below as well as + another class, <TT>Caller</TT>, which calls the virtual method <TT> +UIntMethod</TT> from pure unmanaged C++ code.</P> +<DIV class="code"> +<PRE> +// file: example.h +class Base { +public: + virtual ~Base() {} + + virtual unsigned int UIntMethod(unsigned int x) { + std::cout << "Base - UIntMethod(" << x << ")" << std::endl; + return x; + } + virtual void BaseBoolMethod(const Base &b, bool flag) {} +}; + +class Caller { +public: + Caller(): m_base(0) {} + ~Caller() { delBase(); } + void set(Base *b) { delBase(); m_base = b; } + void reset() { m_base = 0; } + unsigned int UIntMethodCall(unsigned int x) { return m_base->UIntMethod(x); } + +private: + Base *m_base; + void delBase() { delete m_base; m_base = 0; } +}; +</PRE> +</DIV> +<P> The director feature is turned off by default and the following + simple interface file shows how directors are enabled for the class <TT> +Base</TT>.</P> +<DIV class="code"> +<PRE> +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%feature("director") Base; + +%include "example.h" +</PRE> +</DIV> +<P> The following is a C# class inheriting from <TT>Base</TT>:</P> +<DIV class="code"> +<PRE> +public class CSharpDerived : Base +{ + public override uint UIntMethod(uint x) + { + Console.WriteLine("CSharpDerived - UIntMethod({0})", x); + return x; + } +} +</PRE> +</DIV> +<P> The <TT>Caller</TT> class can demonstrate the <TT>UIntMethod</TT> + method being called from unmanaged code using the following C# code:</P> +<DIV class="targetlang"> +<PRE> +public class runme +{ + static void Main() + { + Caller myCaller = new Caller(); + + // Test pure C++ class + using (Base myBase = new Base()) + { + makeCalls(myCaller, myBase); + } + + // Test director / C# derived class + using (Base myBase = new CSharpDerived()) + { + makeCalls(myCaller, myBase); + } + } + + static void makeCalls(Caller myCaller, Base myBase) + { + myCaller.set(myBase); + myCaller.UIntMethodCall(123); + myCaller.reset(); + } +} +</PRE> +</DIV> +<P> If the above is run, the output is then:</P> +<DIV class="shell"> +<PRE> +Base - UIntMethod(123) +CSharpDerived - UIntMethod(123) +</PRE> +</DIV> +<H3><A name="csharp_directors_implementation"></A>18.5.2 Directors + implementation</H3> +<P> The previous section demonstrated a simple example where the virtual + <TT>UIntMethod</TT> method was called from C++ code, even when the + overridden method is implemented in C#. The intention of this section + is to gain an insight into how the director feature works. It shows the + generated code for the two virtual methods, <TT>UIntMethod</TT> and <TT> +BaseBoolMethod</TT>, when the director feature is enabled for the <TT> +Base</TT> class.</P> +<P> Below is the generated C# <TT>Base</TT> director class.</P> +<DIV class="code"> +<PRE> +using System; +using System.Runtime.InteropServices; + +public class Base : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal Base(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(Base obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~Base() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + examplePINVOKE.delete_Base(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public virtual uint UIntMethod(uint x) { + uint ret = examplePINVOKE.Base_UIntMethod(swigCPtr, x); + return ret; + } + + public virtual void BaseBoolMethod(Base b, bool flag) { + examplePINVOKE.Base_BaseBoolMethod(swigCPtr, Base.getCPtr(b), flag); + if (examplePINVOKE.SWIGPendingException.Pending) + throw examplePINVOKE.SWIGPendingException.Retrieve(); + } + + public Base() : this(examplePINVOKE.new_Base(), true) { + SwigDirectorConnect(); + } + + private void SwigDirectorConnect() { + if (SwigDerivedClassHasMethod("UIntMethod", swigMethodTypes0)) + swigDelegate0 = new SwigDelegateBase_0(SwigDirectorUIntMethod); + if (SwigDerivedClassHasMethod("BaseBoolMethod", swigMethodTypes1)) + swigDelegate1 = new SwigDelegateBase_1(SwigDirectorBaseBoolMethod); + examplePINVOKE.Base_director_connect(swigCPtr, swigDelegate0, swigDelegate1); + } + + private bool SwigDerivedClassHasMethod(string methodName, Type[] methodTypes) { + System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, methodTypes); + bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(Base)); + return hasDerivedMethod; + } + + private uint SwigDirectorUIntMethod(uint x) { + return UIntMethod(x); + } + + private void SwigDirectorBaseBoolMethod(IntPtr b, bool flag) { + BaseBoolMethod(new Base(b, false), flag); + } + + internal delegate uint SwigDelegateBase_0(uint x); + internal delegate void SwigDelegateBase_1(IntPtr b, bool flag); + + private SwigDelegateBase_0 swigDelegate0; + private SwigDelegateBase_1 swigDelegate1; + + private static Type[] swigMethodTypes0 = new Type[] { typeof(uint) }; + private static Type[] swigMethodTypes1 = new Type[] { typeof(Base), typeof(bool) }; +} +</PRE> +</DIV> +<P> Everything from the <TT>SwigDirectorConnect()</TT> method and below + is code that is only generated when directors are enabled. The design + comprises a C# delegate being initialised for each virtual method on + construction of the class. Let's examine the <TT>BaseBoolMethod</TT>.</P> +<P> In the <TT>Base</TT> constructor a call is made to <TT> +SwigDirectorConnect()</TT> which contains the initialisation code for + all the virtual methods. It uses a support method, <TT> +SwigDerivedClassHasMethod()</TT>, which simply uses reflection to + determine if the named method, BaseBoolMethod, with the list of + required parameter types, exists in a subclass. If it does not exist, + the delegate is not initialised as there is no need for unmanaged code + to call back into managed C# code. However, if there is an overridden + method in any subclass, the delegate is required. It is then + initialised to the <TT>SwigDirectorBaseBoolMethod</TT> which in turn + will call <TT>BaseBoolMethod</TT> if invoked. The delegate is not + initialised to the <TT>BaseBoolMethod</TT> directly as quite often + types will need marshalling from the unmanaged type to the managed type + in which case an intermediary method (<TT>SwigDirectorBaseBoolMethod</TT> +) is required for the marshalling. In this case, the C# <TT>Base</TT> + class needs to be created from the unmanaged <TT>IntPtr</TT> type.</P> +<P> The last thing that <TT>SwigDirectorConnect()</TT> does is to pass + the delegates to the unmanaged code. It calls the intermediary method <TT> +Base_director_connect()</TT> which is really a call to the C function <TT> +CSharp_Base_director_connect()</TT>. This method simply maps each C# + delegate onto a C function pointer.</P> +<DIV class="code"> +<PRE> +SWIGEXPORT void SWIGSTDCALL CSharp_Base_director_connect(void *objarg, + SwigDirector_Base::SWIG_Callback0_t callback0, + SwigDirector_Base::SWIG_Callback1_t callback1) { + Base *obj = (Base *)objarg; + SwigDirector_Base *director = dynamic_cast<SwigDirector_Base *>(obj); + if (director) { + director->swig_connect_director(callback0, callback1); + } +} + +class SwigDirector_Base : public Base, public Swig::Director { +public: + SwigDirector_Base(); + virtual unsigned int UIntMethod(unsigned int x); + virtual ~SwigDirector_Base(); + virtual void BaseBoolMethod(Base const &b, bool flag); + + typedef unsigned int (SWIGSTDCALL* SWIG_Callback0_t)(unsigned int); + typedef void (SWIGSTDCALL* SWIG_Callback1_t)(void *, unsigned int); + void swig_connect_director(SWIG_Callback0_t callbackUIntMethod, + SWIG_Callback1_t callbackBaseBoolMethod); + +private: + SWIG_Callback0_t swig_callbackUIntMethod; + SWIG_Callback1_t swig_callbackBaseBoolMethod; + void swig_init_callbacks(); +}; + +void SwigDirector_Base::swig_connect_director(SWIG_Callback0_t callbackUIntMethod, + SWIG_Callback1_t callbackBaseBoolMethod) { + swig_callbackUIntMethod = callbackUIntMethod; + swig_callbackBaseBoolMethod = callbackBaseBoolMethod; +} +</PRE> +</DIV> +<P> Note that for each director class SWIG creates an unmanaged director + class for making the callbacks. For example <TT>Base</TT> has <TT> +SwigDirector_Base</TT> and <TT>SwigDirector_Base</TT> is derived from <TT> +Base</TT>. Should a C# class be derived from <TT>Base</TT>, the + underlying C++ <TT>SwigDirector_Base</TT> is created rather than <TT> +Base</TT>. The <TT>SwigDirector_Base</TT> class then implements all the + virtual methods, redirecting calls up to managed code if the + callback/delegate is non-zero. The implementation of <TT> +SwigDirector_Base::BaseBoolMethod</TT> shows this - the callback is made + by invoking the <TT>swig_callbackBaseBoolMethod</TT> function pointer:</P> +<DIV class="code"> +<PRE> +void SwigDirector_Base::BaseBoolMethod(Base const &b, bool flag) { + void * jb = 0 ; + unsigned int jflag ; + + if (!swig_callbackBaseBoolMethod) { + Base::BaseBoolMethod(b,flag); + return; + } else { + jb = (Base *) &b; + jflag = flag; + swig_callbackBaseBoolMethod(jb, jflag); + } +} +</PRE> +</DIV> +<H3><A name="csharp_director_caveats"></A>18.5.3 Director caveats</H3> +<P> There is a subtle gotcha with directors. If default parameters are + used, it is recommended to follow a pattern of always calling a single + method in any C# derived class. An example will clarify this and the + reasoning behind the recommendation. Consider the following C++ class + wrapped as a director class:</P> +<DIV class="code"> +<PRE> +class Defaults { +public: + virtual ~Defaults(); + virtual void DefaultMethod(int a=-100); +}; +</PRE> +</DIV> +<P> Recall that C++ methods with default parameters generate overloaded + methods for each defaulted parameter, so a C# derived class can be + created with two <TT>DefaultMethod</TT> override methods:</P> +<DIV class="code"> +<PRE> +public class CSharpDefaults : Defaults +{ + public override void DefaultMethod() + { + DefaultMethod(-100); // note C++ default value used + } + public override void DefaultMethod(int x) + { + } +} +</PRE> +</DIV> +<P> It may not be clear at first, but should a user intend to call <TT> +CSharpDefaults.DefaultMethod()</TT> from C++, a call is actually made to + <TT>CSharpDefaults.DefaultMethod(int)</TT>. This is because the initial + call is made in C++ and therefore the <TT>DefaultMethod(int)</TT> + method will be called as is expected with C++ calls to methods with + defaults, with the default being set to -100. The callback/delegate + matching this method is of course the overloaded method <TT> +DefaultMethod(int)</TT>. However, a call from C# to <TT> +CSharpDefaults.DefaultMethod()</TT> will of course call this exact + method and in order for behaviour to be consistent with calls from C++, + the implementation should pass the call on to <TT> +CSharpDefaults.DefaultMethod(int)</TT>using the C++ default value, as + shown above.</P> +<H2><A name="csharp_typemap_examples"></A>18.6 C# Typemap examples</H2> + This section includes a few examples of typemaps. For more examples, + you might look at the files "<TT>csharp.swg</TT>" and "<TT>typemaps.i</TT> +" in the SWIG library. +<H3><A name="csharp_memory_management_member_variables"></A>18.6.1 + Memory management when returning references to member variables</H3> +<P> This example shows how to prevent premature garbage collection of + objects when the underlying C++ class returns a pointer or reference to + a member variable. The example is a direct equivalent to this <A href="#java_memory_management_objects"> +Java equivalent</A>.</P> +<P> Consider the following C++ code:</P> +<DIV class="code"> +<PRE> +struct Wheel { + int size; + Wheel(int sz) : size(sz) {} +}; + +class Bike { + Wheel wheel; +public: + Bike(int val) : wheel(val) {} + Wheel& getWheel() { return wheel; } +}; +</PRE> +</DIV> +<P> and the following usage from C# after running the code through SWIG:</P> +<DIV class="code"> +<PRE> + Wheel wheel = new Bike(10).getWheel(); + Console.WriteLine("wheel size: " + wheel.size); + // Simulate a garbage collection + System.GC.Collect(); + System.GC.WaitForPendingFinalizers(); + Console.WriteLine("wheel size: " + wheel.size); +</PRE> +</DIV> +<P> Don't be surprised that if the resulting output gives strange + results such as...</P> +<DIV class="shell"> +<PRE> +wheel size: 10 +wheel size: 135019664 +</PRE> +</DIV> +<P> What has happened here is the garbage collector has collected the <TT> +Bike</TT> instance as it doesn't think it is needed any more. The proxy + instance, <TT>wheel</TT>, contains a reference to memory that was + deleted when the <TT>Bike</TT> instance was collected. In order to + prevent the garbage collector from collecting the <TT>Bike</TT> + instance a reference to the <TT>Bike</TT> must be added to the <TT> +wheel</TT> instance. You can do this by adding the reference when the <TT> +getWheel()</TT> method is called using the following typemaps.</P> +<DIV class="code"> +<PRE> +%typemap(cscode) Wheel %{ + // Ensure that the GC doesn't collect any Bike instance set from C# + private Bike bikeReference; + internal void addReference(Bike bike) { + bikeReference = bike; + } +%} + +// Add a C# reference to prevent premature garbage collection and resulting use +// of dangling C++ pointer. Intended for methods that return pointers or +// references to a member variable. +%typemap(csout, excode=SWIGEXCODE) Wheel& getWheel { + IntPtr cPtr = $imcall;$excode + $csclassname ret = null; + if (cPtr != IntPtr.Zero) { + ret = new $csclassname(cPtr, $owner); + ret.addReference(this); + } + return ret; + } +</PRE> +</DIV> +<P> The code in the first typemap gets added to the <TT>Wheel</TT> proxy + class. The code in the second typemap constitutes the bulk of the code + in the generated <TT>getWheel()</TT> function:</P> +<DIV class="code"> +<PRE> +public class Wheel : IDisposable { + ... + // Ensure that the GC doesn't collect any Bike instance set from C# + private Bike bikeReference; + internal void addReference(Bike bike) { + bikeReference = bike; + } +} + +public class Bike : IDisposable { + ... + public Wheel getWheel() { + IntPtr cPtr = examplePINVOKE.Bike_getWheel(swigCPtr); + Wheel ret = null; + if (cPtr != IntPtr.Zero) { + ret = new Wheel(cPtr, false); + ret.addReference(this); + } + return ret; + } +} +</PRE> +</DIV> +<P> Note the <TT>addReference</TT> call.</P> +<H3><A name="csharp_memory_management_objects"></A>18.6.2 Memory + management for objects passed to the C++ layer</H3> +<P> The example is a direct equivalent to this <A href="#java_memory_management_objects"> +Java equivalent</A>. Managing memory can be tricky when using C++ and C# + proxy classes. The previous example shows one such case and this + example looks at memory management for a class passed to a C++ method + which expects the object to remain in scope after the function has + returned. Consider the following two C++ classes:</P> +<DIV class="code"> +<PRE> +struct Element { + int value; + Element(int val) : value(val) {} +}; +class Container { + Element* element; +public: + Container() : element(0) {} + void setElement(Element* e) { element = e; } + Element* getElement() { return element; } +}; +</PRE> +</DIV> +<P> and usage from C++</P> +<DIV class="code"> +<PRE> + Container container; + Element element(20); + container.setElement(&element); + cout << "element.value: " << container.getElement()->value << endl; +</PRE> +</DIV> +<P> and more or less equivalent usage from C#</P> +<DIV class="code"> +<PRE> + Container container = new Container(); + Element element = new Element(20); + container.setElement(element); +</PRE> +</DIV> +<P> The C++ code will always print out 20, but the value printed out may + not be this in the C# equivalent code. In order to understand why, + consider a garbage collection occuring...</P> +<DIV class="code"> +<PRE> + Container container = new Container(); + Element element = new Element(20); + container.setElement(element); + Console.WriteLine("element.value: " + container.getElement().value); + // Simulate a garbage collection + System.GC.Collect(); + System.GC.WaitForPendingFinalizers(); + Console.WriteLine("element.value: " + container.getElement().value); +</PRE> +</DIV> +<P> The temporary element created with <TT>new Element(20)</TT> could + get garbage collected which ultimately means the <TT>container</TT> + variable is holding a dangling pointer, thereby printing out any old + random value instead of the expected value of 20. One solution is to + add in the appropriate references in the C# layer...</P> +<DIV class="code"> +<PRE> +public class Container : IDisposable { + + ... + + // Ensure that the GC doesn't collect any Element set from C# + // as the underlying C++ class stores a shallow copy + private Element elementReference; + private HandleRef getCPtrAndAddReference(Element element) { + elementReference = element; + return Element.getCPtr(element); + } + + public void setElement(Element e) { + examplePINVOKE.Container_setElement(swigCPtr, getCPtrAndAddReference(e)); + } +} +</PRE> +</DIV> +<P> The following typemaps will generate the desired code. The 'csin' + typemap matches the input parameter type for the <TT>setElement</TT> + method. The 'cscode' typemap simply adds in the specified code into the + C# proxy class.</P> +<DIV class="code"> +<PRE> +%typemap(csin) Element *e "getCPtrAndAddReference($csinput)" + +%typemap(cscode) Container %{ + // Ensure that the GC doesn't collect any Element set from C# + // as the underlying C++ class stores a shallow copy + private Element elementReference; + private HandleRef getCPtrAndAddReference(Element element) { + elementReference = element; + return Element.getCPtr(element); + } +%} +</PRE> +</DIV> +<H3><A name="csharp_date_marshalling"></A>18.6.3 Date marshalling using + the csin typemap and associated attributes</H3> +<P> The <A href="#nan_exception_typemap">NaN Exception example</A> is a + simple example of the "javain" typemap and its 'pre' attribute. This + example demonstrates how a C++ date class, say <TT>CDate</TT>, can be + mapped onto the standard .NET date class, <TT>System.DateTime</TT> by + using the 'pre', 'post' and 'pgcppname' attributes of the "csin" + typemap (the C# equivalent to the "javain" typemap). The example is an + equivalent to the <A href="#java_date_marshalling">Java Date + marshalling example</A>. The idea is that the <TT>System.DateTime</TT> + is used wherever the C++ API uses a <TT>CDate</TT>. Let's assume the + code being wrapped is as follows:</P> +<DIV class="code"> +<PRE> +class CDate { +public: + CDate(); + CDate(int year, int month, int day); + int getYear(); + int getMonth(); + int getDay(); + ... +}; +struct Action { + static int doSomething(const CDate &dateIn, CDate &dateOut); + Action(const CDate &date, CDate &dateOut); +}; +</PRE> +</DIV> +<P> Note that <TT>dateIn</TT> is const and therefore read only and <TT> +dateOut</TT> is a non-const output type.</P> +<P> First let's look at the code that is generated by default, where the + C# proxy class <TT>CDate</TT> is used in the proxy interface:</P> +<DIV class="code"> +<PRE> +public class Action : IDisposable { + ... + public Action(CDate dateIn, CDate dateOut) + : this(examplePINVOKE.new_Action(CDate.getCPtr(dateIn), CDate.getCPtr(dateOut)), true) { + if (examplePINVOKE.SWIGPendingException.Pending) + throw examplePINVOKE.SWIGPendingException.Retrieve(); + } + + public int doSomething(CDate dateIn, CDate dateOut) { + int ret = examplePINVOKE.Action_doSomething(swigCPtr, + CDate.getCPtr(dateIn), + CDate.getCPtr(dateOut)); + if (examplePINVOKE.SWIGPendingException.Pending) + throw examplePINVOKE.SWIGPendingException.Retrieve(); + return ret; + } +} +</PRE> +</DIV> +<P> The <TT>CDate &</TT> and <TT>const CDate &</TT> C# code is generated + from the following two default typemaps:</P> +<DIV class="code"> +<PRE> +%typemap(cstype) SWIGTYPE & "$csclassname" +%typemap(csin) SWIGTYPE & "$csclassname.getCPtr($csinput)" +</PRE> +</DIV> +<P> where '$csclassname' is translated into the proxy class name, <TT> +CDate</TT> and '$csinput' is translated into the name of the parameter, + eg <TT>dateIn</TT>. From C#, the intention is then to call into a + modifed API with something like:</P> +<DIV class="code"> +<PRE> +System.DateTime dateIn = new System.DateTime(2011, 4, 13); +System.DateTime dateOut = new System.DateTime(); + +// Note in calls below, dateIn remains unchanged and dateOut +// is set to a new value by the C++ call +Action action = new Action(dateIn, out dateOut); +dateIn = new System.DateTime(2012, 7, 14); +</PRE> +</DIV> +<P> To achieve this mapping, we need to alter the default code + generation slightly so that at the C# layer, a <TT>System.DateTime</TT> + is converted into a <TT>CDate</TT>. The intermediary layer will still + take a pointer to the underlying <TT>CDate</TT> class. The typemaps to + achieve this are shown below.</P> +<DIV class="code"> +<PRE> +%typemap(cstype) const CDate& "System.DateTime" +%typemap(csin, + pre=" CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);" + ) const CDate & + "$csclassname.getCPtr(temp$csinput)" + +%typemap(cstype) CDate& "out System.DateTime" +%typemap(csin, + pre=" CDate temp$csinput = new CDate();", + post=" $csinput = new System.DateTime(temp$csinput.getYear()," + " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", + cshin="out $csinput" + ) CDate & + "$csclassname.getCPtr(temp$csinput)" + +</PRE> +</DIV> +<P> The resulting generated proxy code in the <TT>Action</TT> class + follows:</P> +<DIV class="code"> +<PRE> +public class Action : IDisposable { + ... + public int doSomething(System.DateTime dateIn, out System.DateTime dateOut) { + CDate tempdateIn = new CDate(dateIn.Year, dateIn.Month, dateIn.Day); + CDate tempdateOut = new CDate(); + try { + int ret = examplePINVOKE.Action_doSomething(swigCPtr, + CDate.getCPtr(tempdateIn), + CDate.getCPtr(tempdateOut)); + if (examplePINVOKE.SWIGPendingException.Pending) + throw examplePINVOKE.SWIGPendingException.Retrieve(); + return ret; + } finally { + dateOut = new System.DateTime(tempdateOut.getYear(), + tempdateOut.getMonth(), tempdateOut.getDay(), 0, 0, 0); + } + } + + static private IntPtr SwigConstructAction(System.DateTime dateIn, out System.DateTime dateOut) { + CDate tempdateIn = new CDate(dateIn.Year, dateIn.Month, dateIn.Day); + CDate tempdateOut = new CDate(); + try { + return examplePINVOKE.new_Action(CDate.getCPtr(tempdateIn), CDate.getCPtr(tempdateOut)); + } finally { + dateOut = new System.DateTime(tempdateOut.getYear(), + tempdateOut.getMonth(), tempdateOut.getDay(), 0, 0, 0); + } + } + + public Action(System.DateTime dateIn, out System.DateTime dateOut) + : this(Action.SwigConstructAction(dateIn, out dateOut), true) { + if (examplePINVOKE.SWIGPendingException.Pending) + throw examplePINVOKE.SWIGPendingException.Retrieve(); + } +} +</PRE> +</DIV> +<P> A few things to note:</P> +<UL> +<LI> The "cstype" typemap has changed the parameter type to <TT> +System.DateTime</TT> instead of the default generated <TT>CDate</TT> + proxy.</LI> +<LI> The non-const <TT>CDate &</TT> type is marshalled as a reference + parameter in C# as the date cannot be explicitly set once the object + has been created, so a new object is created instead.</LI> +<LI> The code in the 'pre' attribute appears before the intermediary + call (<TT>examplePINVOKE.new_Action</TT> / <TT> +examplePINVOKE.Action_doSomething</TT>).</LI> +<LI> The code in the 'post' attribute appears after the intermediary + call.</LI> +<LI> A try .. finally block is generated with the intermediary call in + the try block and 'post' code in the finally block. The alternative of + just using a temporary variable for the return value from the + intermediary call and the 'post' code being inserted before the return + statement is not possible given that the intermediary call and method + return comes from a single source (the "csout" typemap).</LI> +<LI> The temporary variables in the "csin" typemaps are called <TT> +temp$csin</TT>, where "$csin" is replaced with the parameter name. + "$csin" is used to mangle the variable name so that more than one <TT> +CDate &</TT> type can be used as a parameter in a method, otherwise two + or more local variables with the same name would be generated.</LI> +<LI> The use of the "csin" typemap causes a constructor helper function + (<TT>SwigConstructAction</TT>) to be generated. This allows C# code to + be called before the intermediary call made in the constructor + initialization list.</LI> +<LI> The 'cshin' attribute is required for the <TT>SwigConstructAction</TT> + constructor helper function so that the 2nd parameter is declared as <TT> +out dateOut</TT> instead of just <TT>dateOut</TT>.</LI> +</UL> +<P> So far we have considered the date as an input only and an output + only type. Now let's consider <TT>CDate *</TT> used as an input/output + type. Consider the following C++ function which modifies the date + passed in:</P> +<DIV class="code"> +<PRE> +void addYears(CDate *pDate, int years) { + *pDate = CDate(pDate->getYear() + years, pDate->getMonth(), pDate->getDay()); +} +</PRE> +</DIV> +<P> If usage of <TT>CDate *</TT> commonly follows this input/output + pattern, usage from C# like the following</P> +<DIV class="code"> +<PRE> +System.DateTime christmasEve = new System.DateTime(2000, 12, 24); +example.addYears(ref christmasEve, 10); // christmasEve now contains 2010-12-24 +</PRE> +</DIV> +<P> will be possible with the following <TT>CDate *</TT> typemaps</P> +<DIV class="code"> +<PRE> +%typemap(cstype, out="System.DateTime") CDate * "ref System.DateTime" + +%typemap(csin, + pre=" CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);", + post=" $csinput = new System.DateTime(temp$csinput.getYear()," + " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", + cshin="ref $csinput" + ) CDate * + "$csclassname.getCPtr(temp$csinput)" +</PRE> +</DIV> +<P> Globals are wrapped by the module class and for a module called + example, the typemaps result in the following code:</P> +<DIV class="code"> +<PRE> +public class example { + public static void addYears(ref System.DateTime pDate, int years) { + CDate temppDate = new CDate(pDate.Year, pDate.Month, pDate.Day); + try { + examplePINVOKE.addYears(CDate.getCPtr(temppDate), years); + } finally { + pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(), 0, 0, 0); + } + } + ... +} +</PRE> +</DIV> +<P> The following typemap is the same as the previous but demonstrates + how a using block can be used for the temporary variable. The only + change to the previous typemap is the introduction of the 'terminator' + attribute to terminate the <TT>using</TT> block. The <TT>subtractYears</TT> + method is nearly identical to the above <TT>addYears</TT> method.</P> +<DIV class="code"> +<PRE> +%typemap(csin, + pre=" using (CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day)) {", + post=" $csinput = new System.DateTime(temp$csinput.getYear()," + " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", + terminator=" } // terminate temp$csinput using block", + cshin="ref $csinput" + ) CDate * + "$csclassname.getCPtr(temp$csinput)" + +void subtractYears(CDate *pDate, int years) { + *pDate = CDate(pDate->getYear() - years, pDate->getMonth(), pDate->getDay()); +} +</PRE> +</DIV> +<P> The resulting generated code shows the termination of the <TT>using</TT> + block:</P> +<DIV class="code"> +<PRE> +public class example { + public static void subtractYears(ref System.DateTime pDate, int years) { + using (CDate temppDate = new CDate(pDate.Year, pDate.Month, pDate.Day)) { + try { + examplePINVOKE.subtractYears(CDate.getCPtr(temppDate), years); + } finally { + pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(), 0, 0, 0); + } + } // terminate temppDate using block + } + ... +} +</PRE> +</DIV> +<H3><A name="csharp_date_properties"></A>18.6.4 A date example + demonstrating marshalling of C# properties</H3> +<P> The previous section looked at converting a C++ date class to <TT> +System.DateTime</TT> for parameters. This section extends this idea so + that the correct marshalling is obtained when wrapping C++ variables. + Consider the same <TT>CDate</TT> class from the previous section and a + global variable:</P> +<DIV class="code"> +<PRE> +CDate ImportantDate = CDate(1999, 12, 31); +</PRE> +</DIV> +<P> The aim is to use <TT>System.DateTime</TT> from C# when accessing + this date as shown in the following usage where the module name is + 'example':</P> +<DIV class="code"> +<PRE> +example.ImportantDate = new System.DateTime(2000, 11, 22); +System.DateTime importantDate = example.ImportantDate; +Console.WriteLine("Important date: " + importantDate); +</PRE> +</DIV> +<P> When SWIG wraps a variable that is a class/struct/union, it is + wrapped using a pointer to the type for the reasons given in <A href="#SWIG_structure_data_members"> +Stucture data members</A>. The typemap type required is thus <TT>CDate *</TT> +. Given that the previous section already designed <TT>CDate *</TT> + typemaps, we'll use those same typemaps plus the 'csvarin' and + 'csvarout' typemaps.<DIV class="code"> +<PRE> +%typemap(cstype, out="System.DateTime") CDate * "ref System.DateTime" + +%typemap(csin, + pre=" CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);", + post=" $csinput = new System.DateTime(temp$csinput.getYear()," + " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", + cshin="ref $csinput" + ) CDate * + "$csclassname.getCPtr(temp$csinput)" + +%typemap(csvarin, excode=SWIGEXCODE2) CDate * %{ + /* csvarin typemap code */ + set { + CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day); + $imcall;$excode + } %} + +%typemap(csvarout, excode=SWIGEXCODE2) CDate * %{ + /* csvarout typemap code */ + get { + IntPtr cPtr = $imcall; + CDate tempDate = (cPtr == IntPtr.Zero) ? null : new CDate(cPtr, $owner);$excode + return new System.DateTime(tempDate.getYear(), tempDate.getMonth(), tempDate.getDay(), + 0, 0, 0); + } %} +</PRE> +</DIV></P> +<P> For a module called example, the typemaps result in the following + code:</P> +<DIV class="code"> +<PRE> +public class example { + public static System.DateTime ImportantDate { + /* csvarin typemap code */ + set { + CDate tempvalue = new CDate(value.Year, value.Month, value.Day); + examplePINVOKE.ImportantDate_set(CDate.getCPtr(tempvalue)); + } + /* csvarout typemap code */ + get { + IntPtr cPtr = examplePINVOKE.ImportantDate_get(); + CDate tempDate = (cPtr == IntPtr.Zero) ? null : new CDate(cPtr, false); + return new System.DateTime(tempDate.getYear(), tempDate.getMonth(), tempDate.getDay(), + 0, 0, 0); + } + } + ... +} +</PRE> +</DIV> +<P> Some points to note:</P> +<UL> +<LI>The property set comes from the 'csvarin' typemap and the property + get comes from the 'csvarout' typemap.</LI> +<LI>The type used for the property comes from the 'cstype' typemap. This + particular example has the 'out' attribute set in the typemap and as it + is specified, it is used in preference to the type in the typemap body. + This is because the type in the 'out' attribute can never include + modifiers such as 'ref', thereby avoiding code such as <TT>public + static ref System.DateTime ImportantDate { ...</TT>, which would of + course not compile.</LI> +<LI>The <TT>$excode</TT> special variable expands to nothing as there + are no exception handlers specified in any of the unmanaged code + typemaps (in fact the marshalling was done using the default unmanaged + code typemaps.)</LI> +<LI>The <TT>$imcall</TT> typemap expands to the appropriate intermediary + method call in the <TT>examplePINVOKE</TT> class.</LI> +<LI>The <TT>$csinput</TT> special variable in the 'csin' typemap always + expands to <TT>value</TT> for properties. In this case <TT> +$csclassname.getCPtr(temp$csinput)</TT> expands to <TT> +CDate.getCPtr(tempvalue)</TT>.</LI> +<LI>The 'csin' typemap has 'pre', 'post' and 'cshin' attributes, and + these are all ignored in the property set. The code in these attributes + must instead be replicated within the 'csvarin' typemap. The line + creating the <TT>temp$csinput</TT> variable is such an example; it is + identical to what is in the 'pre' attribute.</LI> +</UL> +<H3><A name="csharp_partial_classes"></A>18.6.5 Turning wrapped classes + into partial classes</H3> +<P> C# supports the notion of partial classes whereby a class definition + can be split into more than one file. It is possible to turn the + wrapped C++ class into a partial C# class using the <TT> +csclassmodifiers</TT> typemap. Consider a C++ class called <TT>ExtendMe</TT> +:</P> +<DIV class="code"> +<PRE> +class ExtendMe { +public: + int Part1() { return 1; } +}; +</PRE> +</DIV> +<P> The default C# proxy class generated is:</P> +<DIV class="code"> +<PRE> +public class ExtendMe : IDisposable { + ... + public int Part1() { + ... + } +} +</PRE> +</DIV> +<P> The default csclassmodifiers typemap shipped with SWIG is</P> +<DIV class="code"> +<PRE> +%typemap(csclassmodifiers) SWIGTYPE "public class" +</PRE> +</DIV> +<P> Note that the type used is the special catch all type <TT>SWIGTYPE</TT> +. If instead we use the following typemap to override this for just the <TT> +ExtendMe</TT> class:</P> +<DIV class="code"> +<PRE> +%typemap(csclassmodifiers) ExtendMe "public partial class" +</PRE> +</DIV> +<P> The C# proxy class becomes a partial class:</P> +<DIV class="code"> +<PRE> +public partial class ExtendMe : IDisposable { + ... + public int Part1() { + ... + } +} +</PRE> +</DIV> +<P> You can then of course declare another part of the partial class + elsewhere, for example:</P> +<DIV class="code"> +<PRE> +public partial class ExtendMe : IDisposable { + public int Part2() { + return 2; + } +} +</PRE> +</DIV> +<P> and compile the following code:</P> +<DIV class="code"> +<PRE> +ExtendMe em = new ExtendMe(); +Console.WriteLine("part1: {0}", em.Part1()); +Console.WriteLine("part2: {0}", em.Part2()); +</PRE> +</DIV> +<P> demonstrating that the class contains methods calling both unmanaged + code - <TT>Part1()</TT> and managed code - <TT>Part2()</TT>. The + following example is an alternative approach to adding managed code to + the generated proxy class.</P> +<H3><A name="csharp_extending_proxy_class"></A>18.6.6 Extending proxy + classes with additional C# code</H3> +<P> The previous example showed how to use partial classes to add + functionality to a generated C# proxy class. It is also possible to + extend a wrapped struct/class with C/C++ code by using the <A href="#SWIGPlus_class_extension"> +%extend directive</A>. A third approach is to add some C# methods into + the generated proxy class with the <TT>cscode</TT> typemap. If we + declare the following typemap before SWIG parses the <TT>ExtendMe</TT> + class used in the previous example</P> +<DIV class="code"> +<PRE> +%typemap(cscode) ExtendMe %{ + public int Part3() { + return 3; + } +%} + +</PRE> +</DIV> +<P> The generated C# proxy class will instead be:</P> +<DIV class="code"> +<PRE> +public class ExtendMe : IDisposable { + ... + public int Part3() { + return 3; + } + public int Part1() { + ... + } +} +</PRE> +</DIV><HR NOSHADE> + +<!-- Hand-written HTML --> +<H1><A name="Chicken"></A>19 SWIG and Chicken</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Chicken_nn2">Preliminaries</A> +<UL> +<LI><A href="#Chicken_nn3">Running SWIG in C mode</A></LI> +<LI><A href="#Chicken_nn4">Running SWIG in C++ mode</A></LI> +</UL> +</LI> +<LI><A href="#Chicken_nn5">Code Generation</A> +<UL> +<LI><A href="#Chicken_nn6">Naming Conventions</A></LI> +<LI><A href="#Chicken_nn7">Modules</A></LI> +<LI><A href="#Chicken_nn8">Constants and Variables</A></LI> +<LI><A href="#Chicken_nn9">Functions</A></LI> +<LI><A href="#Chicken_nn10">Exceptions</A></LI> +</UL> +</LI> +<LI><A href="#Chicken_nn11">TinyCLOS</A></LI> +<LI><A href="#Chicken_nn12">Linkage</A> +<UL> +<LI><A href="#Chicken_nn13">Static binary or shared library linked at + compile time</A></LI> +<LI><A href="#Chicken_nn14">Building chicken extension libraries</A></LI> +<LI><A href="#Chicken_nn15">Linking multiple SWIG modules with TinyCLOS</A> +</LI> +</UL> +</LI> +<LI><A href="#Chicken_nn16">Typemaps</A></LI> +<LI><A href="#Chicken_nn17">Pointers</A> +<UL> +<LI><A href="#collection">Garbage collection</A></LI> +</UL> +</LI> +<LI><A href="#Chicken_nn18">Unsupported features and known problems</A> +<UL> +<LI><A href="#Chicken_nn19">TinyCLOS problems with Chicken version <= + 1.92</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes SWIG's support of CHICKEN. CHICKEN is a + Scheme-to-C compiler supporting most of the language features as + defined in the<I> Revised^5 Report on Scheme</I>. Its main attributes + are that it</P> +<OL> +<LI>generates portable C code</LI> +<LI>includes a customizable interpreter</LI> +<LI>links to C libraries with a simple Foreign Function Interface</LI> +<LI>supports full tail-recursion and first-class continuations</LI> +</OL> +<P> When confronted with a large C library, CHICKEN users can use SWIG + to generate CHICKEN wrappers for the C library. However, the real + advantages of using SWIG with CHICKEN are its<STRONG> support for C++</STRONG> + -- object-oriented code is difficult to wrap by hand in CHICKEN -- and + its<STRONG> typed pointer representation</STRONG>, essential for C and + C++ libraries involving structures or classes.</P> +<H2><A name="Chicken_nn2"></A>19.1 Preliminaries</H2> +<P> CHICKEN support was introduced to SWIG in version 1.3.18. SWIG + relies on some recent additions to CHICKEN, which are only present in + releases of CHICKEN with version number<STRONG> greater than or equal + to 1.89</STRONG>. To use a chicken version between 1.40 and 1.89, see + the <A href="#collection">Garbage collection</A> section below.</P> +<P> You may want to look at any of the examples in Examples/chicken/ or + Examples/GIFPlot/Chicken for the basic steps to run SWIG CHICKEN.</P> +<H3><A name="Chicken_nn3"></A>19.1.1 Running SWIG in C mode</H3> +<P> To run SWIG CHICKEN in C mode, use the -chicken option.</P> +<DIV class="shell"> +<PRE>% swig -chicken example.i</PRE> +</DIV> +<P> To allow the wrapper to take advantage of future CHICKEN code + generation improvements, part of the wrapper is direct CHICKEN function + calls (<TT>example_wrap.c</TT>) and part is CHICKEN Scheme (<TT> +example.scm</TT>). The basic Scheme code must be compiled to C using + your system's CHICKEN compiler or both files can be compiled directly + using the much simpler <TT>csc</TT>.</P> +<DIV class="shell"> +<PRE> +% chicken example.scm -output-file oexample.c +</PRE> +</DIV> +<P> So for the C mode of SWIG CHICKEN, <TT>example_wrap.c</TT> and <TT> +oexample.c</TT> are the files that must be compiled to object files and + linked into your project.</P> +<H3><A name="Chicken_nn4"></A>19.1.2 Running SWIG in C++ mode</H3> +<P> To run SWIG CHICKEN in C++ mode, use the -chicken -c++ option.</P> +<DIV class="shell"> +<PRE>% swig -chicken -c++ example.i</PRE> +</DIV> +<P> This will generate <TT>example_wrap.cxx</TT> and <TT>example.scm</TT> +. The basic Scheme code must be compiled to C using your system's + CHICKEN compiler or both files can be compiled directly using the much + simpler <TT>csc</TT>.</P> +<DIV class="shell"> +<PRE>% chicken example.scm -output-file oexample.c</PRE> +</DIV> +<P> So for the C++ mode of SWIG CHICKEN, <TT>example_wrap.cxx</TT> and <TT> +oexample.c</TT> are the files that must be compiled to object files and + linked into your project.</P> +<H2><A name="Chicken_nn5"></A>19.2 Code Generation</H2> +<H3><A name="Chicken_nn6"></A>19.2.1 Naming Conventions</H3> +<P> Given a C variable, function or constant declaration named <TT> +Foo_Bar</TT>, the declaration will be available in CHICKEN as an + identifier ending with <TT>Foo-Bar</TT>. That is, an underscore is + converted to a dash.</P> +<P> You may control what the CHICKEN identifier will be by using the <TT> +%rename</TT> SWIG directive in the SWIG interface file.</P> +<H3><A name="Chicken_nn7"></A>19.2.2 Modules</H3> +<P> The name of the module must be declared one of two ways:</P> +<UL> +<LI>Placing <TT>%module example</TT> in the SWIG interface file.</LI> +<LI>Using <TT>-module example</TT> on the SWIG command line.</LI> +</UL> +<P> The generated example.scm file then exports <CODE>(declare (unit + modulename))</CODE>. If you do not want SWIG to export the <CODE> +(declare (unit modulename))</CODE>, pass the -nounit option to SWIG.</P> +<P> CHICKEN will be able to access the module using the <CODE>(declare + (uses<I> modulename</I>))</CODE> CHICKEN Scheme form.</P> +<H3><A name="Chicken_nn8"></A>19.2.3 Constants and Variables</H3> +<P> Constants may be created using any of the four constructs in the + interface file:</P> +<OL> +<LI><CODE>#define MYCONSTANT1 ...</CODE></LI> +<LI><CODE>%constant int MYCONSTANT2 = ...</CODE></LI> +<LI><CODE>const int MYCONSTANT3 = ...</CODE></LI> +<LI><CODE>enum { MYCONSTANT4 = ... };</CODE></LI> +</OL> +<P> In all cases, the constants may be accessed from within CHICKEN + using the form <TT>(MYCONSTANT1)</TT>; that is, the constants may be + accessed using the read-only parameter form.</P> +<P> Variables are accessed using the full parameter form. For example, + to set the C variable "int my_variable;", use the Scheme form <TT> +(my-variable 2345)</TT>. To get the C variable, use <TT>(my-variable)</TT> +.</P> +<P> The <TT>%feature("constasvar")</TT> can be applied to any constant + or immutable variable. Instead of exporting the constant as a function + that must be called, the constant will appear as a scheme variable. + This causes the generated .scm file to just contain the code <TT>(set! + MYCONSTANT1 (MYCONSTANT1))</TT>. See <A href="#features">Features and + the %feature directive</A> for info on how to apply the %feature.</P> +<H3><A name="Chicken_nn9"></A>19.2.4 Functions</H3> +<P> C functions declared in the SWIG interface file will have + corresponding CHICKEN Scheme procedures. For example, the C function + "int sqrt(double x);" will be available using the Scheme form <TT>(sqrt + 2345.0)</TT>. A <CODE>void</CODE> return value will give + C_SCHEME_UNDEFINED as a result.</P> +<P> A function may return more than one value by using the <CODE>OUTPUT</CODE> + specifier (see Lib/chicken/typemaps.i). They will be returned as + multiple values using <CODE>(values)</CODE> if there is more than one + result (that is, a non-void return value and at least one argout + parameter, or a void return value and at least two argout parameters). + The return values can then be accessed with <CODE>(call-with-values)</CODE> +.</P> +<H3><A name="Chicken_nn10"></A>19.2.5 Exceptions</H3> +<P>The SWIG chicken module has support for exceptions thrown from C or + C++ code to be caught in scheme. See <A href="#exception">Exception + handling with %exception</A> for more information about declaring + exceptions in the interface file.</P> +<P>Chicken supports both the <CODE>SWIG_exception(int code, const char + *msg)</CODE> interface as well as a <CODE>SWIG_ThrowException(C_word + val)</CODE> function for throwing exceptions from inside the %exception + blocks. <CODE>SWIG_exception</CODE> will throw a list consisting of the + code (as an integer) and the message. Both of these will throw an + exception using <CODE>(abort)</CODE>, which can be handled by <CODE> +(handle-exceptions)</CODE>. See <A href="http://www.call-with-current-continuation.org/manual/Exceptions.html#Exceptions"> +Chicken manual on Exceptions</A> and <A href="http://srfi.schemers.org/srfi-12/srfi-12.html"> +SFRI-12</A>. Since the exception values are thrown directly, if <CODE> +(condition-case)</CODE> is used to catch an exception the exception will + come through in the <CODE>val ()</CODE> case.</P> +<P>The following simple module</P> +<DIV class="code"> +<PRE> +%module exception_test + +%inline %{ + void test_throw(int i) throws (int) { + if (i == 1) throw 15; + } +%} +</PRE> +</DIV> +<P>could be run with</P> +<DIV class="targetlang"> +<PRE> +(handle-exceptions exvar + (if (= exvar 15) + (print "Correct!") + (print "Threw something else " exvar)) + (test-throw 1)) +</PRE> +</DIV> +<H2><A name="Chicken_nn11"></A>19.3 TinyCLOS</H2> +<P> The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as: + "Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a + metaobject protocol. The implementation is even simpler than the simple + CLOS found in `The Art of the Metaobject Protocol,' weighing in at + around 850 lines of code, including (some) comments and documentation."</P> +<P> Almost all good Scheme books describe how to use metaobjects and + generic procedures to implement an object-oriented Scheme system. + Please consult a Scheme book if you are unfamiliar with the concept.</P> +<P> CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN uses + if the -proxy argument is given. If -proxy is passed, then the + generated example.scm file will contain TinyCLOS class definitions. A + class named Foo is declared as <Foo>, and each member variable is + allocated a slot. Member functions are exported as generic functions.</P> +<P> Primitive symbols and functions (the interface that would be + presented if -proxy was not passed) are hidden and no longer + accessible. If the -unhideprimitive command line argument is passed to + SWIG, then the primitive symbols will be available, but each will be + prefixed by the string "primitive:"</P> +<P> The exported symbol names can be controlled with the -closprefix and + -useclassprefix arguments. If -useclassprefix is passed to SWIG, every + member function will be generated with the class name as a prefix. If + the -closprefix mymod: argument is passed to SWIG, then the exported + functions will be prefixed by the string "mymod:". If -useclassprefix + is passed, -closprefix is ignored.</P> +<H2><A name="Chicken_nn12"></A>19.4 Linkage</H2> +<P> Please refer to<EM> CHICKEN - A practical and portable Scheme system + - User's manual</EM> for detailed help on how to link object files to + create a CHICKEN Scheme program. Briefly, to link object files, be sure + to add <TT>`chicken-config -extra-libs -libs`</TT> or <TT> +`chicken-config -shared -extra-libs -libs`</TT>to your linker options. + Use the <TT>-shared</TT> option if you want to create a dynamically + loadable module. You might also want to use the much simpler <TT>csc</TT> + or <TT>csc.bat</TT>.</P> +<P>Each scheme file that is generated by SWIG contains <CODE>(declare + (uses<I> modname</I>))</CODE>. This means that to load the module from + scheme code, the code must include <CODE>(declare (uses<I> modname</I> +))</CODE>.</P> +<H3><A name="Chicken_nn13"></A>19.4.1 Static binary or shared library + linked at compile time</H3> +<P>We can easily use csc to build a static binary.</P> +<DIV class="shell"> +<PRE> +$ swig -chicken example.i +$ csc -v example.scm example_impl.c example_wrap.c test_script.scm -o example +$ ./example +</PRE> +</DIV> +<P>Similar to the above, any number of <TT>module.scm</TT> files could + be compiled into a shared library, and then that shared library linked + when compiling the main application.</P> +<DIV class="shell"> +<PRE> +$ swig -chicken example.i +$ csc -sv example.scm example_wrap.c example_impl.c -o example.so +</PRE> +</DIV> +<P>The <TT>example.so</TT> file can then linked with <TT>test_script.scm</TT> + when it is compiled, in which case <TT>test_script.scm</TT> must have <CODE> +(declare (uses example))</CODE>. Multiple SWIG modules could have been + linked into <TT>example.so</TT> and each one accessed with a <CODE> +(declare (uses ... ))</CODE>.</P> +<DIV class="shell"> +<PRE> +$ csc -v test_script.scm -lexample +</PRE> +</DIV> +<P>An alternative is that the test_script.scm can have the code <CODE> +(load-library 'example "example.so")</CODE>, in which case the test + script does not need to be linked with example.so. The test_script.scm + file can then be run with <TT>csi</TT>.</P> +<H3><A name="Chicken_nn14"></A>19.4.2 Building chicken extension + libraries</H3> +<P>Building a shared library like in the above section only works if the + library is linked at compile time with a script containing <CODE> +(declare (uses ...))</CODE> or is loaded explicitly with <CODE> +(load-library 'example "example.so")</CODE>. It is not the format that + CHICKEN expects for extension libraries and eggs. The problem is the <CODE> +(declare (unit<I> modname</I>))</CODE> inside the <TT>modname.scm</TT> + file. There are two possible solutions to this.</P> +<P>First, SWIG accepts a <TT>-nounit</TT> argument, in which case the <CODE> +(declare (unit<I> modname</I>))</CODE> is not generated. Then, the <TT> +modname.scm</TT> and <TT>modname_wrap.c</TT> files<B> must</B> be + compiled into their own shared library.</P> +<DIV class="shell"> +<PRE> +$ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so +</PRE> +</DIV> +<P>This library can then be loaded by scheme code with the <CODE> +(require 'modname)</CODE> function. See <A href="http://www.call-with-current-continuation.org/manual/Loading-extension-libraries.html"> + Loading-extension-libraries</A> in the eval unit inside the CHICKEN + manual for more information.</P> +<P>Another alternative is to run SWIG normally and create a scheme file + that contains <CODE>(declare (uses<I> modname</I>))</CODE> and then + compile that file into the shared library as well. For example, inside + the <TT>mod_load.scm</TT> file,</P> +<DIV class="targetlang"> +<PRE> +(declare (uses mod1)) +(declare (uses mod2)) +</PRE> +</DIV> +<P>Which would then be compiled with</P> +<DIV class="shell"> +<PRE> +$ swig -chicken mod1.i +$ swig -chicken mod2.i +$ csc -sv mod_load.scm mod1.scm mod2.scm mod1_wrap.c mod2_wrap.c mod1_impl.c mod2_impl.c -o mod.so +</PRE> +</DIV> +<P>Then the extension library can be loaded with <CODE>(require 'mod)</CODE> +. As we can see here, <TT>mod_load.scm</TT> contains the code that gets + executed when the module is loaded. All this code does is load both + mod1 and mod2. As we can see, this technique is more useful when you + want to combine a few SWIG modules into one chicken extension library, + especially if modules are related by <CODE>%import</CODE></P> +<P>In either method, the files that are compiled into the shared library + could also be packaged into an egg. The <TT>mod1_wrap.c</TT> and <TT> +mod2_wrap.c</TT> files that are created by SWIG are stand alone and do + not need SWIG to be installed to be compiled. Thus the egg could be + distributed and used by anyone, even if SWIG is not installed.</P> +<P>See the <TT>Examples/chicken/egg</TT> directory in the SWIG source + for an example that builds two eggs, one using the first method and one + using the second method.</P> +<H3><A name="Chicken_nn15"></A>19.4.3 Linking multiple SWIG modules with + TinyCLOS</H3> +<P>Linking together multiple modules that share type information using + the <CODE>%import</CODE> directive while also using <TT>-proxy</TT> is + more complicated. For example, if <TT>mod2.i</TT> imports <TT>mod1.i</TT> +, then the <TT>mod2.scm</TT> file contains references to symbols + declared in <TT>mod1.scm</TT>, and thus a <CODE>(declare (uses<I> mod1</I> +))</CODE> or <CODE>(require '<I>mod1</I>)</CODE> must be exported to the + top of <TT>mod2.scm</TT>. By default, when SWIG encounters an <CODE> +%import "modname.i"</CODE> directive, it exports <CODE>(declare (uses<I> + modname</I>))</CODE> into the scm file. This works fine unless mod1 was + compiled with the <TT>-nounit</TT> argument or was compiled into an + extension library with other modules under a different name.</P> +<P>One option is to override the automatic generation of <CODE>(declare + (uses mod1))</CODE> by passing the <TT>-noclosuses</TT> option to SWIG + when compiling <TT>mod2.i</TT>. SWIG then provides the <CODE> +%insert(closprefix) %{ %}</CODE> directive. Any scheme code inside that + directive is inserted into the generated .scm file, and if <TT>mod1</TT> + was compiled with <TT>-nounit</TT>, the directive should contain <CODE> +(require 'mod1)</CODE>. This option allows for mixed loading as well, + where some modules are imported with <CODE>(declare (uses<I> modname</I> +))</CODE> (which means they were compiled without -nounit) and some are + imported with <CODE>(require 'modname)</CODE>.</P> +<P>The other option is to use the second idea in the above section. + Compile all the modules normally, without any <CODE>%insert(closprefix)</CODE> +, <TT>-nounit</TT>, or <TT>-noclosuses</TT>. Then the modules will + import each other correctly with <CODE>(declare (uses ...))</CODE>. To + create an extension library or an egg, just create a <TT> +module_load.scm</TT> file that <CODE>(declare (uses ...))</CODE> all the + modules.</P> +<H2><A name="Chicken_nn16"></A>19.5 Typemaps</H2> +<P> The Chicken module handles all types via typemaps. This information + is read from <CODE>Lib/chicken/typemaps.i</CODE> and <CODE> +Lib/chicken/chicken.swg</CODE>.</P> +<H2><A name="Chicken_nn17"></A>19.6 Pointers</H2> +<P> For pointer types, SWIG uses CHICKEN tagged pointers. A tagged + pointer is an ordinary CHICKEN pointer with an extra slot for a void *. + With SWIG CHICKEN, this void * is a pointer to a type-info structure. + So each pointer used as input or output from the SWIG-generated CHICKEN + wrappers will have type information attached to it. This will let the + wrappers correctly determine which method should be called according to + the object type hierarchy exposed in the SWIG interface files.</P> +<P> To construct a Scheme object from a C pointer, the wrapper code + calls the function <CODE>SWIG_NewPointerObj(void *ptr, swig_type_info + *type, int owner)</CODE>, The function that calls <CODE> +SWIG_NewPointerObj</CODE> must have a variable declared <CODE>C_word + *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);</CODE> It is ok to call <CODE> +SWIG_NewPointerObj</CODE> more than once, just make sure known_space has + enough space for all the created pointers.</P> +<P> To get the pointer represented by a CHICKEN tagged pointer, the + wrapper code calls the function <CODE>SWIG_ConvertPtr(C_word s, void + **result, swig_type_info *type, int flags)</CODE>, passing a pointer to + a struct representing the expected pointer type. flags is either zero + or SWIG_POINTER_DISOWN (see below).</P> +<H3><A name="collection"></A>19.6.1 Garbage collection</H3> +<P>If the owner flag passed to <CODE>SWIG_NewPointerObj</CODE> is 1, <CODE> +NewPointerObj</CODE> will add a finalizer to the type which will call + the destructor or delete method of that type. The destructor and delete + functions are no longer exported for use in scheme code, instead SWIG + and chicken manage pointers. In situations where SWIG knows that a + function is returning a type that should be garbage collected, SWIG + will automatically set the owner flag to 1. For other functions, the <CODE> +%newobject</CODE> directive must be specified for functions whose return + values should be garbage collected. See <A href="#ownership">Object + ownership and %newobject</A> for more information.</P> +<P>In situations where a C or C++ function will assume ownership of a + pointer, and thus chicken should no longer garbage collect it, SWIG + provides the <CODE>DISOWN</CODE> input typemap. After applying this + typemap (see the <A href="Typemaps.html">Typemaps chapter</A> for more + information on how to apply typemaps), any pointer that gets passed in + will no longer be garbage collected. An object is disowned by passing + the <CODE>SWIG_POINTER_DISOWN</CODE> flag to <CODE>SWIG_ConvertPtr</CODE> +.<B> Warning:</B> Since the lifetime of the object is now controlled by + the underlying code, the object might get deleted while the scheme code + still holds a pointer to it. Further use of this pointer can lead to a + crash.</P> +<P>Adding a finalizer function from C code was added to chicken in the + 1.89 release, so garbage collection does not work for chicken versions + below 1.89. If you would like the SWIG generated code to work with + chicken 1.40 to 1.89, pass the <CODE>-nocollection</CODE> argument to + SWIG. This will not export code inside the _wrap.c file to register + finalizers, and will then export destructor functions which must be + called manually.</P> +<H2><A name="Chicken_nn18"></A>19.7 Unsupported features and known + problems</H2> +<UL> +<LI>No director support.</LI> +<LI>No support for c++ standard types like std::vector.</LI> +<LI>The TinyCLOS wrappers for overloaded functions will not work + correctly when using <A href="#SWIGPlus_default_args"> +%feature(compactdefaultargs)</A>.</LI> +</UL> +<H3><A name="Chicken_nn19"></A>19.7.1 TinyCLOS problems with Chicken + version <= 1.92</H3> +<P>In Chicken versions equal to or below 1.92, TinyCLOS has a limitation + such that generic methods do not properly work on methods with + different number of specializers: TinyCLOS assumes that every method + added to a generic function will have the same number of specializers. + SWIG generates functions with different lengths of specializers when + C/C++ functions are overloaded. For example, the code</P> +<DIV class="code"> +<PRE> +class Foo {}; +int foo(int a, Foo *b); +int foo(int a); +</PRE> +</DIV> +<P>will produce scheme code</P> +<DIV class="targetlang"> +<PRE> +(define-method (foo (arg0 <top>) (arg1 <Foo>)) (<I>call primitive function</I>)) +(define-method (foo (arg0 <top>)) (<I>call primitive function</I>)) +</PRE> +</DIV> +<P>Using unpatched TinyCLOS, the second <CODE>(define-method)</CODE> + will replace the first one, so calling <CODE>(foo 3 f)</CODE> will + produce an error.</P> +<P>There are three solutions to this. The easist is to upgrade to the + latest Chicken version. Otherwise, the file <TT> +Lib/chicken/tinyclos-multi-generic.patch</TT> in the SWIG source + contains a patch against tinyclos.scm inside the 1.92 chicken source to + add support into TinyCLOS for multi-argument generics. (This patch was + accepted into Chicken) This requires chicken to be rebuilt and custom + install of chicken. An alternative is the <TT> +Lib/chicken/multi-generic.scm</TT> file in the SWIG source. This file + can be loaded after TinyCLOS is loaded, and it will override some + functions inside TinyCLOS to correctly support multi-argument generics. + Please see the comments at the top of both files for more information.</P> +<HR NOSHADE> + +<!-- Hand-written HTML --> +<H1><A name="Guile"></A>20 SWIG and Guile</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Guile_nn2">Meaning of "Module"</A></LI> +<LI><A href="#Guile_nn3">Using the SCM or GH Guile API</A></LI> +<LI><A href="#Guile_nn4">Linkage</A> +<UL> +<LI><A href="#Guile_nn5">Simple Linkage</A></LI> +<LI><A href="#Guile_nn6">Passive Linkage</A></LI> +<LI><A href="#Guile_nn7">Native Guile Module Linkage</A></LI> +<LI><A href="#Guile_nn8">Old Auto-Loading Guile Module Linkage</A></LI> +<LI><A href="#Guile_nn9">Hobbit4D Linkage</A></LI> +</UL> +</LI> +<LI><A href="#Guile_nn10">Underscore Folding</A></LI> +<LI><A href="#Guile_nn11">Typemaps</A></LI> +<LI><A href="#Guile_nn12">Representation of pointers as smobs</A> +<UL> +<LI><A href="#Guile_nn13">GH Smobs</A></LI> +<LI><A href="#Guile_nn14">SCM Smobs</A></LI> +<LI><A href="#Guile_nn15">Garbage Collection</A></LI> +</UL> +</LI> +<LI><A href="#Guile_nn16">Exception Handling</A></LI> +<LI><A href="#Guile_nn17">Procedure documentation</A></LI> +<LI><A href="#Guile_nn18">Procedures with setters</A></LI> +<LI><A href="#Guile_nn19">GOOPS Proxy Classes</A> +<UL> +<LI><A href="#Guile_nn20">Naming Issues</A></LI> +<LI><A href="#Guile_nn21">Linking</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This section details guile-specific support in SWIG.</P> +<H2><A name="Guile_nn2"></A>20.1 Meaning of "Module"</H2> +<P> There are three different concepts of "module" involved, defined + separately for SWIG, Guile, and Libtool. To avoid horrible confusion, + we explicitly prefix the context, e.g., "guile-module".</P> +<H2><A name="Guile_nn3"></A>20.2 Using the SCM or GH Guile API</H2> +<P>The guile module can currently export wrapper files that use the + guile GH interface or the SCM interface. This is controlled by an + argument passed to swig. The "-gh" argument causes swig to output GH + code, and the "-scm" argument causes swig to output SCM code. Right now + the "-scm" argument is the default. The "-scm" wrapper generation + assumes a guile version >= 1.6 and has several advantages over the + "-gh" wrapper generation including garbage collection and GOOPS + support. The "-gh" wrapper generation can be used for older versions of + guile. The guile GH wrapper code generation is depreciated and the SCM + interface is the default. The SCM and GH interface differ greatly in + how they store pointers and have completely different run-time code. + See below for more info.</P> +<P>The GH interface to guile is deprecated. Read more about why in the <A +href="http://www.gnu.org/software/guile/docs/guile-ref/GH-deprecation.html"> +Guile manual</A>. The idea of the GH interface was to provide a high + level API that other languages and projects could adopt. This was a + good idea, but didn't pan out well for general development. But for the + specific, minimal uses that the SWIG typemaps put the GH interface to + use is ideal for using a high level API. So even though the GH + interface is depreciated, SWIG will continue to use the GH interface + and provide mappings from the GH interface to whatever API we need. We + can maintain this mapping where guile failed because SWIG uses a small + subset of all the GH functions which map easily. All the guile typemaps + like typemaps.i and std_vector.i will continue to use the GH functions + to do things like create lists of values, convert strings to integers, + etc. Then every language module will define a mapping between the GH + interface and whatever custom API the language uses. This is currently + implemented by the guile module to use the SCM guile API rather than + the GH guile API. For example, here are some of the current mapping + file for the SCM API</P> +<DIV class="code"> +<PRE> + +#define gh_append2(a, b) scm_append(scm_listify(a, b, SCM_UNDEFINED)) +#define gh_apply(a, b) scm_apply(a, b, SCM_EOL) +#define gh_bool2scm SCM_BOOL +#define gh_boolean_p SCM_BOOLP +#define gh_car SCM_CAR +#define gh_cdr SCM_CDR +#define gh_cons scm_cons +#define gh_double2scm scm_make_real +... +</PRE> +</DIV> +<P>This file is parsed by SWIG at wrapper generation time, so every + reference to a gh_ function is replaced by a scm_ function in the + wrapper file. Thus the gh_ function calls will never be seen in the + wrapper; the wrapper will look exactly like it was generated for the + specific API. Currently only the guile language module has created a + mapping policy from gh_ to scm_, but there is no reason other languages + (like mzscheme or chicken) couldn't also use this. If that happens, + there is A LOT less code duplication in the standard typemaps.</P> +<H2><A name="Guile_nn4"></A>20.3 Linkage</H2> +<P> Guile support is complicated by a lack of user community + cohesiveness, which manifests in multiple shared-library usage + conventions. A set of policies implementing a usage convention is + called a<B> linkage</B>.</P> +<H3><A name="Guile_nn5"></A>20.3.1 Simple Linkage</H3> +<P> The default linkage is the simplest; nothing special is done. In + this case the function <CODE>SWIG_init()</CODE> is exported. Simple + linkage can be used in several ways:</P> +<UL> +<LI><B>Embedded Guile, no modules.</B> You want to embed a Guile + interpreter into your program; all bindings made by SWIG shall show up + in the root module. Then call <CODE>SWIG_init()</CODE> in the <CODE> +inner_main()</CODE> function. See the "simple" and "matrix" examples + under <CODE>Examples/guile</CODE>.</LI> +<LI> +<P><B>Dynamic module mix-in.</B> You want to create a Guile module using + <CODE>define-module</CODE>, containing both Scheme code and bindings + made by SWIG; you want to load the SWIG modules as shared libraries + into Guile.</P> +<DIV class="targetlang"> +<PRE> +(define-module (my module)) +(define my-so (dynamic-link "./example.so")) +(dynamic-call "SWIG_init" my-so) ; make SWIG bindings +;; Scheme definitions can go here +</PRE> +</DIV> +<P> Newer Guile versions provide a shorthand for <CODE>dynamic-link</CODE> + and <CODE>dynamic-call</CODE>:</P> +<DIV class="targetlang"> +<PRE> +(load-extension "./example.so" "SWIG_init") +</PRE> +</DIV> +<P> You need to explicitly export those bindings made by SWIG that you + want to import into other modules:</P> +<DIV class="targetlang"> +<PRE> +(export foo bar) +</PRE> +</DIV> +<P> In this example, the procedures <CODE>foo</CODE> and <CODE>bar</CODE> + would be exported. Alternatively, you can export all bindings with the + following module-system hack:</P> +<DIV class="targetlang"> +<PRE> +(module-map (lambda (sym var) + (module-export! (current-module) (list sym))) + (current-module)) +</PRE> +</DIV> +<P>SWIG can also generate this Scheme stub (from <CODE>define-module</CODE> + up to <CODE>export</CODE>) semi-automagically if you pass it the + command-line argument <CODE>-scmstub</CODE>. The code will be exported + in a file called <CODE><I>module</I>.scm</CODE> in the directory + specified by <CODE>-outdir</CODE> or the current directory if <CODE> +-outdir</CODE> is not specified. Since SWIG doesn't know how to load + your extension module (with <CODE>dynamic-link</CODE> or <CODE> +load-extension</CODE>), you need to supply this information by including + a directive like this in the interface file:</P> +<DIV class="code"> +<PRE> +%scheme %{ (load-extension "./example.so" "SWIG_init") %} +</PRE> +</DIV> +<P> (The <CODE>%scheme</CODE> directive allows to insert arbitrary + Scheme code into the generated file <CODE><VAR>module.scm</VAR></CODE>; + it is placed between the <CODE>define-module</CODE> form and the <CODE> +export</CODE> form.)</P> +</LI> +</UL> +<P>If you want to include several SWIG modules, you would need to rename + <CODE>SWIG_init</CODE> via a preprocessor define to avoid symbol + clashes. For this case, however, passive linkage is available.</P> +<H3><A name="Guile_nn6"></A>20.3.2 Passive Linkage</H3> +<P>Passive linkage is just like simple linkage, but it generates an + initialization function whose name is derived from the module and + package name (see below).</P> +<P>You should use passive linkage rather than simple linkage when you + are using multiple modules.</P> +<H3><A name="Guile_nn7"></A>20.3.3 Native Guile Module Linkage</H3> +<P>SWIG can also generate wrapper code that does all the Guile module + declarations on its own if you pass it the <CODE>-Linkage module</CODE> + command-line option. This requires Guile 1.5.0 or later.</P> +<P>The module name is set with the <CODE>-package</CODE> and <CODE> +-module</CODE> command-line options. Suppose you want to define a module + with name <CODE>(my lib foo)</CODE>; then you would have to pass the + options <CODE>-package<VAR> my</VAR>/<VAR>lib</VAR> -module<VAR> foo</VAR> +</CODE>. Note that the last part of the name can also be set via the + SWIG directive <CODE>%module</CODE>.</P> +<P>You can use this linkage in several ways:</P> +<UL> +<LI><B>Embedded Guile with SWIG modules.</B> You want to embed a Guile + interpreter into your program; the SWIG bindings shall be put into + different modules. Simply call the function <CODE>scm_init_<VAR>my</VAR> +_<VAR>modules</VAR>_<VAR>foo</VAR>_module</CODE> in the <CODE> +inner_main()</CODE> function.</LI> +<LI><B>Dynamic Guile modules.</B> You want to load the SWIG modules as + shared libraries into Guile; all bindings are automatically put in + newly created Guile modules.<DIV class="targetlang"> +<PRE> +(define my-so (dynamic-link "./foo.so")) +;; create new module and put bindings there: +(dynamic-call "scm_init_my_modules_foo_module" my-so) +</PRE> +</DIV> Newer Guile versions have a shorthand procedure for this:<DIV class="targetlang"> +<PRE> +(load-extension "./foo.so" "scm_init_my_modules_foo_module") +</PRE> +</DIV></LI> +</UL> +<H3><A name="Guile_nn8"></A>20.3.4 Old Auto-Loading Guile Module Linkage</H3> +<P>Guile used to support an autoloading facility for object-code + modules. This support has been marked deprecated in version 1.4.1 and + is going to disappear sooner or later. SWIG still supports building + auto-loading modules if you pass it the <CODE>-Linkage ltdlmod</CODE> + command-line option.</P> +<P>Auto-loading worked like this: Suppose a module with name <CODE>(my + lib foo)</CODE> is required and not loaded yet. Guile will then search + all directories in its search path for a Scheme file <CODE> +my/modules/foo.scm</CODE> or a shared library <CODE><VAR>my</VAR>/<VAR> +modules</VAR>/lib<VAR>foo</VAR>.so</CODE> (or <CODE><VAR>my</VAR>/<VAR> +modules</VAR>/lib<VAR>foo</VAR>.la</CODE>; see the GNU libtool + documentation). If a shared library is found that contains the symbol <CODE> +scm_init_<VAR>my</VAR>_<VAR>modules</VAR>_<VAR>foo</VAR>_module</CODE>, + the library is loaded, and the function at that symbol is called with + no arguments in order to initialize the module.</P> +<P>When invoked with the <CODE>-Linkage ltdlmod</CODE> command-line + option, SWIG generates an exported module initialization function with + an appropriate name.</P> +<H3><A name="Guile_nn9"></A>20.3.5 Hobbit4D Linkage</H3> +<P> The only other linkage supported at this time creates shared object + libraries suitable for use by hobbit's <CODE>(hobbit4d link)</CODE> + guile module. This is called the "hobbit" linkage, and requires also + using the "-package" command line option to set the part of the module + name before the last symbol. For example, both command lines:</P> +<DIV class="shell"> +<PRE> +swig -guile -package my/lib foo.i +swig -guile -package my/lib -module foo foo.i +</PRE> +</DIV> +<P> would create module <CODE>(my lib foo)</CODE> (assuming in the first + case foo.i declares the module to be "foo"). The installed files are + my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very + experimental; the (hobbit4d link) conventions are not well understood.</P> +<H2><A name="Guile_nn10"></A>20.4 Underscore Folding</H2> +<P> Underscores are converted to dashes in identifiers. Guile support + may grow an option to inhibit this folding in the future, but no one + has complained so far.</P> +<P>You can use the SWIG directives <CODE>%name</CODE> and <CODE>%rename</CODE> + to specify the Guile name of the wrapped functions and variables (see + CHANGES).</P> +<H2><A name="Guile_nn11"></A>20.5 Typemaps</H2> +<P> The Guile module handles all types via typemaps. This information is + read from <CODE>Lib/guile/typemaps.i</CODE>. Some non-standard typemap + substitutions are supported:</P> +<UL> +<LI><CODE>$descriptor</CODE> expands to a type descriptor for use with + the <CODE>SWIG_NewPointerObj()</CODE> and <CODE>SWIG_ConvertPtr</CODE> + functions.</LI> +<LI>For pointer types, <CODE>$*descriptor</CODE> expands to a descriptor + for the direct base type (i.e., one pointer is stripped), whereas <CODE> +$basedescriptor</CODE> expands to a descriptor for the base type (i.e., + all pointers are stripped).</LI> +</UL> +<P>A function returning <CODE>void</CODE> (more precisely, a function + whose <CODE>out</CODE> typemap returns <CODE>SCM_UNSPECIFIED</CODE>) is + treated as returning no values. In <CODE>argout</CODE> typemaps, one + can use the macro <CODE>GUILE_APPEND_RESULT</CODE> in order to append a + value to the list of function return values.</P> +<P>Multiple values can be passed up to Scheme in one of three ways:</P> +<UL> +<LI> +<P><EM>Multiple values as lists.</EM> By default, if more than one value + is to be returned, a list of the values is created and returned; to + switch back to this behavior, use</P> +<DIV class="code"> +<PRE> +%values_as_list;</PRE> +</DIV></LI> +<LI> +<P><EM>Multiple values as vectors.</EM> By issuing</P> +<DIV class="code"> +<PRE> +%values_as_vector;</PRE> +</DIV> +<P> vectors instead of lists will be used.</P> +</LI> +<LI> +<P><EM>Multiple values for multiple-value continuations.</EM><STRONG> + This is the most elegant way.</STRONG> By issuing</P> +<DIV class="code"> +<PRE> +%multiple_values;</PRE> +</DIV> +<P> multiple values are passed to the multiple-value continuation, as + created by <CODE>call-with-values</CODE> or the convenience macro <CODE> +receive</CODE>. The latter is available if you issue <CODE>(use-modules + (srfi srfi-8))</CODE>. Assuming that your <CODE>divide</CODE> function + wants to return two values, a quotient and a remainder, you can write:</P> +<DIV class="targetlang"> +<PRE> +(receive (quotient remainder) + (divide 35 17) + <VAR>body</VAR>...) +</PRE> +</DIV> +<P> In <CODE><VAR>body</VAR></CODE>, the first result of <CODE>divide</CODE> + will be bound to the variable <CODE>quotient</CODE>, and the second + result to <CODE>remainder</CODE>.</P> +</LI> +</UL> +<P> See also the "multivalue" example.</P> +<P>Constants are exported as a function that returns the value. The + %feature("constasvar") can be applied to any constant, immutable + variable, or enum. Instead of exporting the constant as a function that + must be called, the constant will appear as a scheme variable. See <A href="#features"> +Features and the %feature directive</A> for info on how to apply the + %feature.</P> +<H2><A name="Guile_nn12"></A>20.6 Representation of pointers as smobs</H2> +<P> For pointer types, SWIG uses Guile smobs. SWIG smobs print like + this: <CODE>#<swig struct xyzzy * 0x1234affe></CODE> Two of them are <CODE> +equal?</CODE> if and only if they have the same type and value.</P> +<P> To construct a Scheme object from a C pointer, the wrapper code + calls the function <CODE>SWIG_NewPointerObj()</CODE>, passing a pointer + to a struct representing the pointer type. The type index to store in + the upper half of the CAR is read from this struct. To get the pointer + represented by a smob, the wrapper code calls the function <CODE> +SWIG_ConvertPtr()</CODE>, passing a pointer to a struct representing the + expected pointer type. See also <A href="#runtime_type_checker">The + run-time type checker</A>. If the Scheme object passed was not a SWIG + smob representing a compatible pointer, a <CODE>wrong-type-arg</CODE> + exception is raised.</P> +<H3><A name="Guile_nn13"></A>20.6.1 GH Smobs</H3> +<P> In earlier versions of SWIG, C pointers were represented as Scheme + strings containing a hexadecimal rendering of the pointer value and a + mangled type name. As Guile allows registering user types, so-called + "smobs" (small objects), a much cleaner representation has been + implemented now. The details will be discussed in the following.</P> +<P> A smob is a cons cell where the lower half of the CAR contains the + smob type tag, while the upper half of the CAR and the whole CDR are + available. Every module creates its own smob type in the clientdata + field of the module. So the lower 16 bits of the car of the smob store + the tag and the upper 16 bits store the index this type is in the + array. We can then, given a smob, find its swig_type_info struct by + using the tag (lower 16 bits of car) to find which module this type is + in (since each tag is unique for the module). Then we use the upper 16 + bits to index into the array of types attached to this module. Looking + up the module from the tag is worst case O(# of modules) but average + case O(1). This is because the modules are stored in a circularly + linked list, and when we start searching the modules for the tag, we + start looking with the module that the function doing the lookup is in. + SWIG_Guile_ConvertPtr() takes as its first argument the + swig_module_info * of the calling function, which is where we start + comparing tags. Most types will be looked up in the same module that + created them, so the first module we check will most likely be correct. + Once we have a swig_type_info structure, we loop through the linked + list of casts, using pointer comparisons.</P> +<H3><A name="Guile_nn14"></A>20.6.2 SCM Smobs</H3> +<P>The SCM interface (using the "-scm" argument to swig) uses + swigrun.swg. The whole type system, when it is first initialized, + creates two smobs named "swig" and "collected_swig". The swig smob is + used for non-garbage collected smobs, while the collected_swig smob is + used as described below. Each smob has the same format, which is a + double cell created by SCM_NEWSMOB2() The first word of data is the + pointer to the object and the second word of data is the swig_type_info + * structure describing this type. This is a lot easier than the GH + interface above because we can store a pointer to the type info + structure right in the type. With the GH interface, there was not + enough room in the smob to store two whole words of data so we needed + to store part of the "swig_type_info address" in the smob tag. If a + generated GOOPS module has been loaded, smobs will be wrapped by the + corresponding GOOPS class.</P> +<H3><A name="Guile_nn15"></A>20.6.3 Garbage Collection</H3> +<P>Garbage collection is a feature of the new SCM interface, and it is + automatically included if you pass the "-scm" flag to swig. Thus the + swig garbage collection support requires guile >1.6. Garbage collection + works like this. Every swig_type_info structure stores in its + clientdata field a pointer to the destructor for this type. The + destructor is the generated wrapper around the delete function. So swig + still exports a wrapper for the destructor, it just does not call + scm_c_define_gsubr() for the wrapped delete function. So the only way + to delete an object is from the garbage collector, since the delete + function is not available to scripts. How swig determines if a type + should be garbage collected is exactly like described in <A href="#ownership"> + Object ownership and %newobject</A> in the SWIG manual. All typemaps + use an $owner var, and the guile module replaces $owner with 0 or 1 + depending on feature:new.</P> +<H2><A name="Guile_nn16"></A>20.7 Exception Handling</H2> +<P> SWIG code calls <CODE>scm_error</CODE> on exception, using the + following mapping:<DIV class="code"> +<PRE> + MAP(SWIG_MemoryError, "swig-memory-error"); + MAP(SWIG_IOError, "swig-io-error"); + MAP(SWIG_RuntimeError, "swig-runtime-error"); + MAP(SWIG_IndexError, "swig-index-error"); + MAP(SWIG_TypeError, "swig-type-error"); + MAP(SWIG_DivisionByZero, "swig-division-by-zero"); + MAP(SWIG_OverflowError, "swig-overflow-error"); + MAP(SWIG_SyntaxError, "swig-syntax-error"); + MAP(SWIG_ValueError, "swig-value-error"); + MAP(SWIG_SystemError, "swig-system-error"); +</PRE> +</DIV></P> +<P> The default when not specified here is to use "swig-error". See + Lib/exception.i for details.</P> +<H2><A name="Guile_nn17"></A>20.8 Procedure documentation</H2> +<P>If invoked with the command-line option <CODE>-procdoc<VAR> file</VAR> +</CODE>, SWIG creates documentation strings for the generated wrapper + functions, describing the procedure signature and return value, and + writes them to<VAR> file</VAR>. You need Guile 1.4 or later to make use + of the documentation files.</P> +<P>SWIG can generate documentation strings in three formats, which are + selected via the command-line option <CODE>-procdocformat<VAR> format</VAR> +</CODE>:</P> +<UL> +<LI><CODE>guile-1.4</CODE> (default): Generates a format suitable for + Guile 1.4.</LI> +<LI><CODE>plain</CODE>: Generates a format suitable for Guile 1.4.1 and + later.</LI> +<LI><CODE>texinfo</CODE>: Generates texinfo source, which must be run + through texinfo in order to get a format suitable for Guile 1.4.1 and + later.</LI> +</UL> +<P>You need to register the generated documentation file with Guile like + this:<DIV class="targetlang"> +<PRE> +(use-modules (ice-9 documentation)) +(set! documentation-files + (cons "<VAR>file</VAR>" documentation-files)) +</PRE> +</DIV></P> +<P>Documentation strings can be configured using the Guile-specific + typemap argument <CODE>doc</CODE>. See <CODE>Lib/guile/typemaps.i</CODE> + for details.</P> +<H2><A name="Guile_nn18"></A>20.9 Procedures with setters</H2> +<P>For global variables, SWIG creates a single wrapper procedure <CODE>(<VAR> +variable</VAR> :optional value)</CODE>, which is used for both getting + and setting the value. For struct members, SWIG creates two wrapper + procedures <CODE>(<VAR>struct</VAR>-<VAR>member</VAR>-get pointer)</CODE> + and <CODE>(<VAR>struct-member</VAR>-set pointer value)</CODE>.</P> +<P>If invoked with the command-line option <CODE>-emit-setters</CODE> (<EM> +recommended</EM>), SWIG will additionally create procedures with + setters. For global variables, the procedure-with-setter <CODE><VAR> +variable</VAR></CODE> is created, so you can use <CODE>(<VAR>variable</VAR> +)</CODE> to get the value and <CODE>(set! (<VAR>variable</VAR>)<VAR> + value</VAR>)</CODE> to set it. For struct members, the + procedure-with-setter <CODE><VAR>struct</VAR>-<VAR>member</VAR></CODE> + is created, so you can use <CODE>(<VAR>struct</VAR>-<VAR>member</VAR><VAR> + pointer</VAR>)</CODE> to get the value and <CODE>(set! (<VAR>struct</VAR> +-<VAR>member</VAR><VAR> pointer</VAR>)<VAR> value</VAR>)</CODE> to set + it.</P> +<P>If invoked with the command-line option <CODE>-only-setters</CODE>, + SWIG will<EM> only</EM> create procedures with setters, i.e., for + struct members, the procedures <CODE>(<VAR>struct</VAR>-<VAR>member</VAR> +-get pointer)</CODE> and <CODE>(<VAR>struct-member</VAR>-set pointer + value)</CODE> are<EM> not</EM> generated.</P> +<H2><A name="Guile_nn19"></A>20.10 GOOPS Proxy Classes</H2> +<P>SWIG can also generate classes and generic functions for use with + Guile's Object-Oriented Programming System (GOOPS). GOOPS is a + sophisticated object system in the spirit of the Common Lisp Object + System (CLOS).</P> +<P>GOOPS support is only available with the new SCM interface (enabled + with the <CODE>-scm</CODE> command-line option of SWIG). To enable + GOOPS support, pass the <CODE>-proxy</CODE> argument to swig. This will + export the GOOPS wrapper definitions into the <CODE><I>module</I>.scm</CODE> + file in the directory specified by -outdir or the current directory. + GOOPS support requires either passive or module linkage.</P> +<P>The generated file will contain definitions of GOOPS classes + mimicking the C++ class hierarchy.</P> +<P>Enabling GOOPS support implies <CODE>-emit-setters</CODE>.</P> +<P>If <CODE>-emit-slot-accessors</CODE> is also passed as an argument, + then the generated file will contain accessor methods for all the slots + in the classes and for global variables. The input class</P> +<DIV class="code"> +<PRE> + class Foo { + public: + Foo(int i) : a(i) {} + int a; + int getMultBy(int i) { return a * i; } + Foo getFooMultBy(int i) { return Foo(a * i); } + }; + Foo getFooPlus(int i) { return Foo(a + i); } +</PRE> +</DIV> +<P> will produce (if <CODE>-emit-slot-accessors</CODE> is not passed as + a parameter)</P> +<DIV class="targetlang"> +<PRE> +(define-class <Foo> (<swig>) + (a #:allocation #:swig-virtual + #:slot-ref primitive:Foo-a-get + #:slot-set! primitive:Foo-a-set) + #:metaclass <swig-metaclass> + #:new-function primitive:new-Foo +) +(define-method (getMultBy (swig_smob <Foo>) i) + (primitive:Foo-getMultBy (slot-ref swig_smob 'smob) i)) +(define-method (getFooMultBy (swig_smob <Foo>) i) + (make <Foo> #:init-smob (primitive:Foo-getFooMultBy (slot-ref swig_smob 'smob) i))) + +(define-method (getFooPlus i) + (make <Foo> #:init-smob (primitive:getFooPlus i))) + +(export <Foo> getMultBy getFooMultBy getFooPlus ) +</PRE> +</DIV> +<P> and will produce (if <CODE>-emit-slot-accessors</CODE> is passed as + a parameter)</P> +<DIV class="targetlang"> +<PRE> +(define-class <Foo> (<swig>) + (a #:allocation #:swig-virtual + #:slot-ref primitive:Foo-a-get + #:slot-set! primitive:Foo-a-set + <B>#:accessor a</B>) + #:metaclass <swig-metaclass> + #:new-function primitive:new-Foo +) +(define-method (getMultBy (swig_smob <Foo>) i) + (primitive:Foo-getMultBy (slot-ref swig_smob 'smob) i)) +(define-method (getFooMultBy (swig_smob <Foo>) i) + (make <Foo> #:init-smob (primitive:Foo-getFooMultBy (slot-ref swig_smob 'smob) i))) + +(define-method (getFooPlus i) + (make <Foo> #:init-smob (primitive:getFooPlus i))) + +(export <Foo> <B>a</B> getMultBy getFooMultBy getFooPlus ) +</PRE> +</DIV> +<P> which can then be used by this code</P> +<DIV class="targetlang"> +<PRE> +;; not using getters and setters +(define foo (make <Foo> #:args '(45))) +(slot-ref foo 'a) +(slot-set! foo 'a 3) +(getMultBy foo 4) +(define foo2 (getFooMultBy foo 7)) +(slot-ref foo 'a) +(slot-ref (getFooPlus foo 4) 'a) + +;; using getters and setters +(define foo (make <Foo> #:args '(45))) +(a foo) +(set! (a foo) 5) +(getMultBy foo 4) +(a (getFooMultBy foo 7)) +</PRE> +</DIV> +<P>Notice that constructor arguments are passed as a list after the <CODE> +#:args</CODE> keyword. Hopefully in the future the following will be + valid <CODE>(make <Foo> #:a 5 #:b 4)</CODE></P> +<P>Also note that the order the declarations occur in the .i file make a + difference. For example,</P> +<DIV class="code"> +<PRE> +%module test + +%{ #include "foo.h" %} + +%inline %{ + int someFunc(Foo &a) { + ... + } +%} + +%include "foo.h" +</PRE> +</DIV> +<P> This is a valid SWIG file it will work as you think it will for + primitive support, but the generated GOOPS file will be broken. Since + the <CODE>someFunc</CODE> definition is parsed by SWIG before all the + declarations in foo.h, the generated GOOPS file will contain the + definition of <CODE>someFunc()</CODE> before the definition of <Foo>. + The generated GOOPS file would look like</P> +<DIV class="targetlang"> +<PRE> +;;... + +(define-method (someFunc (swig_smob <Foo>)) + (primitive:someFunc (slot-ref swig_smob 'smob))) + +;;... + +(define-class <Foo> (<swig>) + ;;... +) + +;;... +</PRE> +</DIV> +<P> Notice that <Foo> is used before it is defined. The fix is to just + put the <CODE>%import "foo.h"</CODE> before the <CODE>%inline</CODE> + block.</P> +<H3><A name="Guile_nn20"></A>20.10.1 Naming Issues</H3> +<P>As you can see in the example above, there are potential naming + conflicts. The default exported accessor for the <CODE>Foo::a</CODE> + variable is named <CODE>a</CODE>. The name of the wrapper global + function is <CODE>getFooPlus</CODE>. If the <CODE>-useclassprefix</CODE> + option is passed to swig, the name of all accessors and member + functions will be prepended with the class name. So the accessor will + be called <CODE>Foo-a</CODE> and the member functions will be called <CODE> +Foo-getMultBy</CODE>. Also, if the <CODE>-goopsprefix goops:</CODE> + argument is passed to swig, every identifier will be prefixed by <CODE> +goops:</CODE></P> +<P>Two guile-modules are created by SWIG. The first module contains the + primitive definitions of all the wrapped functions and variables, and + is located either in the _wrap.cxx file (with <CODE>-Linkage module</CODE> +) or in the scmstub file (if <CODE>-Linkage passive -scmstub</CODE>). + The name of this guile-module is the swig-module name (given on the + command line with the -module argument or with the %module directive) + concatenated with the string "-primitive". For example, if <CODE> +%module Test</CODE> is set in the swig interface file, the name of the + guile-module in the scmstub or <CODE>-Linkage module</CODE> will be <CODE> +Test-primitive</CODE>. Also, the scmstub file will be named <CODE> +Test-primitive.scm</CODE>. The string "primitive" can be changed by the <CODE> +-primsuffix</CODE> swig argument. So the same interface, with the <CODE> +-primsuffix base</CODE> will produce a module called <CODE>Test-base</CODE> +. The second generated guile-module contains all the GOOPS class + definitions and is located in a file named<I> module</I>.scm in the + directory specified with -outdir or the current directory. The name of + this guile-module is the name of the swig-module (given on the command + line or with the <CODE>%module</CODE> directive). In the previous + example, the GOOPS definitions will be in a file named Test.scm.</P> +<P>Because of the naming conflicts, you can't in general use both the <CODE> +-primitive</CODE> and the GOOPS guile-modules at the same time. To do + this, you need to rename the exported symbols from one or both + guile-modules. For example,</P> +<DIV class="targetlang"> +<PRE> +(use-modules ((Test-primitive) #:renamer (symbol-prefix-proc 'primitive:))) +(use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:))) +</PRE> +</DIV> +<P>TODO: Renaming class name prefixes?</P> +<H3><A name="Guile_nn21"></A>20.10.2 Linking</H3> +<P>The guile-modules generated above all need to be linked together. + GOOPS support requires either passive or module linkage. The exported + GOOPS guile-module will be the name of the swig-module and should be + located in a file called<I> Module</I>.scm. This should be installed on + the autoload path for guile, so that <CODE>(use-modules (<I>Package + Module</I>))</CODE> will load everything needed. Thus, the top of the + GOOPS guile-module will contain code to load everything needed by the + interface (the shared library, the scmstub module, etc.). The <CODE> +%goops</CODE> directive inserts arbitrary code into the generated GOOPS + guile-module, and should be used to load the dependent libraries.</P> +<P>This breaks up into three cases</P> +<UL> +<LI><B>Passive Linkage without -scmstub</B>: Note that this linkage + style has the potential for naming conflicts, since the primitive + exported function and variable names are not wrapped in a guile-module + and might conflict with names from the GOOPS guile-module (see above). + Pass the -goopsprefix argument to solve this problem. If the <CODE> +-exportprimitive</CODE> option is passed to SWIG the <CODE>(export ...)</CODE> + code that would be exported into the scmstub file is exported at the + bottom of the generated GOOPS guile-module. The <CODE>%goops</CODE> + directive should contain code to load the .so library.<DIV class="code"> +<PRE> +%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %} +</PRE> +</DIV> +<P> Produces the following code at the top of the generated GOOPS + guile-module (with the <CODE>-package my/modules -module foo</CODE> + command line arguments)</P> +<DIV class="targetlang"> +<PRE> +(define-module (my modules foo)) + +;; %goops directive goes here +(load-extension "./foo.so" "scm_init_my_modules_foo_module") + +(use-modules (oop goops) (Swig common)) +</PRE> +</DIV></LI> +<LI> +<P><B>Passive Linkage with -scmstub</B>: Here, the name of the scmstub + file should be <CODE>Module-primitive.scm</CODE> (with<I> primitive</I> + replaced with whatever is given with the <CODE>-primsuffix</CODE> + argument. The code to load the <CODE>.so</CODE> library should be + located in the <CODE>%scheme</CODE> directive, which will then be added + to the scmstub file. Swig will automatically generate the line <CODE> +(use-modules (<I>Package</I><I> Module-primitive</I>))</CODE> into the + GOOPS guile-module. So if<I> Module-primitive.scm</I> is on the + autoload path for guile, the <CODE>%goops</CODE> directive can be + empty. Otherwise, the <CODE>%goops</CODE> directive should contain + whatever code is needed to load the<I> Module-primitive.scm</I> file + into guile.</P> +<DIV class="targetlang"> +<PRE> +%scheme %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %} +// only include the following definition if (my modules foo) cannot +// be loaded automatically +%goops %{ + (primitive-load "/path/to/foo-primitive.scm") + (primitive-load "/path/to/Swig/common.scm") +%} +</PRE> +</DIV> +<P> Produces the following code at the top of the generated GOOPS + guile-module</P> +<DIV class="targetlang"> +<PRE> +(define-module (my modules foo)) + +;; %goops directive goes here (if any) +(primitive-load "/path/to/foo-primitive.scm") +(primitive-load "/path/to/Swig/common.scm") + +(use-modules (oop goops) (Swig common)) +(use-modules ((my modules foo-primitive) :renamer (symbol-prefix-proc + 'primitive:))) + +</PRE> +</DIV></LI> +<LI> +<P><B>Module Linkage</B>: This is very similar to passive linkage with a + scmstub file. Swig will also automatically generate the line <CODE> +(use-modules (<I>Package</I><I> Module-primitive</I>))</CODE> into the + GOOPS guile-module. Again the <CODE>%goops</CODE> directive should + contain whatever code is needed to get that module loaded into guile.</P> +<DIV class="code"> +<PRE> +%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %} +</PRE> +</DIV> +<P> Produces the following code at the top of the generated GOOPS + guile-module</P> +<DIV class="targetlang"> +<PRE> +(define-module (my modules foo)) + +;; %goops directive goes here (if any) +(load-extension "./foo.so" "scm_init_my_modules_foo_module") + +(use-modules (oop goops) (Swig common)) +(use-modules ((my modules foo-primitive) :renamer (symbol-prefix-proc + 'primitive:))) + +</PRE> +</DIV></LI> +</UL> +<P><B>(Swig common)</B>: The generated GOOPS guile-module also imports + definitions from the (Swig common) guile-module. This module is + included with SWIG and should be installed by SWIG into the autoload + path for guile (based on the configure script and whatever arguments + are passed). If it is not, then the <CODE>%goops</CODE> directive also + needs to contain code to load the <CODE>common.scm</CODE> file into + guile. Also note that if you are trying to install the generated + wrappers on a computer without SWIG installed, you will need to include + the common.swg file along with the install.</P> +<P><B>Multiple Modules</B>: Type dependencies between modules is + supported. For example, if <CODE>mod1</CODE> includes definitions of + some classes, and <CODE>mod2</CODE> includes some classes derived from + classes in <CODE>mod1</CODE>, the generated GOOPS file for <CODE>mod2</CODE> + will declare the correct superclasses. The only problem is that since <CODE> +mod2</CODE> uses symbols from <CODE>mod1</CODE>, the <CODE>mod2</CODE> + GOOPS file must include a <CODE>(use-modules (mod2))</CODE>. Currently, + SWIG does not automatically export this line; it must be included in + the <CODE>%goops</CODE> directive of <CODE>mod2</CODE>. Maybe in the + future SWIG can detect dependencies and export this line. (how do other + language modules handle this problem?)</P> +<HR NOSHADE> +<H1><A name="Java"></A>21 SWIG and Java</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#java_overview">Overview</A></LI> +<LI><A href="#java_preliminaries">Preliminaries</A> +<UL> +<LI><A href="#running_swig">Running SWIG</A></LI> +<LI><A href="#java_commandline">Additional Commandline Options</A></LI> +<LI><A href="#getting_right_headers">Getting the right header files</A></LI> +<LI><A href="#compiling_dynamic">Compiling a dynamic module</A></LI> +<LI><A href="#using_module">Using your module</A></LI> +<LI><A href="#dynamic_linking_problems">Dynamic linking problems</A></LI> +<LI><A href="#compilation_problems_cpp">Compilation problems and + compiling with C++</A></LI> +<LI><A href="#building_windows">Building on Windows</A> +<UL> +<LI><A href="#visual_studio">Running SWIG from Visual Studio</A></LI> +<LI><A href="#nmake">Using NMAKE</A></LI> +</UL> +</LI> +</UL> +</LI> +<LI><A href="#java_basic_tour">A tour of basic C/C++ wrapping</A> +<UL> +<LI><A href="#module_packages_classes">Modules, packages and generated + Java classes</A></LI> +<LI><A href="#functions">Functions</A></LI> +<LI><A href="#global_variables">Global variables</A></LI> +<LI><A href="#constants">Constants</A></LI> +<LI><A href="#enumerations">Enumerations</A> +<UL> +<LI><A href="#anonymous_enums">Anonymous enums</A></LI> +<LI><A href="#typesafe_enums">Typesafe enums</A></LI> +<LI><A href="#proper_enums">Proper Java enums</A></LI> +<LI><A href="#typeunsafe_enums">Type unsafe enums</A></LI> +<LI><A href="#simple_enums">Simple enums</A></LI> +</UL> +</LI> +<LI><A href="#pointers">Pointers</A></LI> +<LI><A href="#structures">Structures</A></LI> +<LI><A href="#classes">C++ classes</A></LI> +<LI><A href="#inheritance">C++ inheritance</A></LI> +<LI><A href="#pointers_refs_arrays">Pointers, references, arrays and + pass by value</A> +<UL> +<LI><A href="#null_pointers">Null pointers</A></LI> +</UL> +</LI> +<LI><A href="#overloaded_functions">C++ overloaded functions</A></LI> +<LI><A href="#java_default_arguments">C++ default arguments</A></LI> +<LI><A href="#namespaces">C++ namespaces</A></LI> +<LI><A href="#templates">C++ templates</A></LI> +<LI><A href="#smart_pointers">C++ Smart Pointers</A></LI> +</UL> +</LI> +<LI><A href="#further_details">Further details on the generated Java + classes</A> +<UL> +<LI><A href="#imclass">The intermediary JNI class</A> +<UL> +<LI><A href="#imclass_pragmas">The intermediary JNI class pragmas</A></LI> +</UL> +</LI> +<LI><A href="#java_module_class">The Java module class</A> +<UL> +<LI><A href="#module_class_pragmas">The Java module class pragmas</A></LI> +</UL> +</LI> +<LI><A href="#java_proxy_classes">Java proxy classes</A> +<UL> +<LI><A href="#memory_management">Memory management</A></LI> +<LI><A href="#inheritance_mirroring">Inheritance</A></LI> +<LI><A href="#proxy_classes_gc">Proxy classes and garbage collection</A></LI> +<LI><A href="#java_pgcpp">The premature garbage collection prevention + parameter for proxy class marshalling</A></LI> +<LI><A href="#java_multithread_libraries">Single threaded applications + and thread safety</A></LI> +</UL> +</LI> +<LI><A href="#type_wrapper_classes">Type wrapper classes</A></LI> +<LI><A href="#enum_classes">Enum classes</A> +<UL> +<LI><A href="#typesafe_enums_classes">Typesafe enum classes</A></LI> +<LI><A href="#proper_enums_classes">Proper Java enum classes</A></LI> +<LI><A href="#typeunsafe_enums_classes">Type unsafe enum classes</A></LI> +</UL> +</LI> +</UL> +</LI> +<LI><A href="#java_directors">Cross language polymorphism using + directors</A> +<UL> +<LI><A href="#java_enabling_directors">Enabling directors</A></LI> +<LI><A href="#java_directors_classes">Director classes</A></LI> +<LI><A href="#java_directors_overhead">Overhead and code bloat</A></LI> +<LI><A href="#java_directors_example">Simple directors example</A></LI> +<LI><A href="#java_directors_threading">Director threading issues</A></LI> +</UL> +</LI> +<LI><A href="#java_allprotected">Accessing protected members</A></LI> +<LI><A href="#common_customization">Common customization features</A> +<UL> +<LI><A href="#helper_functions">C/C++ helper functions</A></LI> +<LI><A href="#class_extension">Class extension with %extend</A></LI> +<LI><A href="#exception_handling">Exception handling with %exception and + %javaexception</A></LI> +<LI><A href="#method_access">Method access with %javamethodmodifiers</A></LI> +</UL> +</LI> +<LI><A href="#tips_techniques">Tips and techniques</A> +<UL> +<LI><A href="#input_output_parameters">Input and output parameters using + primitive pointers and references</A></LI> +<LI><A href="#simple_pointers">Simple pointers</A></LI> +<LI><A href="#c_arrays">Wrapping C arrays with Java arrays</A></LI> +<LI><A href="#unbounded_c_arrays">Unbounded C Arrays</A></LI> +<LI><A href="#java_heap_allocations">Overriding new and delete to + allocate from Java heap</A></LI> +</UL> +</LI> +<LI><A href="#java_typemaps">Java typemaps</A> +<UL> +<LI><A href="#default_primitive_type_mappings">Default primitive type + mappings</A></LI> +<LI><A href="#Java_default_non_primitive_typemaps">Default typemaps for + non-primitive types</A></LI> +<LI><A href="#jvm64">Sixty four bit JVMs</A></LI> +<LI><A href="#what_is_typemap">What is a typemap?</A></LI> +<LI><A href="#typemaps_c_to_java_types">Typemaps for mapping C/C++ types + to Java types</A></LI> +<LI><A href="#typemap_attributes">Java typemap attributes</A></LI> +<LI><A href="#special_variables">Java special variables</A></LI> +<LI><A href="#typemaps_for_c_and_cpp">Typemaps for both C and C++ + compilation</A></LI> +<LI><A href="#java_code_typemaps">Java code typemaps</A></LI> +<LI><A href="#java_directors_typemaps">Director specific typemaps</A></LI> +</UL> +</LI> +<LI><A href="#typemap_examples">Typemap Examples</A> +<UL> +<LI><A href="#simpler_enum_classes">Simpler Java enums for enums without + initializers</A></LI> +<LI><A href="#exception_typemap">Handling C++ exception specifications + as Java exceptions</A></LI> +<LI><A href="#nan_exception_typemap">NaN Exception - exception handling + for a particular type</A></LI> +<LI><A href="#converting_java_string_arrays">Converting Java String + arrays to char **</A></LI> +<LI><A href="#expanding_java_object">Expanding a Java object to multiple + arguments</A></LI> +<LI><A href="#using_typemaps_return_arguments">Using typemaps to return + arguments</A></LI> +<LI><A href="#adding_downcasts">Adding Java downcasts to polymorphic + return types</A></LI> +<LI><A href="#adding_equals_method">Adding an equals method to the Java + classes</A></LI> +<LI><A href="#void_pointers">Void pointers and a common Java base class</A> +</LI> +<LI><A href="#struct_pointer_pointer">Struct pointer to pointer</A></LI> +<LI><A href="#java_memory_management_member_variables">Memory management + when returning references to member variables</A></LI> +<LI><A href="#java_memory_management_objects">Memory management for + objects passed to the C++ layer</A></LI> +<LI><A href="#java_date_marshalling">Date marshalling using the javain + typemap and associated attributes</A></LI> +</UL> +</LI> +<LI><A href="#java_directors_faq">Living with Java Directors</A></LI> +<LI><A href="#odds_ends">Odds and ends</A> +<UL> +<LI><A href="#javadoc_comments">JavaDoc comments</A></LI> +<LI><A href="#functional_interface">Functional interface without proxy + classes</A></LI> +<LI><A href="#using_own_jni_functions">Using your own JNI functions</A></LI> +<LI><A href="#performance">Performance concerns and hints</A></LI> +<LI><A href="#java_debugging">Debugging</A></LI> +</UL> +</LI> +<LI><A href="#java_examples">Examples</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes SWIG's support of Java. It covers most SWIG + features, but certain low-level details are covered in less depth than + in earlier chapters.</P> +<H2><A name="java_overview"></A>21.1 Overview</H2> +<P> The 100% Pure Java effort is a commendable concept, however in the + real world programmers often either need to re-use their existing code + or in some situations want to take advantage of Java but are forced + into using some native (C/C++) code. The Java extension to SWIG makes + it very easy to plumb in existing C/C++ code for access from Java, as + SWIG writes the Java Native Interface (JNI) code for you. It is + different to using the 'javah' tool as SWIG will wrap existing C/C++ + code, whereas javah takes 'native' Java function declarations and + creates C/C++ function prototypes. SWIG wraps C/C++ code using Java + proxy classes and is very useful if you want to have access to large + amounts of C/C++ code from Java. If only one or two JNI functions are + needed then using SWIG may be overkill. SWIG enables a Java program to + easily call into C/C++ code from Java. Historically, SWIG was not able + to generate any code to call into Java code from C++. However, SWIG now + supports full cross language polymorphism and code is generated to call + up from C++ to Java when wrapping C++ virtual methods.</P> +<P> Java is one of the few non-scripting language modules in SWIG. As + SWIG utilizes the type safety that the Java language offers, it takes a + somewhat different approach to that used for scripting languages. In + particular runtime type checking and the runtime library are not used + by Java. This should be borne in mind when reading the rest of the SWIG + documentation. This chapter on Java is relatively self contained and + will provide you with nearly everything you need for using SWIG and + Java. However, the "<A href="#SWIG">SWIG Basics</A>" chapter will be a + useful read in conjunction with this one.</P> +<P> This chapter starts with a few practicalities on running SWIG and + compiling the generated code. If you are looking for the minimum amount + to read, have a look at the sections up to and including the <A href="#java_basic_tour"> +tour of basic C/C++ wrapping</A> section which explains how to call the + various C/C++ code constructs from Java. Following this section are + details of the C/C++ code and Java classes that SWIG generates. Due to + the complexities of C and C++ there are different ways in which C/C++ + code could be wrapped and called from Java. SWIG is a powerful tool and + the rest of the chapter details how the default code wrapping can be + tailored. Various customisation tips and techniques using SWIG + directives are covered. The latter sections cover the advanced + techniques of using typemaps for complete control of the wrapping + process.</P> +<H2><A name="java_preliminaries"></A>21.2 Preliminaries</H2> +<P> SWIG 1.1 works with JDKs from JDK 1.1 to JDK1.4 (Java 2 SDK1.4) and + should also work with any later versions. Given the choice, you should + probably use the latest version of Sun's JDK. The SWIG Java module is + known to work using Sun's JVM on Solaris, Linux and the various + flavours of Microsoft Windows including Cygwin. The Kaffe JVM is known + to give a few problems and at the time of writing was not a fully + fledged JVM with full JNI support. The generated code is also known to + work on vxWorks using WindRiver's PJava 3.1. The best way to determine + whether your combination of operating system and JDK will work is to + test the examples and test-suite that comes with SWIG. Run <TT>make -k + check</TT> from the SWIG root directory after installing SWIG on Unix + systems.</P> +<P> The Java module requires your system to support shared libraries and + dynamic loading. This is the commonly used method to load JNI code so + your system will more than likely support this.</P> +<H3><A name="running_swig"></A>21.2.1 Running SWIG</H3> +<P> Suppose that you defined a SWIG module such as the following:</P> +<DIV class="code"> +<PRE> +/* File: example.i */ +%module test +%{ +#include "stuff.h" +%} +int fact(int n); +</PRE> +</DIV> +<P> To build a Java module, run SWIG using the <TT>-java</TT> option :</P> +<DIV class="code"> +<PRE> +%swig -java example.i +</PRE> +</DIV> +<P> If building C++, add the <TT>-c++</TT> option:</P> +<DIV class="code"> +<PRE> +$ swig -c++ -java example.i +</PRE> +</DIV> +<P> This creates two different files; a C/C++ source file <TT> +example_wrap.c</TT> or <TT>example_wrap.cxx</TT> and numerous Java + files. The generated C/C++ source file contains the JNI wrapper code + that needs to be compiled and linked with the rest of your C/C++ + application.</P> +<P> The name of the wrapper file is derived from the name of the input + file. For example, if the input file is <TT>example.i</TT>, the name of + the wrapper file is <TT>example_wrap.c</TT>. To change this, you can + use the <TT>-o</TT> option. It is also possible to change the <A href="#output"> +output directory</A> that the Java files are generated into using <TT> +-outdir</TT>.</P> +<P> The module name, specified with <TT>%module</TT>, determines the + name of various generated classes as discussed <A href="#module_packages_classes"> +later</A>. Note that the module name does not define a Java package and + by default, the generated Java classes do not have a Java package. The <TT> +-package</TT> option described below can specify a Java package name to + use.</P> +<P> The following sections have further practical examples and details + on how you might go about compiling and using the generated files.</P> +<H3><A name="java_commandline"></A>21.2.2 Additional Commandline Options</H3> +<P> The following table list the additional commandline options + available for the Java module. They can also be seen by using:</P> +<DIV class="code"> +<PRE> +swig -java -help +</PRE> +</DIV> +<TABLE summary="Java specific options"> +<TR><TH>Java specific options</TH></TR> +<TR><TD>-nopgcpp</TD><TD>suppress the premature garbage collection + prevention parameter</TD></TR> +<TR><TD>-noproxy</TD><TD>generate the low-level functional interface + instead of proxy classes</TD></TR> +<TR><TD>-package <name></TD><TD>set name of the Java package to <name></TD> +</TR> +</TABLE> +<P> Their use will become clearer by the time you have finished reading + this section on SWIG and Java.</P> +<H3><A name="getting_right_headers"></A>21.2.3 Getting the right header + files</H3> +<P> In order to compile the C/C++ wrappers, the compiler needs the <TT> +jni.h</TT> and <TT>jni_md.h</TT> header files which are part of the JDK. + They are usually in directories like this:</P> +<DIV class="code"> +<PRE> +/usr/java/include +/usr/java/include/<operating_system> +</PRE> +</DIV> +<P> The exact location may vary on your machine, but the above locations + are typical.</P> +<H3><A name="compiling_dynamic"></A>21.2.4 Compiling a dynamic module</H3> +<P> The JNI code exists in a dynamic module or shared library (DLL on + Windows) and gets loaded by the JVM. To build a shared library file, + you need to compile your module in a manner similar to the following + (shown for Solaris):</P> +<DIV class="code"> +<PRE> +$ swig -java example.i +$ gcc -c example_wrap.c -I/usr/java/include -I/usr/java/include/solaris +$ ld -G example_wrap.o -o libexample.so +</PRE> +</DIV> +<P> The exact commands for doing this vary from platform to platform. + However, SWIG tries to guess the right options when it is installed. + Therefore, you may want to start with one of the examples in the <TT> +Examples/java</TT> directory. If that doesn't work, you will need to + read the man-pages for your compiler and linker to get the right set of + options. You might also check the <A href="http://www.dabeaz.com/cgi-bin/wiki.pl"> +SWIG Wiki</A> for additional information. <A href="http://weblogs.java.net/blog/kellyohair/archive/2006/01/compilation_of.html"> +JNI compilation</A> is a useful reference for compiling on different + platforms.</P> +<P><B> Important</B> +<BR> If you are going to use optimisations turned on with gcc (for + example -O2), ensure you also compile with -fno-strict-aliasing. The + GCC optimisations have become more aggressive from gcc-4.0 onwards and + will result in code that fails with strict aliasing optimisations + turned on. See the <A href="#typemaps_c_to_java_types">C/C++ to Java + typemaps</A> section for more details.</P> +<P> The name of the shared library output file is important. If the name + of your SWIG module is "<TT>example</TT>", the name of the + corresponding shared library file should be "<TT>libexample.so</TT>" + (or equivalent depending on your machine, see <A href="#dynamic_linking_problems"> +Dynamic linking problems</A> for more information). The name of the + module is specified using the <TT>%module</TT> directive or <TT>-module</TT> + command line option.</P> +<H3><A name="using_module"></A>21.2.5 Using your module</H3> +<P> To load your shared native library module in Java, simply use Java's + <TT>System.loadLibrary</TT> method in a Java class:</P> +<DIV class="code"> +<PRE> +// runme.java + +public class runme { + static { + System.loadLibrary("example"); + } + + public static void main(String argv[]) { + System.out.println(example.fact(4)); + } +} +</PRE> +</DIV> +<P> Compile all the Java files and run:</P> +<DIV class="code"> +<PRE> +$ javac *.java +$ java runme +24 +$ +</PRE> +</DIV> +<P> If it doesn't work have a look at the following section which + discusses problems loading the shared library.</P> +<H3><A name="dynamic_linking_problems"></A>21.2.6 Dynamic linking + problems</H3> +<P> As shown in the previous section the code to load a native library + (shared library) is <TT>System.loadLibrary("name")</TT>. This can fail + with an UnsatisfiedLinkError exception and can be due to a number of + reasons.</P> +<P> You may get an exception similar to this:</P> +<DIV class="code"> +<PRE> +$ java runme +Exception in thread "main" java.lang.UnsatisfiedLinkError: no example in java.library.path + at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1312) + at java.lang.Runtime.loadLibrary0(Runtime.java:749) + at java.lang.System.loadLibrary(System.java:820) + at runme.<clinit>(runme.java:5) +</PRE> +</DIV> +<P> The most common cause for this is an incorrect naming of the native + library for the name passed to the <TT>loadLibrary</TT> function. The + string passed to the <TT>loadLibrary</TT> function must not include the + file extension name in the string, that is<I> .dll</I> or<I> .so</I>. + The string must be<I> name</I> and not<I> libname</I> for all + platforms. On Windows the native library must then be called<I> + name.dll</I> and on most Unix systems it must be called<I> libname.so</I> +.</P> +<P> Another common reason for the native library not loading is because + it is not in your path. On Windows make sure the<I> path</I> + environment variable contains the path to the native library. On Unix + make sure that your<I> LD_LIBRARY_PATH</I> contains the path to the + native library. Adding paths to<I> LD_LIBRARY_PATH</I> can slow down + other programs on your system so you may want to consider alternative + approaches. For example you could recompile your native library with + extra path information using <TT>-rpath</TT> if you're using GNU, see + the GNU linker documentation (<TT>ld</TT> man page). You could use a + command such as <TT>ldconfig</TT> (Linux) or <TT>crle</TT> (Solaris) to + add additional search paths to the default system configuration (this + requires root access and you will need to read the man pages).</P> +<P> The native library will also not load if there are any unresolved + symbols in the compiled C/C++ code. The following exception is + indicative of this:</P> +<DIV class="code"> +<PRE> +$ java runme +Exception in thread "main" java.lang.UnsatisfiedLinkError: libexample.so: undefined +symbol: fact + at java.lang.ClassLoader$NativeLibrary.load(Native Method) + at java.lang.ClassLoader.loadLibrary0(ClassLoader.java, Compiled Code) + at java.lang.ClassLoader.loadLibrary(ClassLoader.java, Compiled Code) + at java.lang.Runtime.loadLibrary0(Runtime.java, Compiled Code) + at java.lang.System.loadLibrary(System.java, Compiled Code) + at runme.<clinit>(runme.java:5) +$ +</PRE> +</DIV> +<P> This error usually indicates that you forgot to include some object + files or libraries in the linking of the native library file. Make sure + you compile both the SWIG wrapper file and the code you are wrapping + into the native library file. If you forget to compile and link in the + SWIG wrapper file into your native library file, you will get a message + similar to the following:</P> +<DIV class="code"> +<PRE> +$ java runme +Exception in thread "main" java.lang.UnsatisfiedLinkError: exampleJNI.gcd(II)I + at exampleJNI.gcd(Native Method) + at example.gcd(example.java:12) + at runme.main(runme.java:18) +</PRE> +</DIV> +<P> where <TT>gcd</TT> is the missing JNI function that SWIG generated + into the wrapper file. Also make sure you pass all of the required + libraries to the linker. The <TT>java -verbose:jni</TT> commandline + switch is also a great way to get more information on unresolved + symbols. One last piece of advice is to beware of the common faux pas + of having more than one native library version in your path.</P> +<P> In summary, ensure that you are using the correct C/C++ compiler and + linker combination and options for successful native library loading. + If you are using the examples that ship with SWIG, then the + Examples/Makefile must have these set up correctly for your system. The + SWIG installation package makes a best attempt at getting these correct + but does not get it right 100% of the time. The <A href="http://www.dabeaz.com/cgi-bin/wiki.pl"> +SWIG Wiki</A> also has some settings for commonly used compiler and + operating system combinations. The following section also contains some + C++ specific linking problems and solutions.</P> +<H3><A name="compilation_problems_cpp"></A>21.2.7 Compilation problems + and compiling with C++</H3> +<P> On most machines, shared library files should be linked using the + C++ compiler. For example:</P> +<DIV class="code"> +<PRE> +% swig -c++ -java example.i +% g++ -c -fpic example.cxx +% g++ -c -fpic example_wrap.cxx -I/usr/java/j2sdk1.4.1/include -I/usr/java/ +j2sdk1.4.1/include/linux +% g++ -shared example.o example_wrap.o -o libexample.so +</PRE> +</DIV> +<P> In addition to this, you may need to include additional library + files to make it work. For example, if you are using the Sun C++ + compiler on Solaris, you often need to add an extra library <TT>-lCrun</TT> + like this:</P> +<DIV class="code"> +<PRE> +% swig -c++ -java example.i +% CC -c example.cxx +% CC -c example_wrap.cxx -I/usr/java/include -I/usr/java/include/solaris +% CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o libexample.so -lCrun +</PRE> +</DIV> +<P> If you aren't entirely sure about the linking for C++, you might + look at an existing C++ program. On many Unix machines, the <TT>ldd</TT> + command will list library dependencies. This should give you some clues + about what you might have to include when you link your shared library. + For example:</P> +<DIV class="code"> +<PRE> +$ ldd swig + libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000) + libm.so.6 => /lib/libm.so.6 (0x4005b000) + libc.so.6 => /lib/libc.so.6 (0x40077000) + /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) +$ +</PRE> +</DIV> +<P> Finally make sure the version of JDK header files matches the + version of Java that you are running as incompatibilities could lead to + compilation problems or unpredictable behaviour.</P> +<H3><A name="building_windows"></A>21.2.8 Building on Windows</H3> +<P> Building on Windows is roughly similar to the process used with + Unix. You will want to produce a DLL that can be loaded by the Java + Virtual Machine. This section covers the process of using SWIG with + Microsoft Visual C++ 6 although the procedure may be similar with other + compilers. In order for everything to work, you will need to have a JDK + installed on your machine in order to read the JNI header files.</P> +<H4><A name="visual_studio"></A>21.2.8.1 Running SWIG from Visual Studio</H4> +<P> If you are developing your application within Microsoft Visual + studio, SWIG can be invoked as a custom build option. The Examples\java + directory has a few <A href="#Windows_examples">Windows Examples</A> + containing Visual Studio project (.dsp) files. The process to re-create + the project files for a C project are roughly:</P> +<UL> +<LI>Open up a new workspace and use the AppWizard to select a DLL + project.</LI> +<LI>Add both the SWIG interface file (the .i file), any supporting C + files, and the name of the wrapper file that will be created by SWIG + (ie. <TT>example_wrap.c</TT>). Don't worry if the wrapper file doesn't + exist yet--Visual Studio will keep a reference to it.</LI> +<LI>Select the SWIG interface file and go to the settings menu. Under + settings, select the "Custom Build" option.</LI> +<LI>Enter "SWIG" in the description field.</LI> +<LI>Enter "<TT>swig -java -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)</TT> +" in the "Build command(s) field"</LI> +<LI>Enter "<TT>$(ProjDir)\$(InputName)_wrap.c</TT>" in the "Output + files(s) field".</LI> +<LI>Next, select the settings for the entire project and go to C/C++ tab + and select the Preprocessor category . Add the include directories to + the JNI header files under "Additional include directories", eg + "C:\jdk1.3\include,C:\jdk1.3\include\win32".</LI> +<LI>Next, select the settings for the entire project and go to Link tab + and select the General category. Set the name of the output file to + match the name of your Java module (ie. example.dll).</LI> +<LI>Next, select the example.c and example_wrap.c files and go to the + C/C++ tab and select the Precompiled Headers tab in the project + settings. Disabling precompiled headers for these files will overcome + any precompiled header errors while building.</LI> +<LI>Finally, add the java compilation as a post build rule in the + Post-build step tab in project settings, eg, "c:\jdk1.3\bin\javac + *.java"</LI> +<LI>Build your project.</LI> +</UL> +<P> Note: If using C++, choose a C++ suffix for the wrapper file, for + example <TT>example_wrap.cxx</TT>. Use <TT>_wrap.cxx</TT> instead of <TT> +_wrap.c</TT> in the instructions above and add -c++ when invoking swig.</P> +<P> Now, assuming all went well, SWIG will be automatically invoked when + you build your project. When doing a build, any changes made to the + interface file will result in SWIG being automatically invoked to + produce a new version of the wrapper file.</P> +<P> The Java classes that SWIG output should also be compiled into + .class files. To run the native code in the DLL (example.dll), make + sure that it is in your path then run your Java program which uses it, + as described in the previous section. If the library fails to load have + a look at <A href="#dynamic_linking_problems">Dynamic linking problems</A> +.</P> +<H4><A name="nmake"></A>21.2.8.2 Using NMAKE</H4> +<P> Alternatively, a Makefile for use by NMAKE can be written. Make sure + the environment variables for MSVC++ are available and the MSVC++ tools + are in your path. Now, just write a short Makefile like this :</P> +<DIV class="code"> +<PRE> +# Makefile for using SWIG and Java for C code + +SRCS = example.c +IFILE = example +INTERFACE = $(IFILE).i +WRAPFILE = $(IFILE)_wrap.c + +# Location of the Visual C++ tools (32 bit assumed) + +TOOLS = c:\msdev +TARGET = example.dll +CC = $(TOOLS)\bin\cl.exe +LINK = $(TOOLS)\bin\link.exe +INCLUDE32 = -I$(TOOLS)\include +MACHINE = IX86 + +# C Library needed to build a DLL + +DLLIBC = msvcrt.lib oldnames.lib + +# Windows libraries that are apparently needed +WINLIB = kernel32.lib advapi32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib + +# Libraries common to all DLLs +LIBS = $(DLLIBC) $(WINLIB) + +# Linker options +LOPT = -debug:full -debugtype:cv /NODEFAULTLIB /RELEASE /NOLOGO \ + /MACHINE:$(MACHINE) -entry:_DllMainCRTStartup@12 -dll + +# C compiler flags + +CFLAGS = /Z7 /Od /c /nologo +JAVA_INCLUDE = -ID:\jdk1.3\include -ID:\jdk1.3\include\win32 + +java:: + swig -java -o $(WRAPFILE) $(INTERFACE) + $(CC) $(CFLAGS) $(JAVA_INCLUDE) $(SRCS) $(WRAPFILE) + set LIB=$(TOOLS)\lib + $(LINK) $(LOPT) -out:example.dll $(LIBS) example.obj example_wrap.obj + javac *.java +</PRE> +</DIV> +<P> To build the DLL and compile the java code, run NMAKE (you may need + to run <TT>vcvars32</TT> first). This is a pretty simplistic Makefile, + but hopefully its enough to get you started. Of course you may want to + make changes for it to work for C++ by adding in the -c++ command line + switch for swig and replacing .c with .cxx.</P> +<H2><A name="java_basic_tour"></A>21.3 A tour of basic C/C++ wrapping</H2> +<P> By default, SWIG attempts to build a natural Java interface to your + C/C++ code. Functions are wrapped as functions, classes are wrapped as + classes, variables are wrapped with JavaBean type getters and setters + and so forth. This section briefly covers the essential aspects of this + wrapping.</P> +<H3><A name="module_packages_classes"></A>21.3.1 Modules, packages and + generated Java classes</H3> +<P> The SWIG <TT>%module</TT> directive specifies the name of the Java + module. When you specify `<TT>%module example</TT>', the<I> module name</I> + determines the name of some of the generated files in the module. The + generated code consists of a<I> module class</I> file <TT>example.java</TT> +, an<I> intermediary JNI class</I> file, <TT>exampleJNI.java</TT> as + well as numerous other Java<I> proxy class</I> files. Each proxy class + is named after the structs, unions and classes you are wrapping. You + may also get a<I> constants interface</I> file if you are wrapping any + unnamed enumerations or constants, for example <TT> +exampleConstants.java</TT>. When choosing a module name, make sure you + don't use the same name as one of the generated proxy class files nor a + Java keyword. Sometimes a C/C++ type cannot be wrapped by a proxy + class, for example a pointer to a primitive type. In these situations a<I> + type wrapper class</I> is generated. Wrapping an enum generates an<I> + enum class</I>, either a proper Java enum or a Java class that + simulates the enums pattern. Details of all these generated classes + will unfold as you read this section.</P> +<P> The JNI (C/C++) code is generated into a file which also contains + the module name, for example <TT>example_wrap.cxx</TT> or <TT> +example_wrap.c</TT>. These C or C++ files complete the contents of the + module.</P> +<P> The generated Java classes can be placed into a Java package by + using the <TT>-package</TT> commandline option. This is often combined + with the <TT>-outdir</TT> to specify a package directory for generating + the Java files.</P> +<DIV class="code"> +<PRE> +swig -java -package com.bloggs.swig -outdir com/bloggs/swig example.i +</PRE> +</DIV> SWIG won't create the directory, so make sure it exists + beforehand. +<H3><A name="functions"></A>21.3.2 Functions</H3> +<P> There is no such thing as a global Java function so global C + functions are wrapped as static methods in the module class. For + example,</P> +<DIV class="code"> +<PRE> +%module example +int fact(int n); + +</PRE> +</DIV> +<P> creates a static function that works exactly like you think it + might:</P> +<DIV class="code"> +<PRE> +public class example { + public static int fact(int n) { + // makes call using JNI to the C function + } +} +</PRE> +</DIV> +<P> The Java class <TT>example</TT> is the<I> module class</I>. The + function can be used as follows from Java:</P> +<DIV class="code"> +<PRE> +System.out.println(example.fact(4)); +</PRE> +</DIV> +<H3><A name="global_variables"></A>21.3.3 Global variables</H3> +<P> C/C++ global variables are fully supported by SWIG. Java does not + allow the overriding of the dot operator so all variables are accessed + through getters and setters. Again because there is no such thing as a + Java global variable, access to C/C++ global variables is done through + static getter and setter functions in the module class.</P> +<DIV class="code"> +<PRE> +// SWIG interface file with global variables +%module example +... +%inline %{ +extern int My_variable; +extern double density; +%} +... +</PRE> +</DIV> +<P> Now in Java :</P> +<DIV class="code"> +<PRE> +// Print out value of a C global variable +System.out.println("My_variable = " + example.getMy_variable()); +// Set the value of a C global variable +example.setDensity(0.8442); +</PRE> +</DIV> +<P> The value returned by the getter will always be up to date even if + the value is changed in C. Note that the getters and setters produced + follow the JavaBean property design pattern. That is the first letter + of the variable name is capitalized and preceded with set or get. If + you have the misfortune of wrapping two variables that differ only in + the capitalization of their first letters, use %rename to change one of + the variable names. For example:</P> +<DIV class="code"> +<PRE> +%rename Clash RenamedClash; +float Clash; +int clash; +</PRE> +</DIV> +<P> If a variable is declared as <TT>const</TT>, it is wrapped as a + read-only variable. That is only a getter is produced.</P> +<P> To make ordinary variables read-only, you can use the <TT>%immutable</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +%{ +extern char *path; +%} +%immutable; +extern char *path; +%mutable; +</PRE> +</DIV> +<P> The <TT>%immutable</TT> directive stays in effect until it is + explicitly disabled or cleared using <TT>%mutable</TT>. See the <A href="#SWIG_readonly_variables"> +Creating read-only variables</A> section for further details.</P> +<P> If you just want to make a specific variable immutable, supply a + declaration name. For example:</P> +<DIV class="code"> +<PRE> +%{ +extern char *path; +%} +%immutable path; +... +extern char *path; // Read-only (due to %immutable) +</PRE> +</DIV> +<H3><A name="constants"></A>21.3.4 Constants</H3> +<P> C/C++ constants are wrapped as Java static final variables. To + create a constant, use <TT>#define</TT> or the <TT>%constant</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +#define PI 3.14159 +#define VERSION "1.0" +%constant int FOO = 42; +%constant const char *path = "/usr/local"; +</PRE> +</DIV> +<P> By default the generated static final variables are initialized by + making a JNI call to get their value. The constants are generated into + the constants interface and look like this:</P> +<DIV class="code"> +<PRE> +public interface exampleConstants { + public final static double PI = exampleJNI.PI_get(); + public final static String VERSION = exampleJNI.VERSION_get(); + public final static int FOO = exampleJNI.FOO_get(); + public final static String path = exampleJNI.path_get(); +} +</PRE> +</DIV> +<P> Note that SWIG has inferred the C type and used an appropriate Java + type that will fit the range of all possible values for the C type. By + default SWIG generates<B> runtime constants</B>. They are not<B> + compiler constants</B> that can, for example, be used in a switch + statement. This can be changed by using the <TT>%javaconst(flag)</TT> + directive. It works like all the other <A href="#features">%feature + directives</A>. The default is <TT>%javaconst(0)</TT>. It is possible + to initialize all wrapped constants from pure Java code by placing a <TT> +%javaconst(1)</TT><B> before</B> SWIG parses the constants. Putting it + at the top of your interface file would ensure this. Here is an + example:</P> +<DIV class="code"> +<PRE> +%javaconst(1); +%javaconst(0) BIG; +%javaconst(0) LARGE; + +#define EXPRESSION (0x100+5) +#define BIG 1000LL +#define LARGE 2000ULL +</PRE> +</DIV> +<P> generates:</P> +<DIV class="code"> +<PRE> +public interface exampleConstants { + public final static int EXPRESSION = (0x100+5); + public final static long BIG = exampleJNI.BIG_get(); + public final static java.math.BigInteger LARGE = exampleJNI.LARGE_get(); +} +</PRE> +</DIV> +<P> Note that SWIG has inferred the C <TT>long long</TT> type from <TT> +BIG</TT> and used an appropriate Java type (<TT>long</TT>) as a Java <TT> +long</TT> is the smallest sized Java type that will take all possible + values for a C <TT>long long</TT>. Similarly for <TT>LARGE</TT>.</P> +<P> Be careful using the <TT>%javaconst(1)</TT> directive as not all C + code will compile as Java code. For example neither the <TT>1000LL</TT> + value for <TT>BIG</TT> nor <TT>2000ULL</TT> for <TT>LARGE</TT> above + would generate valid Java code. The example demonstrates how you can + target particular constants (<TT>BIG</TT> and <TT>LARGE</TT>) with <TT> +%javaconst</TT>. SWIG doesn't use <TT>%javaconst(1)</TT> as the default + as it tries to generate code that will always compile. However, using a + <TT>%javaconst(1)</TT> at the top of your interface file is strongly + recommended as the preferred compile time constants will be generated + and most C constants will compile as Java code and in any case the odd + constant that doesn't can be fixed using <TT>%javaconst(0)</TT>.</P> +<P> There is an alternative directive which can be used for these rare + constant values that won't compile as Java code. This is the <TT> +%javaconstvalue(value)</TT> directive, where <TT>value</TT> is a Java + code replacement for the C constant and can be either a string or a + number. This is useful if you do not want to use either the parsed C + value nor a JNI call, such as when the C parsed value will not compile + as Java code and a compile time constant is required. The same example + demonstrates this:</P> +<DIV class="code"> +<PRE> +%javaconst(1); +%javaconstvalue("new java.math.BigInteger(\"2000\")") LARGE; +%javaconstvalue(1000) BIG; + +#define EXPRESSION (0x100+5) +#define BIG 1000LL +#define LARGE 2000ULL +</PRE> +</DIV> +<P> Note the string quotes for <TT>"2000"</TT> are escaped. The + following is then generated:</P> +<DIV class="code"> +<PRE> +public interface exampleConstants { + public final static int EXPRESSION = (0x100+5); + public final static long BIG = 1000; + public final static java.math.BigInteger LARGE = new java.math.BigInteger("2000"); +} +</PRE> +</DIV> +<P> Note: declarations declared as <TT>const</TT> are wrapped as + read-only variables and will be accessed using a getter as described in + the previous section. They are not wrapped as constants. The exception + to this rule are static const integral values defined within a + class/struct, where they are wrapped as constants, eg:.</P> +<DIV class="code"> +<PRE> +struct Maths { + static const int FIVE = 5; +}; +</PRE> +</DIV> +<P><B> Compatibility Note:</B> In SWIG-1.3.19 and earlier releases, the + constants were generated into the module class and the constants + interface didn't exist. Backwards compatibility is maintained as the + module class implements the constants interface (even though some + consider this type of interface implementation to be bad practice):</P> +<DIV class="code"> +<PRE> +public class example implements exampleConstants { +} +</PRE> +</DIV> +<P> You thus have the choice of accessing these constants from either + the module class or the constants interface, for example, <TT> +example.EXPRESSION</TT> or <TT>exampleConstants.EXPRESSION</TT>. Or if + you decide this practice isn't so bad and your own class implements <TT> +exampleConstants</TT>, you can of course just use <TT>EXPRESSION</TT>.</P> +<H3><A name="enumerations"></A>21.3.5 Enumerations</H3> +<P> SWIG handles both named and unnamed (anonymous) enumerations. There + is a choice of approaches to wrapping named C/C++ enums. This is due to + historical reasons as SWIG's initial support for enums was limited and + Java did not originally have support for enums. Each approach has + advantages and disadvantages and it is important for the user to decide + which is the most appropriate solution. There are four approaches of + which the first is the default approach based on the so called Java + typesafe enum pattern. The second generates proper Java enums. The + final two approaches use simple integers for each enum item. Before + looking at the various approaches for wrapping named C/C++ enums, + anonymous enums are considered.</P> +<H4><A name="anonymous_enums"></A>21.3.5.1 Anonymous enums</H4> +<P> There is no name for anonymous enums and so they are handled like + constants. For example:</P> +<DIV class="code"> +<PRE> +enum { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P> is wrapped into the constants interface, in a similar manner as + constants (see previous section):</P> +<DIV class="code"> +<PRE> +public interface exampleConstants { + public final static int ALE = exampleJNI.ALE_get(); + public final static int LAGER = exampleJNI.LAGER_get(); + public final static int STOUT = exampleJNI.STOUT_get(); + public final static int PILSNER = exampleJNI.PILSNER_get(); + public final static int PILZ = exampleJNI.PILZ_get(); +} +</PRE> +</DIV> +<P> The <TT>%javaconst(flag)</TT> and <TT>%javaconstvalue(value)</TT> + directive introduced in the previous section on constants can also be + used with enums. As is the case for constants, the default is <TT> +%javaconst(0)</TT> as not all C values will compile as Java code. + However, it is strongly recommended to add in a <TT>%javaconst(1)</TT> + directive at the top of your interface file as it is only on very rare + occasions that this will produce code that won't compile under Java. + Using <TT>%javaconst(1)</TT> will ensure compile time constants are + generated, thereby allowing the enum values to be used in Java switch + statements. Example usage:</P> +<DIV class="code"> +<PRE> +%javaconst(1); +%javaconst(0) PILSNER; +enum { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P> generates:</P> +<DIV class="code"> +<PRE> +public interface exampleConstants { + public final static int ALE = 0; + public final static int LAGER = 10; + public final static int STOUT = LAGER + 1; + public final static int PILSNER = exampleJNI.PILSNER_get(); + public final static int PILZ = PILSNER; +} +</PRE> +</DIV> +<P> As in the case of constants, you can access them through either the + module class or the constants interface, for example, <TT>example.ALE</TT> + or <TT>exampleConstants.ALE</TT>.</P> +<H4><A name="typesafe_enums"></A>21.3.5.2 Typesafe enums</H4> +<P> This is the default approach to wrapping named enums. The typesafe + enum pattern is a relatively well known construct to work around the + lack of enums in versions of Java prior to JDK 1.5. It basically + defines a class for the enumeration and permits a limited number of + final static instances of the class. Each instance equates to an enum + item within the enumeration. The implementation is in the + "enumtypesafe.swg" file. Let's look at an example:</P> +<DIV class="code"> +<PRE> +%include "enumtypesafe.swg" // optional as typesafe enums are the default +enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P>will generate:</P> +<DIV class="code"> +<PRE> +public final class Beverage { + public final static Beverage ALE = new Beverage("ALE"); + public final static Beverage LAGER = new Beverage("LAGER", exampleJNI.LAGER_get()); + public final static Beverage STOUT = new Beverage("STOUT"); + public final static Beverage PILSNER = new Beverage("PILSNER"); + public final static Beverage PILZ = new Beverage("PILZ", exampleJNI.PILZ_get()); + [... additional support methods omitted for brevity ...] +} +</PRE> +</DIV> +<P> See <A href="#typesafe_enums_classes">Typesafe enum classes</A> to + see the omitted support methods. Note that the enum item with an + initializer (LAGER) is initialized with the enum value obtained via a + JNI call. However, as with anonymous enums and constants, use of the <TT> +%javaconst</TT> directive is strongly recommended to change this + behaviour:</P> +<DIV class="code"> +<PRE> +%include "enumtypesafe.swg" // optional as typesafe enums are the default +%javaconst(1); +enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P> will generate:</P> +<DIV class="code"> +<PRE> +public final class Beverage { + public final static Beverage ALE = new Beverage("ALE"); + public final static Beverage LAGER = new Beverage("LAGER", 10); + public final static Beverage STOUT = new Beverage("STOUT"); + public final static Beverage PILSNER = new Beverage("PILSNER"); + public final static Beverage PILZ = new Beverage("PILZ", PILSNER); + [... additional support methods omitted for brevity ...] +} +</PRE> +</DIV> +<P> The generated code is easier to read and more efficient as a true + constant is used instead of a JNI call. As is the case for constants, + the default is <TT>%javaconst(0)</TT> as not all C values will compile + as Java code. However, it is recommended to add in a <TT>%javaconst(1)</TT> + directive at the top of your interface file as it is only on very rare + occasions that this will produce code that won't compile under Java. + The <TT>%javaconstvalue(value)</TT> directive can also be used for + typesafe enums. Note that global enums are generated into a Java class + within whatever package you are using. C++ enums defined within a C++ + class are generated into a static final inner Java class within the + Java proxy class.</P> +<P> Typesafe enums have their advantages over using plain integers in + that they they can be used in a typesafe manner. However, there are + limitations. For example, they cannot be used in switch statements and + serialization is an issue. Please look at the following references for + further information: <A href="http://java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums"> +Replace Enums with Classes</A> in<I> Effective Java Programming</I> on + the Sun website, <A href="http://www.javaworld.com/javaworld/jw-07-1997/jw-07-enumerated.html"> +Create enumerated constants in Java</A> JavaWorld article, <A href="http://www.javaworld.com/javaworld/javatips/jw-javatip133.html"> +Java Tip 133: More on typesafe enums</A> and <A href="http://www.javaworld.com/javaworld/javatips/jw-javatip122.html"> +Java Tip 122: Beware of Java typesafe enumerations</A> JavaWorld tips.</P> +<P> Note that the syntax required for using typesafe enums is the same + as that for proper Java enums. This is useful during the period that a + project has to support legacy versions of Java. When upgrading to JDK + 1.5 or later, proper Java enums could be used instead, without users + having to change their code. The following section details proper Java + enum generation.</P> +<H4><A name="proper_enums"></A>21.3.5.3 Proper Java enums</H4> +<P> Proper Java enums were only introduced in JDK 1.5 so this approach + is only compatible with more recent versions of Java. Java enums have + been designed to overcome all the limitations of both typesafe and type + unsafe enums and should be the choice solution, provided older versions + of Java do not have to be supported. In this approach, each named C/C++ + enum is wrapped by a Java enum. Java enums, by default, do not support + enums with initializers. Java enums are in many respects similar to + Java classes in that they can be customised with additional methods. + SWIG takes advantage of this feature to facilitate wrapping C/C++ enums + that have initializers. In order to wrap all possible C/C++ enums using + proper Java enums, the "enums.swg" file must be used. Let's take a look + at an example.</P> +<DIV class="code"> +<PRE> +%include "enums.swg" +%javaconst(1); +enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P> will generate:</P> +<DIV class="code"> +<PRE> +public enum Beverage { + ALE, + LAGER(10), + STOUT, + PILSNER, + PILZ(PILSNER); + [... additional support methods omitted for brevity ...] +} +</PRE> +</DIV> +<P> See <A href="#proper_enums_classes">Proper Java enum classes</A> to + see the omitted support methods. The generated Java enum has numerous + additional methods to support enums with initializers, such as <TT> +LAGER</TT> above. Note that as with the typesafe enum pattern, enum + items with initializers are by default initialized with the enum value + obtained via a JNI call. However, this is not the case above as we have + used the recommended <TT>%javaconst(1)</TT> to avoid the JNI call. The <TT> +%javaconstvalue(value)</TT> directive covered in the <A href="#constants"> +Constants</A> section can also be used for proper Java enums.</P> +<P> The additional support methods need not be generated if none of the + enum items have initializers and this is covered later in the <A href="#simpler_enum_classes"> +Simpler Java enums for enums without initializers</A> section.</P> +<H4><A name="typeunsafe_enums"></A>21.3.5.4 Type unsafe enums</H4> +<P> In this approach each enum item in a named enumeration is wrapped as + a static final integer in a class named after the C/C++ enum name. This + is a commonly used pattern in Java to simulate C/C++ enums, but it is + not typesafe. However, the main advantage over the typesafe enum + pattern is enum items can be used in switch statements. In order to use + this approach, the "enumtypeunsafe.swg" file must be used. Let's take a + look at an example.</P> +<DIV class="code"> +<PRE> +%include "enumtypeunsafe.swg" +%javaconst(1); +enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P> will generate:</P> +<DIV class="code"> +<PRE> +public final class Beverage { + public final static int ALE = 0; + public final static int LAGER = 10; + public final static int STOUT = LAGER + 1; + public final static int PILSNER = STOUT + 1; + public final static int PILZ = PILSNER; +} +</PRE> +</DIV> +<P> As is the case previously, the default is <TT>%javaconst(0)</TT> as + not all C/C++ values will compile as Java code. However, again it is + recommended to add in a <TT>%javaconst(1)</TT> directive. and the <TT> +%javaconstvalue(value)</TT> directive covered in the <A href="#constants"> +Constants</A> section can also be used for type unsafe enums. Note that + global enums are generated into a Java class within whatever package + you are using. C++ enums defined within a C++ class are generated into + a static final inner Java class within the Java proxy class.</P> +<P> Note that unlike typesafe enums, this approach requires users to + mostly use different syntax compared with proper Java enums. Thus the + upgrade path to proper enums provided in JDK 1.5 is more painful.</P> +<H4><A name="simple_enums"></A>21.3.5.5 Simple enums</H4> +<P> This approach is similar to the type unsafe approach. Each enum item + is also wrapped as a static final integer. However, these integers are + not generated into a class named after the C/C++ enum. Instead, global + enums are generated into the constants interface. Also, enums defined + in a C++ class have their enum items generated directly into the Java + proxy class rather than an inner class within the Java proxy class. In + fact, this approach is effectively wrapping the enums as if they were + anonymous enums and the resulting code is as per <A href="#anonymous_enums"> +anonymous enums</A>. The implementation is in the "enumsimple.swg" file.</P> +<P><B> Compatibility Note:</B> SWIG-1.3.21 and earlier versions wrapped + all enums using this approach. The type unsafe approach is preferable + to this one and this simple approach is only included for backwards + compatibility with these earlier versions of SWIG.</P> +<H3><A name="pointers"></A>21.3.6 Pointers</H3> +<P> C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no + problem working with incomplete type information. Here is a rather + simple interface:</P> +<DIV class="code"> +<PRE> +%module example + +FILE *fopen(const char *filename, const char *mode); +int fputs(const char *, FILE *); +int fclose(FILE *); +</PRE> +</DIV> +<P> When wrapped, you will be able to use the functions in a natural way + from Java. For example:</P> +<DIV class="code"> +<PRE> +SWIGTYPE_p_FILE f = example.fopen("junk","w"); +example.fputs("Hello World\n", f); +example.fclose(f); +</PRE> +</DIV> +<P> C pointers in the Java module are stored in a Java <TT>long</TT> and + cross the JNI boundary held within this 64 bit number. Many other SWIG + language modules use an encoding of the pointer in a string. These + scripting languages use the SWIG runtime type checker for dynamic type + checking as they do not support static type checking by a compiler. In + order to implement static type checking of pointers within Java, they + are wrapped by a simple Java class. In the example above the <TT>FILE *</TT> + pointer is wrapped with a<I> type wrapper class</I> called <TT> +SWIGTYPE_p_FILE</TT>.</P> +<P> Once obtained, a type wrapper object can be freely passed around to + different C functions that expect to receive an object of that type. + The only thing you can't do is dereference the pointer from Java. Of + course, that isn't much of a concern in this example.</P> +<P> As much as you might be inclined to modify a pointer value directly + from Java, don't. The value is not necessarily the same as the logical + memory address of the underlying object. The value will vary depending + on the native byte-ordering of the platform (i.e., big-endian vs. + little-endian). Most JVMs are 32 bit applications so any JNI code must + also be compiled as 32 bit. The net result is pointers in JNI code are + also 32 bits and are stored in the high order 4 bytes on big-endian + machines and in the low order 4 bytes on little-endian machines. By + design it is also not possible to manually cast a pointer to a new type + by using Java casts as it is particularly dangerous especially when + casting C++ objects. If you need to cast a pointer or change its value, + consider writing some helper functions instead. For example:</P> +<DIV class="code"> +<PRE> +%inline %{ +/* C-style cast */ +Bar *FooToBar(Foo *f) { + return (Bar *) f; +} + +/* C++-style cast */ +Foo *BarToFoo(Bar *b) { + return dynamic_cast<Foo*>(b); +} + +Foo *IncrFoo(Foo *f, int i) { + return f+i; +} +%} +</PRE> +</DIV> +<P> Also, if working with C++, you should always try to use the new C++ + style casts. For example, in the above code, the C-style cast may + return a bogus result whereas as the C++-style cast will return a NULL + pointer if the conversion can't be performed.</P> +<H3><A name="structures"></A>21.3.7 Structures</H3> +<P> If you wrap a C structure, it is wrapped by a Java class with + getters and setters for access to the member variables. For example,</P> +<DIV class="code"> +<PRE> +struct Vector { + double x,y,z; +}; + +</PRE> +</DIV> +<P> is used as follows:</P> +<DIV class="code"> +<PRE> +Vector v = new Vector(); +v.setX(3.5); +v.setY(7.2); +double x = v.getX(); +double y = v.getY(); +</PRE> +</DIV> +<P> The variable setters and getters are also based on the JavaBean + design pattern already covered under the Global variables section. + Similar access is provided for unions and the public data members of + C++ classes.</P> +<P> This object is actually an instance of a Java class that has been + wrapped around a pointer to the C structure. This instance doesn't + actually do anything--it just serves as a proxy. The pointer to the C + object is held in the Java proxy class in much the same way as pointers + are held by type wrapper classes. Further details about Java proxy + classes are covered a little later.</P> +<P> <TT>const</TT> members of a structure are read-only. Data members + can also be forced to be read-only using the <TT>%immutable</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +struct Foo { + ... + %immutable; + int x; /* Read-only members */ + char *name; + %mutable; + ... +}; +</PRE> +</DIV> +<P> When <TT>char *</TT> members of a structure are wrapped, the + contents are assumed to be dynamically allocated using <TT>malloc</TT> + or <TT>new</TT> (depending on whether or not SWIG is run with the -c++ + option). When the structure member is set, the old contents will be + released and a new value created. If this is not the behavior you want, + you will have to use a typemap (described later).</P> +<P> If a structure contains arrays, access to those arrays is managed + through pointers. For example, consider this:</P> +<DIV class="code"> +<PRE> +struct Bar { + int x[16]; +}; +</PRE> +</DIV> +<P> If accessed in Java, you will see behavior like this:</P> +<DIV class="code"> +<PRE> +Bar b = new Bar(); +SWIGTYPE_p_int x = b.getX(); +</PRE> +</DIV> +<P> This pointer can be passed around to functions that expect to + receive an <TT>int *</TT> (just like C). You can also set the value of + an array member using another pointer. For example:</P> +<DIV class="code"> +<PRE> +Bar b = new Bar(); +SWIGTYPE_p_int x = b.getX(); +Bar c = new Bar(); +c.setX(x); // Copy contents of b.x to c.x +</PRE> +</DIV> +<P> For array assignment (setters not getters), SWIG copies the entire + contents of the array starting with the data pointed to by <TT>b.x</TT> +. In this example, 16 integers would be copied. Like C, SWIG makes no + assumptions about bounds checking---if you pass a bad pointer, you may + get a segmentation fault or access violation. The default wrapping + makes it hard to set or get just one element of the array and so array + access from Java is somewhat limited. This can be changed easily though + by using the approach outlined later in the <A href="#c_arrays"> +Wrapping C arrays with Java arrays</A> and <A href="#unbounded_c_arrays"> +Unbounded C Arrays</A> sections.</P> +<P> When a member of a structure is itself a structure, it is handled as + a pointer. For example, suppose you have two structures like this:</P> +<DIV class="code"> +<PRE> +struct Foo { + int a; +}; + +struct Bar { + Foo f; +}; +</PRE> +</DIV> +<P> Now, suppose that you access the <TT>f</TT> member of <TT>Bar</TT> + like this:</P> +<DIV class="code"> +<PRE> +Bar b = new Bar(); +Foo x = b.getF(); +</PRE> +</DIV> +<P> In this case, <TT>x</TT> is a pointer that points to the <TT>Foo</TT> + that is inside <TT>b</TT>. This is the same value as generated by this + C code:</P> +<DIV class="code"> +<PRE> +Bar b; +Foo *x = &b->f; /* Points inside b */ +</PRE> +</DIV> +<P> Because the pointer points inside the structure, you can modify the + contents and everything works just like you would expect. For example:</P> +<DIV class="code"> +<PRE> +Bar b = new Bar(); +b.getF().setA(3); // Modify b.f.a +Foo x = b.getF(); +x.setA(3); // Modify x.a - this is the same as b.f.a +</PRE> +</DIV> +<H3><A name="classes"></A>21.3.8 C++ classes</H3> +<P> C++ classes are wrapped by Java classes as well. For example, if you + have this class,</P> +<DIV class="code"> +<PRE> +class List { +public: + List(); + ~List(); + int search(char *item); + void insert(char *item); + void remove(char *item); + char *get(int n); + int length; +}; +</PRE> +</DIV> +<P> you can use it in Java like this:</P> +<DIV class="code"> +<PRE> +List l = new List(); +l.insert("Ale"); +l.insert("Stout"); +l.insert("Lager"); +String item = l.get(2); +int length = l.getLength(); +</PRE> +</DIV> +<P> Class data members are accessed in the same manner as C structures.</P> +<P> Static class members are unsurprisingly wrapped as static members of + the Java class:</P> +<DIV class="code"> +<PRE> +class Spam { +public: + static void foo(); + static int bar; +}; +</PRE> +</DIV> +<P> The static members work like any other Java static member:</P> +<DIV class="code"> +<PRE> +Spam.foo(); +int bar = Spam.getBar(); +</PRE> +</DIV> +<H3><A name="inheritance"></A>21.3.9 C++ inheritance</H3> +<P> SWIG is fully aware of issues related to C++ inheritance. Therefore, + if you have classes like this</P> +<DIV class="code"> +<PRE> +class Foo { +... +}; + +class Bar : public Foo { +... +}; +</PRE> +</DIV> +<P> those classes are wrapped into a hierarchy of Java classes that + reflect the same inheritance structure:</P> +<DIV class="code"> +<PRE> +Bar b = new Bar(); +Class c = b.getClass(); +System.out.println(c.getSuperclass().getName()); +</PRE> +</DIV> +<P> will of course display:</P> +<DIV class="code"> +<PRE> +Foo +</PRE> +</DIV> +<P> Furthermore, if you have functions like this</P> +<DIV class="code"> +<PRE> +void spam(Foo *f); +</PRE> +</DIV> +<P> then the Java function <TT>spam()</TT> accepts instances of <TT>Foo</TT> + or instances of any other proxy classes derived from <TT>Foo</TT>.</P> +<P> Note that Java does not support multiple inheritance so any multiple + inheritance in the C++ code is not going to work. A warning is given + when multiple inheritance is detected and only the first base class is + used.</P> +<H3><A name="pointers_refs_arrays"></A>21.3.10 Pointers, references, + arrays and pass by value</H3> +<P> In C++, there are many different ways a function might receive and + manipulate objects. For example:</P> +<DIV class="code"> +<PRE> +void spam1(Foo *x); // Pass by pointer +void spam2(Foo &x); // Pass by reference +void spam3(Foo x); // Pass by value +void spam4(Foo x[]); // Array of objects +</PRE> +</DIV> +<P> In Java, there is no detailed distinction like this--specifically, + there are only instances of classes. There are no pointers nor + references. Because of this, SWIG unifies all of these types together + in the wrapper code. For instance, if you actually had the above + functions, it is perfectly legal to do this from Java:</P> +<DIV class="code"> +<PRE> +Foo f = new Foo(); // Create a Foo +example.spam1(f); // Ok. Pointer +example.spam2(f); // Ok. Reference +example.spam3(f); // Ok. Value. +example.spam4(f); // Ok. Array (1 element) +</PRE> +</DIV> +<P> Similar behavior occurs for return values. For example, if you had + functions like this,</P> +<DIV class="code"> +<PRE> +Foo *spam5(); +Foo &spam6(); +Foo spam7(); +</PRE> +</DIV> +<P> then all three functions will return a pointer to some <TT>Foo</TT> + object. Since the third function (spam7) returns a value, newly + allocated memory is used to hold the result and a pointer is returned + (Java will release this memory when the returned object's finalizer is + run by the garbage collector).</P> +<H4><A name="null_pointers"></A>21.3.10.1 Null pointers</H4> +<P> Working with null pointers is easy. A Java <TT>null</TT> can be used + whenever a method expects a proxy class or typewrapper class. However, + it is not possible to pass null to C/C++ functions that take parameters + by value or by reference. If you try you will get a + NullPointerException.</P> +<DIV class="code"> +<PRE> +example.spam1(null); // Pointer - ok +example.spam2(null); // Reference - NullPointerException +example.spam3(null); // Value - NullPointerException +example.spam4(null); // Array - ok +</PRE> +</DIV> +<P> For <TT>spam1</TT> and <TT>spam4</TT> above the Java <TT>null</TT> + gets translated into a NULL pointer for passing to the C/C++ function. + The converse also occurs, that is, NULL pointers are translated into <TT> +null</TT> Java objects when returned from a C/C++ function.</P> +<H3><A name="overloaded_functions"></A>21.3.11 C++ overloaded functions</H3> +<P> C++ overloaded functions, methods, and constructors are mostly + supported by SWIG. For example, if you have two functions like this:</P> +<DIV class="code"> +<PRE> +%module example + +void foo(int); +void foo(char *c); +</PRE> +</DIV> +<P> You can use them in Java in a straightforward manner:</P> +<DIV class="code"> +<PRE> +example.foo(3); // foo(int) +example.foo("Hello"); // foo(char *c) +</PRE> +</DIV> +<P> Similarly, if you have a class like this,</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + Foo(const Foo &); + ... +}; +</PRE> +</DIV> +<P> you can write Java code like this:</P> +<DIV class="code"> +<PRE> +Foo f = new Foo(); // Create a Foo +Foo g = new Foo(f); // Copy f +</PRE> +</DIV> +<P> Overloading support is not quite as flexible as in C++. Sometimes + there are methods that SWIG cannot disambiguate as there can be more + than one C++ type mapping onto a single Java type. For example:</P> +<DIV class="code"> +<PRE> +void spam(int); +void spam(unsigned short); +</PRE> +</DIV> +<P> Here both int and unsigned short map onto a Java int. Here is + another example:</P> +<DIV class="code"> +<PRE> +void foo(Bar *b); +void foo(Bar &b); +</PRE> +</DIV> +<P> If declarations such as these appear, you will get a warning message + like this:</P> +<DIV class="code"> +<PRE> +example.i:12: Warning(515): Overloaded method spam(unsigned short) ignored. +Method spam(int) at example.i:11 used. +</PRE> +</DIV> +<P> To fix this, you either need to either <A href="#SWIG_rename_ignore"> +rename or ignore</A> one of the methods. For example:</P> +<DIV class="code"> +<PRE> +%rename(spam_ushort) spam(unsigned short); +... +void spam(int); +void spam(unsigned short); // Now renamed to spam_ushort +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +%ignore spam(unsigned short); +... +void spam(int); +void spam(unsigned short); // Ignored +</PRE> +</DIV> +<H3><A name="java_default_arguments"></A>21.3.12 C++ default arguments</H3> +<P> Any function with a default argument is wrapped by generating an + additional function for each argument that is defaulted. For example, + if we have the following C++:</P> +<DIV class="code"> +<PRE> +%module example + +void defaults(double d=10.0, int i=0); +</PRE> +</DIV> +<P> The following methods are generated in the Java module class:</P> +<DIV class="code"> +<PRE> +public class example { + public static void defaults(double d, int i) { ... } + public static void defaults(double d) { ... } + public static void defaults() { ... } +} +</PRE> +</DIV> +<P> It is as if SWIG had parsed three separate overloaded methods. The + same approach is taken for static methods, constructors and member + methods.</P> +<P><B> Compatibility note:</B> Versions of SWIG prior to SWIG-1.3.23 + wrapped these with a single wrapper method and so the default values + could not be taken advantage of from Java. Further details on default + arguments and how to restore this approach are given in the more + general <A href="#SWIGPlus_default_args">Default arguments</A> section.</P> +<H3><A name="namespaces"></A>21.3.13 C++ namespaces</H3> +<P> SWIG is aware of C++ namespaces, but namespace names do not appear + in the module nor do namespaces result in a module that is broken up + into submodules or packages. For example, if you have a file like this,</P> +<DIV class="code"> +<PRE> +%module example + +namespace foo { + int fact(int n); + struct Vector { + double x,y,z; + }; +}; +</PRE> +</DIV> +<P> it works in Java as follows:</P> +<DIV class="code"> +<PRE> +int f = example.fact(3); +Vector v = new Vector(); +v.setX(3.4); +double y = v.getY(); +</PRE> +</DIV> +<P> If your program has more than one namespace, name conflicts (if any) + can be resolved using <TT>%rename</TT> For example:</P> +<DIV class="code"> +<PRE> +%rename(Bar_spam) Bar::spam; + +namespace Foo { + int spam(); +} + +namespace Bar { + int spam(); +} +</PRE> +</DIV> +<P> If you have more than one namespace and you want to keep their + symbols separate, consider wrapping them as separate SWIG modules. Each + SWIG module can be placed into a separate package.</P> +<H3><A name="templates"></A>21.3.14 C++ templates</H3> +<P> C++ templates don't present a huge problem for SWIG. However, in + order to create wrappers, you have to tell SWIG to create wrappers for + a particular template instantiation. To do this, you use the <TT> +%template</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%module example +%{ +#include <utility> +%} + +template<class T1, class T2> +struct pair { + typedef T1 first_type; + typedef T2 second_type; + T1 first; + T2 second; + pair(); + pair(const T1&, const T2&); + ~pair(); +}; + +%template(pairii) pair<int,int>; +</PRE> +</DIV> +<P> In Java:</P> +<DIV class="code"> +<PRE> +pairii p = new pairii(3,4); +int first = p.getFirst(); +int second = p.getSecond(); +</PRE> +</DIV> +<P> Obviously, there is more to template wrapping than shown in this + example. More details can be found in the <A href="#SWIGPlus">SWIG and + C++</A> chapter.</P> +<H3><A name="smart_pointers"></A>21.3.15 C++ Smart Pointers</H3> +<P> In certain C++ programs, it is common to use classes that have been + wrapped by so-called "smart pointers." Generally, this involves the use + of a template class that implements <TT>operator->()</TT> like this:</P> +<DIV class="code"> +<PRE> +template<class T> class SmartPtr { + ... + T *operator->(); + ... +} +</PRE> +</DIV> +<P> Then, if you have a class like this,</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int x; + int bar(); +}; +</PRE> +</DIV> +<P> A smart pointer would be used in C++ as follows:</P> +<DIV class="code"> +<PRE> +SmartPtr<Foo> p = CreateFoo(); // Created somehow (not shown) +... +p->x = 3; // Foo::x +int y = p->bar(); // Foo::bar +</PRE> +</DIV> +<P> To wrap this in Java, simply tell SWIG about the <TT>SmartPtr</TT> + class and the low-level <TT>Foo</TT> object. Make sure you instantiate <TT> +SmartPtr</TT> using <TT>%template</TT> if necessary. For example:</P> +<DIV class="code"> +<PRE> +%module example +... +%template(SmartPtrFoo) SmartPtr<Foo>; +... +</PRE> +</DIV> +<P> Now, in Java, everything should just "work":</P> +<DIV class="code"> +<PRE> +SmartPtrFoo p = example.CreateFoo(); // Create a smart-pointer somehow +p.setX(3); // Foo::x +int y = p.bar(); // Foo::bar +</PRE> +</DIV> +<P> If you ever need to access the underlying pointer returned by <TT> +operator->()</TT> itself, simply use the <TT>__deref__()</TT> method. + For example:</P> +<DIV class="code"> +<PRE> +Foo f = p.__deref__(); // Returns underlying Foo * +</PRE> +</DIV> +<H2><A name="further_details"></A>21.4 Further details on the generated + Java classes</H2> +<P> In the previous section, a high-level view of Java wrapping was + presented. A key component of this wrapping is that structures and + classes are wrapped by Java proxy classes and type wrapper classes are + used in situations where no proxies are generated. This provides a very + natural, type safe Java interface to the C/C++ code and fits in with + the Java programming paradigm. However, a number of low-level details + were omitted. This section provides a brief overview of how the proxy + classes work and then covers the type wrapper classes. Finally enum + classes are covered. First, the crucial intermediary JNI class is + considered.</P> +<H3><A name="imclass"></A>21.4.1 The intermediary JNI class</H3> +<P> In the <A href="#SWIG">"SWIG basics"</A> and <A href="#SWIGPlus"> +"SWIG and C++"</A> chapters, details of low-level structure and class + wrapping are described. To summarize those chapters, if you have a + global function and class like this</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int x; + int spam(int num, Foo* foo); +}; +void egg(Foo* chips); +</PRE> +</DIV> +<P> then SWIG transforms the class into a set of low-level procedural + wrappers. These procedural wrappers essentially perform the equivalent + of this C++ code:</P> +<DIV class="code"> +<PRE> +Foo *new_Foo() { + return new Foo(); +} +void delete_Foo(Foo *f) { + delete f; +} +int Foo_x_get(Foo *f) { + return f->x; +} +void Foo_x_set(Foo *f, int value) { + f->x = value; +} +int Foo_spam(Foo *f, int num, Foo* foo) { + return f->spam(num, foo); +} +</PRE> +</DIV> +<P> These procedural function names don't actually exist, but their + functionality appears inside the generated JNI functions. The JNI + functions have to follow a particular naming convention so the function + names are actually:</P> +<DIV class="code"> +<PRE> +SWIGEXPORT jlong JNICALL Java_exampleJNI_new_1Foo(JNIEnv *jenv, jclass jcls); +SWIGEXPORT void JNICALL Java_exampleJNI_delete_1Foo(JNIEnv *jenv, jclass jcls, + jlong jarg1); +SWIGEXPORT void JNICALL Java_exampleJNI_Foo_1x_1set(JNIEnv *jenv, jclass jcls, + jlong jarg1, jobject jarg1_, jint jarg2); +SWIGEXPORT jint JNICALL Java_exampleJNI_Foo_1x_1get(JNIEnv *jenv, jclass jcls, + jlong jarg1, jobject jarg1_); +SWIGEXPORT jint JNICALL Java_exampleJNI_Foo_1spam(JNIEnv *jenv, jclass jcls, + jlong jarg1, jobject jarg1_, jint jarg2, + jlong jarg3, jobject jarg3_); +SWIGEXPORT void JNICALL Java_exampleJNI_egg(JNIEnv *jenv, jclass jcls, + jlong jarg1, jobject jarg1_); +</PRE> +</DIV> +<P> For every JNI C function there has to be a static native Java + function. These appear in the intermediary JNI class:</P> +<DIV class="code"> +<PRE> +class exampleJNI { + public final static native long new_Foo(); + public final static native void delete_Foo(long jarg1); + public final static native void Foo_x_set(long jarg1, Foo jarg1_, int jarg2); + public final static native int Foo_x_get(long jarg1, Foo jarg1_); + public final static native int Foo_spam(long jarg1, Foo jarg1_, int jarg2, + long jarg3, Foo jarg3_); + public final static native void egg(long jarg1, Foo jarg1_); +} +</PRE> +</DIV> +<P> This class contains the complete Java - C/C++ interface so all + function calls go via this class. As this class acts as a go-between + for all JNI calls to C/C++ code from the Java <A href="#java_proxy_classes"> +proxy classes</A>, <A href="#type_wrapper_classes">type wrapper classes</A> + and <A href="#java_module_class">module class</A>, it is known as the + intermediary JNI class.</P> +<P> You may notice that SWIG uses a Java long wherever a pointer or + class object needs to be marshalled across the Java-C/C++ boundary. + This approach leads to minimal JNI code which makes for better + performance as JNI code involves a lot of string manipulation. SWIG + favours generating Java code over JNI code as Java code is compiled + into byte code and avoids the costly string operations needed in JNI + code. This approach has a downside though as the proxy class might get + collected before the native method has completed. You might notice + above that there is an additional parameters with a underscore postfix, + eg <TT>jarg1_</TT>. These are added in order to prevent <A href="#java_pgcpp"> +premature garbage collection when marshalling proxy classes</A>.</P> +<P> The functions in the intermediary JNI class cannot be accessed + outside of its package. Access to them is gained through the module + class for globals otherwise the appropriate proxy class.</P> + <A name="java_module_directive"></A> +<P> The name of the intermediary JNI class can be changed from its + default, that is, the module name with JNI appended after it. The + module directive attribute <TT>jniclassname</TT> is used to achieve + this:</P> +<DIV class="code"> +<PRE> +%module (jniclassname="name") modulename +</PRE> +</DIV> +<P> If <TT>name</TT> is the same as <TT>modulename</TT> then the module + class name gets changed from <TT>modulename</TT> to <TT> +modulenameModule</TT>.</P> +<H4><A name="imclass_pragmas"></A>21.4.1.1 The intermediary JNI class + pragmas</H4> +<P> The intermediary JNI class can be tailored through the use of + pragmas, but is not commonly done. The pragmas for this class are:</P> +<TABLE BORDER summary="Intermediary JNI class pragmas"> +<TR VALIGN="TOP"><TD><B>Pragma</B></TD><TD><B>Description</B></TD></TR> +<TR><TD>jniclassbase</TD><TD>Base class for the intermediary JNI class</TD> +</TR> +<TR><TD>jniclassclassmodifiers</TD><TD>Class modifiers and class type + for the intermediary JNI class</TD></TR> +<TR><TD>jniclasscode</TD><TD>Java code is copied verbatim into the + intermediary JNI class</TD></TR> +<TR><TD>jniclassimports</TD><TD>Java code, usually one or more import + statements, placed before the intermediary JNI class definition</TD></TR> +<TR><TD>jniclassinterfaces</TD><TD>Comma separated interface classes for + the intermediary JNI class</TD></TR> +</TABLE> +<P> The pragma code appears in the generated intermediary JNI class + where you would expect:</P> +<DIV class="code"> +<PRE> +[ jniclassimports pragma ] +[ jniclassclassmodifiers pragma ] jniclassname extends [ jniclassbase pragma ] + implements [ jniclassinterfaces pragma ] { +[ jniclasscode pragma ] +... SWIG generated native methods ... +} +</PRE> +</DIV> +<P> The <TT>jniclasscode</TT> pragma is quite useful for adding in a + static block for loading the shared library / dynamic link library and + demonstrates how pragmas work:</P> +<DIV class="code"> +<PRE> +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} +</PRE> +</DIV> +<P> Pragmas will take either <TT>""</TT> or <TT>%{ %}</TT> as + delimiters. For example, let's change the intermediary JNI class access + to public.</P> +<DIV class="code"> +<PRE> +%pragma(java) jniclassclassmodifiers="public class" +</PRE> +</DIV> +<P> All the methods in the intermediary JNI class will then be callable + outside of the package as the method modifiers are public by default.</P> +<H3><A name="java_module_class"></A>21.4.2 The Java module class</H3> +<P> All global functions and variable getters/setters appear in the + module class. For our example, there is just one function:</P> +<DIV class="code"> +<PRE> +public class example { + public static void egg(Foo chips) { + exampleJNI.egg(Foo.getCPtr(chips), chips); + } +} +</PRE> +</DIV> +<P> The module class is necessary as there is no such thing as a global + in Java so all the C globals are put into this class. They are + generated as static functions and so must be accessed as such by using + the module name in the static function call:</P> +<DIV class="code"> +<PRE> +example.egg(new Foo()); +</PRE> +</DIV> +<P> The primary reason for having the module class wrapping the calls in + the intermediary JNI class is to implement static type checking. In + this case only a <TT>Foo</TT> can be passed to the <TT>egg</TT> + function, whereas any <TT>long</TT> can be passed to the <TT>egg</TT> + function in the intermediary JNI class.</P> +<H4><A name="module_class_pragmas"></A>21.4.2.1 The Java module class + pragmas</H4> +<P> The module class can be tailored through the use of pragmas, in the + same manner as the intermediary JNI class. The pragmas are similarly + named and are used in the same way. The complete list follows:</P> +<TABLE BORDER summary="Java module class pragmas"> +<TR VALIGN="TOP"><TD><B>Pragma</B></TD><TD><B>Description</B></TD></TR> +<TR><TD>modulebase</TD><TD>Base class for the module class</TD></TR> +<TR><TD>moduleclassmodifiers</TD><TD>Class modifiers and class type for + the module class</TD></TR> +<TR><TD>modulecode</TD><TD>Java code is copied verbatim into the module + class</TD></TR> +<TR><TD>moduleimports</TD><TD>Java code, usually one or more import + statements, placed before the module class definition</TD></TR> +<TR><TD>moduleinterfaces</TD><TD>Comma separated interface classes for + the module class</TD></TR> +</TABLE> +<P> The pragma code appears in the generated module class like this:</P> +<DIV class="code"> +<PRE> +[ moduleimports pragma ] +[ modulemodifiers pragma ] modulename extends [ modulebase pragma ] + implements [ moduleinterfaces pragma ] { +[ modulecode pragma ] +... SWIG generated wrapper functions ... +} +</PRE> +</DIV> +<P> See <A href="#imclass_pragmas">The intermediary JNI class pragmas</A> + section for further details on using pragmas.</P> +<H3><A name="java_proxy_classes"></A>21.4.3 Java proxy classes</H3> +<P> A Java proxy class is generated for each structure, union or C++ + class that is wrapped. Proxy classes have also been called <A href="http://java.sun.com/developer/JDCTechTips/2001/tt0612.html#tip2"> +peer classes</A>. The default proxy class for our previous example looks + like this:</P> +<DIV class="code"> +<PRE> +public class Foo { + private long swigCPtr; + protected boolean swigCMemOwn; + + protected Foo(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(Foo obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if(swigCPtr != 0 && swigCMemOwn) { + swigCMemOwn = false; + exampleJNI.delete_Foo(swigCPtr); + } + swigCPtr = 0; + } + + public void setX(int value) { + exampleJNI.Foo_x_set(swigCPtr, this, value); + } + + public int getX() { + return exampleJNI.Foo_x_get(swigCPtr, this); + } + + public int spam(int num, Foo foo) { + return exampleJNI.Foo_spam(swigCPtr, this, num, Foo.getCPtr(foo), foo); + } + + public Foo() { + this(exampleJNI.new_Foo(), true); + } + +} +</PRE> +</DIV> +<P> This class merely holds a pointer to the underlying C++ object (<TT> +swigCPtr</TT>). It also contains all the methods in the C++ class it is + proxying plus getters and setters for public member variables. These + functions call the native methods in the intermediary JNI class. The + advantage of having this extra layer is the type safety that the proxy + class functions offer. It adds static type checking which leads to + fewer surprises at runtime. For example, you can see that if you + attempt to use the <TT>spam()</TT> function it will only compile when + the parameters passed are an <TT>int</TT> and a <TT>Foo</TT>. From a + user's point of view, it makes the class work as if it were a Java + class:</P> +<DIV class="code"> +<PRE> +Foo f = new Foo(); +f.setX(3); +int y = f.spam(5, new Foo()); +</PRE> +</DIV> +<H4><A name="memory_management"></A>21.4.3.1 Memory management</H4> +<P> Each proxy class has an ownership flag <TT>swigCMemOwn</TT>. The + value of this flag determines who is responsible for deleting the + underlying C++ object. If set to <TT>true</TT>, the proxy class's + finalizer will destroy the C++ object when the proxy class is garbage + collected. If set to false, then the destruction of the proxy class has + no effect on the C++ object.</P> +<P> When an object is created by a constructor or returned by value, + Java automatically takes ownership of the result. On the other hand, + when pointers or references are returned to Java, there is often no way + to know where they came from. Therefore, the ownership is set to false. + For example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + Foo bar1(); + Foo &bar2(); + Foo *bar2(); +}; +</PRE> +</DIV> +<P> In Java:</P> +<DIV class="code"> +<PRE> +Foo f = new Foo(); // f.swigCMemOwn = true +Foo f1 = f.bar1(); // f1.swigCMemOwn = true +Foo f2 = f.bar2(); // f2.swigCMemOwn = false +Foo f3 = f.bar3(); // f3.swigCMemOwn = false +</PRE> +</DIV> +<P> This behavior for pointers and references is especially important + for classes that act as containers. For example, if a method returns a + pointer to an object that is contained inside another object, you + definitely don't want Java to assume ownership and destroy it!</P> +<P> For the most part, memory management issues remain hidden. However, + there are situations where you might have to manually change the + ownership of an object. For instance, consider code like this:</P> +<DIV class="code"> +<PRE> +class Obj {}; +class Node { + Obj *value; +public: + void set_value(Obj *v) { value = v; } +}; +</PRE> +</DIV> +<P> Now, consider the following Java code:</P> +<DIV class="code"> +<PRE> +Node n = new Node(); // Create a node +{ + Obj o = new Obj(); // Create an object + n.set_value(o); // Set value +} // o goes out of scope +</PRE> +</DIV> +<P> In this case, the Node <TT>n</TT> is holding a reference to <TT>o</TT> + internally. However, SWIG has no way to know that this has occurred. + The Java proxy class still thinks that it has ownership of <TT>o</TT>. + As <TT>o</TT> has gone out of scope, it could be garbage collected in + which case the C++ destructor will be invoked and <TT>n</TT> will then + be holding a stale-pointer to <TT>o</TT>. If you're lucky, you will + only get a segmentation fault.</P> +<P> To work around this, the ownership flag of <TT>o</TT> needs changing + to <TT>false</TT>. The ownership flag is a private member variable of + the proxy class so this is not possible without some customization of + the proxy class. This can be achieved by using a typemap to customise + the proxy class with pure Java code as detailed later in the section on + <A href="#java_typemaps">Java typemaps</A>.</P> +<P> Sometimes a function will create memory and return a pointer to a + newly allocated object. SWIG has no way of knowing this so by default + the proxy class does not manage the returned object. However, you can + tell the proxy class to manage the memory if you specify the <TT> +%newobject</TT> directive. Consider:</P> +<DIV class="code"> +<PRE> +class Obj {...}; +class Factory { +public: + static Obj *createObj() { return new Obj(); } +}; +</PRE> +</DIV> +<P> If we call the factory function, then we have to manually delete the + memory:</P> +<DIV class="code"> +<PRE> +Obj obj = Factory.createObj(); // obj.swigCMemOwn = false +... +obj.delete(); +</PRE> +</DIV> +<P> Now add in the %newobject directive:</P> +<DIV class="code"> +<PRE> +%newobject Factory::createObj(); + +class Obj {...}; +class Factory { +public: + static Obj *createObj() { return new Obj(); } +}; +</PRE> +</DIV> +<P> A call to <TT>delete()</TT> is no longer necessary as the garbage + collector will make the C++ destructor call because <TT>swigCMemOwn</TT> + is now true.</P> +<DIV class="code"> +<PRE> +Obj obj = Factory.createObj(); // obj.swigCMemOwn = true; +... +</PRE> +</DIV> +<P> Some memory management issues are quite tricky to fix and may only + be noticeable after using for a long time. One such issue is premature + garbage collection of an object created from Java and resultant usage + from C++ code. The section on typemap examples cover two such + scenarios, <A href="#java_memory_management_objects">Memory management + for objects passed to the C++ layer</A> and <A href="#java_memory_management_member_variables"> +Memory management when returning references to member variables</A></P> +<H4><A name="inheritance_mirroring"></A>21.4.3.2 Inheritance</H4> +<P> Java proxy classes will mirror C++ inheritance chains. For example, + given the base class <TT>Base</TT> and its derived class <TT>Derived</TT> +:</P> +<DIV class="code"> +<PRE> +class Base { +public: + virtual double foo(); +}; + +class Derived : public Base { +public: + virtual double foo(); +}; +</PRE> +</DIV> +<P> The base class is generated much like any other proxy class seen so + far:</P> +<DIV class="code"> +<PRE> +public class Base { + private long swigCPtr; + protected boolean swigCMemOwn; + + protected Base(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(Base obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if(swigCPtr != 0 && swigCMemOwn) { + swigCMemOwn = false; + exampleJNI.delete_Base(swigCPtr); + } + swigCPtr = 0; + } + + public double foo() { + return exampleJNI.Base_foo(swigCPtr, this); + } + + public Base() { + this(exampleJNI.new_Base(), true); + } + +} +</PRE> +</DIV> +<P> The <TT>Derived</TT> class extends <TT>Base</TT> mirroring the C++ + class inheritance hierarchy.</P> +<DIV class="code"> +<PRE> +public class Derived extends Base { + private long swigCPtr; + + protected Derived(long cPtr, boolean cMemoryOwn) { + super(exampleJNI.SWIGDerivedUpcast(cPtr), cMemoryOwn); + swigCPtr = cPtr; + } + + protected static long getCPtr(Derived obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if(swigCPtr != 0 && swigCMemOwn) { + swigCMemOwn = false; + exampleJNI.delete_Derived(swigCPtr); + } + swigCPtr = 0; + super.delete(); + } + + public double foo() { + return exampleJNI.Derived_foo(swigCPtr, this); + } + + public Derived() { + this(exampleJNI.new_Derived(), true); + } + +} +</PRE> +</DIV> +<P> Note the memory ownership is controlled by the base class. However + each class in the inheritance hierarchy has its own pointer value which + is obtained during construction. The <TT>SWIGDerivedUpcast()</TT> call + converts the pointer from a <TT>Derived *</TT> to a <TT>Base *</TT>. + This is a necessity as C++ compilers are free to implement pointers in + the inheritance hierarchy with different values.</P> +<P> It is of course possible to extend <TT>Base</TT> using your own Java + classes. If <TT>Derived</TT> is provided by the C++ code, you could for + example add in a pure Java class <TT>Extended</TT> derived from <TT> +Base</TT>. There is a caveat and that is any C++ code will not know + about your pure Java class <TT>Extended</TT> so this type of derivation + is restricted. However, true cross language polymorphism can be + achieved using the <A href="#java_directors">directors</A> feature.</P> +<H4><A name="proxy_classes_gc"></A>21.4.3.3 Proxy classes and garbage + collection</H4> +<P> By default each proxy class has a <TT>delete()</TT> and a <TT> +finalize()</TT> method. The <TT>finalize()</TT> method calls <TT> +delete()</TT> which frees any malloc'd memory for wrapped C structs or + calls the C++ class destructors. The idea is for <TT>delete()</TT> to + be called when you have finished with the C/C++ object. Ideally you + need not call <TT>delete()</TT>, but rather leave it to the garbage + collector to call it from the finalizer. When a program exits, the + garbage collector does not guarantee to call all finalizers. An insight + into the reasoning behind this can be obtained from <A href="http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html"> +Hans Boehm's Destructors, Finalizers, and Synchronization</A> paper. + Depending on what the finalizers do and which operating system you use, + this may or may not be a problem.</P> +<P> If the <TT>delete()</TT> call into JNI code is just for memory + handling, there is not a problem when run on most operating systems, + for example Windows and Unix. Say your JNI code creates memory on the + heap which your finalizers should clean up, the finalizers may or may + not be called before the program exits. In Windows and Unix all memory + that a process uses is returned to the system on exit, so this isn't a + problem. This is not the case in some operating systems like vxWorks. + If however, your finalizer calls into JNI code invoking the C++ + destructor which in turn releases a TCP/IP socket for example, there is + no guarantee that it will be released. Note that with long running + programs the garbage collector will eventually run, thereby calling any + unreferenced object's finalizers.</P> +<P> Some not so ideal solutions are:</P> +<OL> +<LI> +<P> Call the <TT>System.runFinalizersOnExit(true)</TT> or <TT> +Runtime.getRuntime().runFinalizersOnExit(true)</TT> to ensure the + finalizers are called before the program exits. The catch is that this + is a deprecated function call as the documentation says:</P> +<DIV class="code"><I> This method is inherently unsafe. It may result in + finalizers being called on live objects while other threads are + concurrently manipulating those objects, resulting in erratic behavior + or deadlock.</I></DIV> +<P>In many cases you will be lucky and find that it works, but it is not + to be advocated. Have a look at <A href="http://java.sun.com">Sun's + Java web site</A> and search for <TT>runFinalizersOnExit</TT>.</P> +</LI> +<LI> +<P> From jdk1.3 onwards a new function, <TT>addShutdownHook()</TT>, was + introduced which is guaranteed to be called when your program exits. + You can encourage the garbage collector to call the finalizers, for + example, add this static block to the class that has the <TT>main()</TT> + function:</P> +<DIV class="code"> +<PRE> + static { + Runtime.getRuntime().addShutdownHook( + new Thread() { + public void run() { System.gc(); System.runFinalization(); } + } + ); + } +</PRE> +</DIV> +<P>Although this usually works, the documentation doesn't guarantee that + <TT>runFinalization()</TT> will actually call the finalizers. As the + the shutdown hook is guaranteed you could also make a JNI call to clean + up any resources that are being tracked by the C/C++ code.</P> +</LI> +<LI> +<P>Call the <TT>delete()</TT> function manually which will immediately + invoke the C++ destructor. As a suggestion it may be a good idea to set + the object to null so that should the object be inadvertently used + again a Java null pointer exception is thrown, the alternative would + crash the JVM by using a null C pointer. For example given a SWIG + generated class A:</P> +<DIV class="code"> +<PRE> +A myA = new A(); +// use myA ... +myA.delete(); +// any use of myA here would crash the JVM +myA=null; +// any use of myA here would cause a Java null pointer exception to be thrown +</PRE> +</DIV> +<P> The SWIG generated code ensures that the memory is not deleted + twice, in the event the finalizers get called in addition to the manual + <TT>delete()</TT> call.</P> +</LI> +<LI> +<P> Write your own object manager in Java. You could derive all SWIG + classes from a single base class which could track which objects have + had their finalizers run, then call the rest of them on program + termination. The section on <A href="#java_typemaps">Java typemaps</A> + details how to specify a pure Java base class.</P> +</LI> +</OL> +<P> See the <A href="http://www.devx.com/Java/Article/30192">How to + Handle Java Finalization's Memory-Retention Issues</A> article for + alternative approaches to managing memory by avoiding finalizers + altogether.</P> +<H4><A name="java_pgcpp"></A>21.4.3.4 The premature garbage collection + prevention parameter for proxy class marshalling</H4> +<P> As covered earlier, the C/C++ struct/class pointer is stored in the + proxy class as a Java long and when needed is passed into the native + method where it is cast into the appropriate type. This approach + provides very fast marshalling but could be susceptible to premature + garbage collection. Consider the following C++ code:</P> +<DIV class="code"> +<PRE> +class Wibble { +}; +void wobble(Wibble &w); +</PRE> +</DIV> +<P> The module class contains the Java wrapper for the global <TT>wobble</TT> + method:</P> +<DIV class="code"> +<PRE> +public class example { + ... + public static void wobble(Wibble w) { + exampleJNI.wobble(Wibble.getCPtr(w), w); + } +} +</PRE> +</DIV> +<P> where <TT>example</TT> is the name of the module. All native methods + go through the intermediary class which has the native method declared + as such:</P> +<DIV class="code"> +<PRE> +public class exampleJNI { + ... + public final static native void wobble(long jarg1, Wibble jarg1_); +} +</PRE> +</DIV> +<P> The second parameter, <TT>jarg1_</TT>, is the premature garbage + collection prevention parameter and is added to the native method + parameter list whenever a C/C++ struct or class is marshalled as a Java + long. In order to understand why, consider the alternative where the + intermediary class method is declared without the additional parameter:</P> +<DIV class="code"> +<PRE> +public class exampleJNI { + ... + public final static native void wobble(long jarg1); +} +</PRE> +</DIV> +<P> and the following simple call to <TT>wobble</TT>:</P> +<DIV class="code"> +<PRE> +{ + Wibble w = new Wibble(); + example.wobble(w); +} +</PRE> +</DIV> +<P> The hotspot compiler effectively sees something like:</P> +<DIV class="code"> +<PRE> +{ + Wibble w = new Wibble(); + long w_ptr = Wibble.getCPtr(w); + // w is no longer reachable + exampleJNI.wobble(w_ptr); +} +</PRE> +</DIV> +<P> The <TT>Wibble</TT> object is no longer reachable after the point + shown as in this bit of code, the <TT>Wibble</TT> object is not + referenced again after this point. This means that it is a candidate + for garbage collection. Should <TT>wobble</TT> be a long running + method, it is quite likely that the finalizer for the <TT>Wibble</TT> + instance will be called. This in turn will call its underlying C++ + destructor which is obviously disastrous while the method <TT>wobble</TT> + is running using this object. Even if <TT>wobble</TT> is not a long + running method, it is possible for the <TT>Wibble</TT> instance to be + finalized. By passing the <TT>Wibble</TT> instance into the native + method, it will not be finalized as the JVM guarantees not to finalize + any objects until the native method returns. Effectively, the code then + becomes</P> +<DIV class="code"> +<PRE> +{ + Wibble w = new Wibble(); + long w_ptr = Wibble.getCPtr(w); + exampleJNI.wobble(w_ptr, w); + // w is no longer reachable +} +</PRE> +</DIV> +<P> and therefore there is no possibility of premature garbage + collection. In practice, this premature garbage collection was only + ever observed in Sun's server JVM from jdk-1.3 onwards and in Sun's + client JVM from jdk-1.6 onwards.</P> +<P> The premature garbage collection prevention parameter for proxy + classes is generated by default whenever proxy classes are passed by + value, reference or with a pointer. The implementation for this extra + parameter generation requires the "jtype" typemap to contain <TT>long</TT> + and the "jstype" typemap to contain the name of a proxy class.</P> +<P> The additional parameter does impose a slight performance overhead + and the parameter generation can be suppressed globally with the <TT> +-nopgcpp</TT> commandline option. More selective suppression is possible + with the 'nopgcpp' attribute in the "jtype" <A href="#java_typemaps"> +Java typemap</A>. The attribute is a flag and so should be set to "1" to + enable the suppression, or it can be omitted or set to "0" to disable. + For example:</P> +<DIV class="code"> +<PRE> +%typemap(jtype, nopgcpp="1") Wibble & "long" +</PRE> +</DIV> +<P><B> Compatibility note:</B> The generation of this additional + parameter did not occur in versions prior to SWIG-1.3.30.</P> +<H4><A name="java_multithread_libraries"></A>21.4.3.5 Single threaded + applications and thread safety</H4> +<P> Single threaded Java applications using JNI need to consider thread + safety. The same applies for the C# module where the .NET wrappers use + PInvoke. Consider the C++ class:</P> +<DIV class="code"> +<PRE> +class Test { + string str; +public: + Test() : str("initial") {} +}; +</PRE> +</DIV> +<P> and the Java proxy class generated by SWIG:</P> +<DIV class="code"> +<PRE> +public class Test { + private long swigCPtr; + protected boolean swigCMemOwn; + + protected Test(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(Test obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + protected void finalize() { + delete(); + } + + // Call C++ destructor + public synchronized void delete() { + if(swigCPtr != 0 && swigCMemOwn) { + swigCMemOwn = false; + exampleJNI.delete_Test(swigCPtr); + } + swigCPtr = 0; + } + + // Call C++ constructor + public Test() { + this(exampleJNI.new_Test(), true); + } + +} +</PRE> +</DIV> +<P> It has two methods that call JNI methods, namely, <TT> +exampleJNI.new_Test()</TT> for the C++ constructor and <TT> +exampleJNI.delete_Test()</TT> for the C++ destructor. If the garbage + collector collects an instance of this class, ie <TT>delete()</TT> is + not explicitly called, then the C++ destructor will be run in a + different thread to the main thread. This is because when an object is + marked for garbage collection, any objects with finalizers are added to + a finalization queue and the objects in the finalization queue have + their <TT>finalize()</TT> methods run in a separate finalization + thread. Therefore, if the C memory allocator is not thread safe, then + the heap will get corrupted sooner or later, when a concurrent C++ + delete and new are executed. It is thus essential, even in single + threaded usage, to link to the C multi-thread runtime libraries, for + example, use the /MD option for Visual C++ on Windows. Alternatively, + lock all access to C++ functions that have heap + allocation/deallocation.</P> +<P> Note that some of the STL in Visual C++ 6 is not thread safe, so + although code might be linked to the multithread runtime libraries, + undefined behaviour might still occur in a single threaded Java + program. Similarly some older versions of Sun Studio have bugs in the + multi-threaded implementation of the std::string class and so will lead + to undefined behaviour in these supposedly single threaded Java + applications.</P> +<P> The following innocuous Java usage of Test is an example that will + crash very quickly on a multiprocessor machine if the JNI compiled code + is linked against the single thread C runtime libraries.</P> +<DIV class="code"> +<PRE> +for (int i=0; i<100000; i++) { + System.out.println("Iteration " + i); + for (int k=0; k<10; k++) { + Test test = new Test(); + } + System.gc(); +} +</PRE> +</DIV> +<H3><A name="type_wrapper_classes"></A>21.4.4 Type wrapper classes</H3> +<P> The generated type wrapper class, for say an <TT>int *</TT>, looks + like this:</P> +<DIV class="code"> +<PRE> +public class SWIGTYPE_p_int { + private long swigCPtr; + + protected SWIGTYPE_p_int(long cPtr, boolean bFutureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_int() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_int obj) { + return obj.swigCPtr; + } +} +</PRE> +</DIV> +<P> The methods do not have public access, so by default it is + impossible to do anything with objects of this class other than pass + them around. The methods in the class are part of the inner workings of + SWIG. If you need to mess around with pointers you will have to use + some typemaps specific to the Java module to achieve this. The section + on <A href="#java_typemaps">Java typemaps</A> details how to modify the + generated code.</P> +<P> Note that if you use a pointer or reference to a proxy class in a + function then no type wrapper class is generated because the proxy + class can be used as the function parameter. If however, you need + anything more complicated like a pointer to a pointer to a proxy class + then a typewrapper class is generated for your use.</P> +<P> Note that SWIG generates a type wrapper class and not a proxy class + when it has not parsed the definition of a type that gets used. For + example, say SWIG has not parsed the definition of <TT>class Snazzy</TT> + because it is in a header file that you may have forgotten to use the <TT> +%include</TT> directive on. Should SWIG parse <TT>Snazzy *</TT> being + used in a function parameter, it will then generates a type wrapper + class around a <TT>Snazzy</TT> pointer. Also recall from earlier that + SWIG will use a pointer when a class is passed by value or by + reference:</P> +<DIV class="code"> +<PRE> +void spam(Snazzy *x, Snazzy &y, Snazzy z); +</PRE> +</DIV> +<P> Should SWIG not know anything about <TT>Snazzy</TT> then a <TT> +SWIGTYPE_p_Snazzy</TT> must be used for all 3 parameters in the <TT>spam</TT> + function. The Java function generated is:</P> +<DIV class="code"> +<PRE> +public static void spam(SWIGTYPE_p_Snazzy x, SWIGTYPE_p_Snazzy y, SWIGTYPE_p_Snazzy z) { + ... +} +</PRE> +</DIV> +<P> Note that typedefs are tracked by SWIG and the typedef name is used + to construct the type wrapper class name. For example, consider the + case where <TT>Snazzy</TT> is a typedef to an <TT>int</TT> which SWIG + does parse:</P> +<DIV class="code"> +<PRE> +typedef int Snazzy; +void spam(Snazzy *x, Snazzy &y, Snazzy z); +</PRE> +</DIV> +<P> Because the typedefs have been tracked the Java function generated + is:</P> +<DIV class="code"> +<PRE> +public static void spam(SWIGTYPE_p_int x, SWIGTYPE_p_int y, int z) { ... } +</PRE> +</DIV> +<H3><A name="enum_classes"></A>21.4.5 Enum classes</H3> +<P> SWIG can generate three types of enum classes. The <A href="#enumerations"> +Enumerations</A> section discussed these but omitted all the details. + The following sub-sections detail the various types of enum classes + that can be generated.</P> +<H4><A name="typesafe_enums_classes"></A>21.4.5.1 Typesafe enum classes</H4> +<P> The following example demonstrates the typesafe enum classes which + SWIG generates:</P> +<DIV class="code"> +<PRE> +%include "enumtypesafe.swg" +%javaconst(1); +enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P> The following is the code that SWIG generates:</P> +<DIV class="code"> +<PRE> +public final class Beverage { + public final static Beverage ALE = new Beverage("ALE"); + public final static Beverage LAGER = new Beverage("LAGER", 10); + public final static Beverage STOUT = new Beverage("STOUT"); + public final static Beverage PILSNER = new Beverage("PILSNER"); + public final static Beverage PILZ = new Beverage("PILZ", PILSNER); + + public final int swigValue() { + return swigValue; + } + + public String toString() { + return swigName; + } + + public static Beverage swigToEnum(int swigValue) { + if (swigValue < swigValues.length && swigValue >= 0 && + swigValues[swigValue].swigValue == swigValue) + return swigValues[swigValue]; + for (int i = 0; i < swigValues.length; i++) + if (swigValues[i].swigValue == swigValue) + return swigValues[i]; + throw new IllegalArgumentException("No enum " + Beverage.class + " with value " + + swigValue); + } + + private Beverage(String swigName) { + this.swigName = swigName; + this.swigValue = swigNext++; + } + + private Beverage(String swigName, int swigValue) { + this.swigName = swigName; + this.swigValue = swigValue; + swigNext = swigValue+1; + } + + private Beverage(String swigName, Beverage swigEnum) { + this.swigName = swigName; + this.swigValue = swigEnum.swigValue; + swigNext = this.swigValue+1; + } + + private static Beverage[] swigValues = { ALE, LAGER, STOUT, PILSNER, PILZ }; + private static int swigNext = 0; + private final int swigValue; + private final String swigName; +} +</PRE> +</DIV> +<P> As can be seen, there are a fair number of support methods for the + typesafe enum pattern. The typesafe enum pattern involves creating a + fixed number of static instances of the enum class. The constructors + are private to enforce this. Three constructors are available - two for + C/C++ enums with an initializer and one for those without an + initializer. Note that the two enums with initializers, <TT>LAGER</TT> + and <TT>PILZ</TT>, each call one the two different initializer + constructors. In order to use one of these typesafe enums, the <TT> +swigToEnum</TT> static method must be called to return a reference to + one of the static instances. The JNI layer returns the enum value from + the C/C++ world as an integer and this method is used to find the + appropriate Java enum static instance. The <TT>swigValue</TT> method is + used for marshalling in the other direction. The <TT>toString</TT> + method is overridden so that the enum name is available.</P> +<H4><A name="proper_enums_classes"></A>21.4.5.2 Proper Java enum classes</H4> +<P> The following example demonstrates the Java enums approach:</P> +<DIV class="code"> +<PRE> +%include "enums.swg" +%javaconst(1); +enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P> SWIG will generate the following Java enum:</P> +<DIV class="code"> +<PRE> +public enum Beverage { + ALE, + LAGER(10), + STOUT, + PILSNER, + PILZ(PILSNER); + + public final int swigValue() { + return swigValue; + } + + public static Beverage swigToEnum(int swigValue) { + Beverage[] swigValues = Beverage.class.getEnumConstants(); + if (swigValue < swigValues.length && swigValue >= 0 && + swigValues[swigValue].swigValue == swigValue) + return swigValues[swigValue]; + for (Beverage swigEnum : swigValues) + if (swigEnum.swigValue == swigValue) + return swigEnum; + throw new IllegalArgumentException("No enum " + Beverage.class + + " with value " + swigValue); + } + + private Beverage() { + this.swigValue = SwigNext.next++; + } + + private Beverage(int swigValue) { + this.swigValue = swigValue; + SwigNext.next = swigValue+1; + } + + private Beverage(Beverage swigEnum) { + this.swigValue = swigEnum.swigValue; + SwigNext.next = this.swigValue+1; + } + + private final int swigValue; + + private static class SwigNext { + private static int next = 0; + } +} +</PRE> +</DIV> +<P> The enum items appear first. Like the typesafe enum pattern, the + constructors are private. The constructors are required to handle C/C++ + enums with initializers. The <TT>next</TT> variable is in the <TT> +SwigNext</TT> inner class rather than in the enum class as static + primitive variables cannot be modified from within enum constructors. + Marshalling between Java enums and the C/C++ enum integer value is + handled via the <TT>swigToEnum</TT> and <TT>swigValue</TT> methods. All + the constructors and methods in the Java enum are required just to + handle C/C++ enums with initializers. These needn't be generated if the + enum being wrapped does not have any initializers and the <A href="#simpler_enum_classes"> +Simpler Java enums for enums without initializers</A> section describes + how typemaps can be used to achieve this.</P> +<H4><A name="typeunsafe_enums_classes"></A>21.4.5.3 Type unsafe enum + classes</H4> +<P> The following example demonstrates type unsafe enums:</P> +<DIV class="code"> +<PRE> +%include "enumtypeunsafe.swg" +%javaconst(1); +enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER }; +</PRE> +</DIV> +<P> SWIG will generate the following simple class:</P> +<DIV class="code"> +<PRE> +public final class Beverage { + public final static int ALE = 0; + public final static int LAGER = 10; + public final static int STOUT = LAGER + 1; + public final static int PILSNER = STOUT + 1; + public final static int PILZ = PILSNER; +} +</PRE> +</DIV> +<H2><A name="java_directors"></A>21.5 Cross language polymorphism using + directors</H2> +<P> Proxy classes provide a natural, object-oriented way to wrap C++ + classes. as described earlier, each proxy instance has an associated + C++ instance, and method calls from Java to the proxy are passed to the + C++ instance transparently via C wrapper functions.</P> +<P> This arrangement is asymmetric in the sense that no corresponding + mechanism exists to pass method calls down the inheritance chain from + C++ to Java. In particular, if a C++ class has been extended in Java + (by deriving from the proxy class), these classes will not be visible + from C++ code. Virtual method calls from C++ are thus not able to + access the lowest implementation in the inheritance chain.</P> +<P> SWIG can address this problem and make the relationship between C++ + classes and proxy classes more symmetric. To achieve this goal, new + classes called directors are introduced at the bottom of the C++ + inheritance chain. The job of the directors is to route method calls + correctly, either to C++ implementations higher in the inheritance + chain or to Java implementations lower in the inheritance chain. The + upshot is that C++ classes can be extended in Java and from C++ these + extensions look exactly like native C++ classes. Neither C++ code nor + Java code needs to know where a particular method is implemented: the + combination of proxy classes, director classes, and C wrapper functions + transparently takes care of all the cross-language method routing.</P> +<H3><A name="java_enabling_directors"></A>21.5.1 Enabling directors</H3> +<P> The director feature is disabled by default. To use directors you + must make two changes to the interface file. First, add the "directors" + option to the %module directive, like this:</P> +<DIV class="code"> +<PRE> +%module(directors="1") modulename +</PRE> +</DIV> +<P> Without this option no director code will be generated. Second, you + must use the %feature("director") directive to tell SWIG which classes + and methods should get directors. The %feature directive can be applied + globally, to specific classes, and to specific methods, like this:</P> +<DIV class="code"> +<PRE> +// generate directors for all classes that have virtual methods +%feature("director"); + +// generate directors for all virtual methods in class Foo +%feature("director") Foo; + +// generate a director for just Foo::bar() +%feature("director") Foo::bar; +</PRE> +</DIV> +<P> You can use the %feature("nodirector") directive to turn off + directors for specific classes or methods. So for example,</P> +<DIV class="code"> +<PRE> +%feature("director") Foo; +%feature("nodirector") Foo::bar; +</PRE> +</DIV> +<P> will generate directors for all virtual methods of class Foo except + bar().</P> +<P> Directors can also be generated implicitly through inheritance. In + the following, class Bar will get a director class that handles the + methods one() and two() (but not three()):</P> +<DIV class="code"> +<PRE> +%feature("director") Foo; +class Foo { +public: + virtual void one(); + virtual void two(); +}; + +class Bar: public Foo { +public: + virtual void three(); +}; +</PRE> +</DIV> +<H3><A name="java_directors_classes"></A>21.5.2 Director classes</H3> +<P> For each class that has directors enabled, SWIG generates a new + class that derives from both the class in question and a special <TT> +Swig::Director</TT> class. These new classes, referred to as director + classes, can be loosely thought of as the C++ equivalent of the Java + proxy classes. The director classes store a pointer to their underlying + Java proxy classes.</P> +<P> For simplicity let's ignore the <TT>Swig::Director</TT> class and + refer to the original C++ class as the director's base class. By + default, a director class extends all virtual methods in the + inheritance chain of its base class (see the preceding section for how + to modify this behavior). Thus all virtual method calls, whether they + originate in C++ or in Java via proxy classes, eventually end up in at + the implementation in the director class. The job of the director + methods is to route these method calls to the appropriate place in the + inheritance chain. By "appropriate place" we mean the method that would + have been called if the C++ base class and its Java derived classes + were seamlessly integrated. That seamless integration is exactly what + the director classes provide, transparently skipping over all the messy + JNI glue code that binds the two languages together.</P> +<P> In reality, the "appropriate place" is one of only two + possibilities: C++ or Java. Once this decision is made, the rest is + fairly easy. If the correct implementation is in C++, then the lowest + implementation of the method in the C++ inheritance chain is called + explicitly. If the correct implementation is in Java, the Java API is + used to call the method of the underlying Java object (after which the + usual virtual method resolution in Java automatically finds the right + implementation).</P> +<H3><A name="java_directors_overhead"></A>21.5.3 Overhead and code bloat</H3> +<P> Enabling directors for a class will generate a new director method + for every virtual method in the class' inheritance chain. This alone + can generate a lot of code bloat for large hierarchies. Method + arguments that require complex conversions to and from Java types can + result in large director methods. For this reason it is recommended + that directors are selectively enabled only for specific classes that + are likely to be extended in Java and used in C++.</P> +<P> Although directors make it natural to mix native C++ objects with + Java objects (as director objects), one should be aware of the obvious + fact that method calls to Java objects from C++ will be much slower + than calls to C++ objects. Additionally, compared to classes that do + not use directors, the call routing in the director methods adds a + small overhead. This situation can be optimized by selectively enabling + director methods (using the %feature directive) for only those methods + that are likely to be extended in Java.</P> +<H3><A name="java_directors_example"></A>21.5.4 Simple directors example</H3> +<P> Consider the following SWIG interface file:</P> +<DIV class="code"> +<PRE> +%module(directors="1") example; + +%feature("director") DirectorBase; + +class DirectorBase { +public: + virtual ~DirectorBase() {} + virtual void upcall_method() {} +}; + +void callup(DirectorBase *director) { + director->upcall_method(); +} +</PRE> +</DIV> +<P> The following <CODE>DirectorDerived</CODE> Java class is derived + from the Java proxy class <CODE>DirectorBase</CODE> and overrides <CODE> +upcall_method()</CODE>. When C++ code invokes <CODE>upcall_method()</CODE> +, the SWIG-generated C++ code redirects the call via JNI to the Java <CODE> +DirectorDerived</CODE> subclass. Naturally, the SWIG generated C++ code + and the generated Java intermediate class marshal and convert arguments + between C++ and Java when needed.</P> +<DIV class="code"> +<PRE> +public class DirectorDerived extends DirectorBase { + public DirectorDerived() { + } + + public void upcall_method() { + System.out.println("DirectorDerived::upcall_method() invoked."); + } +} +</PRE> +</DIV> +<P> Running the following Java code</P> +<DIV class="code"> +<PRE> +DirectorDerived director = new DirectorDerived(); +example.callup(director); +</PRE> +</DIV> +<P> will result in the following being output:</P> +<DIV class="code"> +<PRE> +DirectorDerived::upcall_method() invoked. +</PRE> +</DIV> +<H3><A name="java_directors_threading"></A>21.5.5 Director threading + issues</H3> +<P> Depending on your operating system and version of Java and how you + are using threads, you might find the JVM hangs on exit. There are a + couple of solutions to try out. The preferred solution requires jdk-1.4 + and later and uses <TT>AttachCurrentThreadAsDaemon</TT> instead of <TT> +AttachCurrentThread</TT> whenever a call into the JVM is required. This + can be enabled by defining the + SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON macro when compiling the C++ + wrapper code. For older JVMs define SWIG_JAVA_NO_DETACH_CURRENT_THREAD + instead, to avoid the <TT>DetachCurrentThread</TT> call but this will + result in a memory leak instead. For further details inspect the source + code in the java/director.swg library file.</P> +<P> Macros can be defined on the commandline when compiling your C++ + code, or alternatively added to the C++ wrapper file as shown below:</P> +<DIV class="code"> +<PRE> +%insert("runtime") %{ +#define SWIG_JAVA_NO_DETACH_CURRENT_THREAD +%} +</PRE> +</DIV> +<H2><A name="java_allprotected"></A>21.6 Accessing protected members</H2> +<P> When using directors, the protected virtual methods are also + wrapped. These methods are wrapped with a protected Java proxy method, + so the only way that Java code can access these is from within a Java + class derived from the director class.</P> +<P> Members which are protected and non-virtual can also be accessed + when using the 'allprotected' mode. The allprotected mode requires + directors and is turned on by setting the <TT>allprotected</TT> option + in addition to the <TT>directors</TT> option in the %module directive, + like this:</P> +<DIV class="code"> +<PRE> +%module(directors="1", allprotected="1") modulename +</PRE> +</DIV> +<P> Protected member variables and methods (both static and non-static) + will then be wrapped with protected access in the Java proxy class.</P> +<P><B> Note:</B> Neither the directors option nor the allprotected mode + support types defined with protected scope. This includes any enums or + typedefs declared in the protected section of the C++ class.</P> +<P> The following simple example is a class with numerous protected + members, including the constructor and destructor:</P> +<DIV class="code"> +<PRE> +%module(directors="1", allprotected="1") example + +%feature("director") ProtectedBase; + +// Ignore use of unsupported types (those defined in the protected section) +%ignore ProtectedBase::typedefs; + +%inline %{ + +class ProtectedBase { +protected: + ProtectedBase() {} + virtual ~ProtectedBase() {} + virtual void virtualMethod() const {} + void nonStaticMethod(double d) const {} + static void staticMethod(int i) {} + int instanceMemberVariable; + static int staticMemberVariable; + + // unsupported: types defined with protected access and the methods/variables which use them + typedef int IntegerType; + IntegerType typedefs(IntegerType it) { return it; } +}; +int ProtectedBase::staticMemberVariable = 10; + +%} + +</PRE> +</DIV> +<P> Note that the <TT>IntegerType</TT> has protected scope and the + members which use this type must be ignored as they cannot be wrapped.</P> +<P> The proxy methods are protected, so the only way the protected + members can be accessed is within a class that derives from the + director class, such as the following:</P> +<DIV class="code"> +<PRE> +class MyProtectedBase extends ProtectedBase +{ + public MyProtectedBase() { + } + + public void accessProtected() { + virtualMethod(); + nonStaticMethod(1.2); + staticMethod(99); + + setInstanceMemberVariable(5); + int i = getInstanceMemberVariable(); + + setStaticMemberVariable(10); + i = getStaticMemberVariable(); + } +} +</PRE> +</DIV> +<H2><A name="common_customization"></A>21.7 Common customization + features</H2> +<P> An earlier section presented the absolute basics of C/C++ wrapping. + If you do nothing but feed SWIG a header file, you will get an + interface that mimics the behavior described. However, sometimes this + isn't enough to produce a nice module. Certain types of functionality + might be missing or the interface to certain functions might be + awkward. This section describes some common SWIG features that are used + to improve the interface to existing C/C++ code.</P> +<H3><A name="helper_functions"></A>21.7.1 C/C++ helper functions</H3> +<P> Sometimes when you create a module, it is missing certain bits of + functionality. For example, if you had a function like this</P> +<DIV class="code"> +<PRE> +typedef struct Image {...}; +void set_transform(Image *im, double m[4][4]); +</PRE> +</DIV> +<P> it would be accessible from Java, but there may be no easy way to + call it. The problem here is that a type wrapper class is generated for + the two dimensional array parameter so there is no easy way to + construct and manipulate a suitable <TT>double [4][4]</TT> value. To + fix this, you can write some extra C helper functions. Just use the <TT> +%inline</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%inline %{ +/* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */ +double (*new_mat44())[4] { + return (double (*)[4]) malloc(16*sizeof(double)); +} +void free_mat44(double (*x)[4]) { + free(x); +} +void mat44_set(double x[4][4], int i, int j, double v) { + x[i][j] = v; +} +double mat44_get(double x[4][4], int i, int j) { + return x[i][j]; +} +%} +</PRE> +</DIV> +<P> From Java, you could then write code like this:</P> +<DIV class="code"> +<PRE> +Image im = new Image(); +SWIGTYPE_p_a_4__double a = example.new_mat44(); +example.mat44_set(a,0,0,1.0); +example.mat44_set(a,1,1,1.0); +example.mat44_set(a,2,2,1.0); +... +example.set_transform(im,a); +example.free_mat44(a); +</PRE> +</DIV> +<P> Admittedly, this is not the most elegant looking approach. However, + it works and it wasn't too hard to implement. It is possible to improve + on this using Java code, typemaps, and other customization features as + covered in later sections, but sometimes helper functions are a quick + and easy solution to difficult cases.</P> +<H3><A name="class_extension"></A>21.7.2 Class extension with %extend</H3> +<P> One of the more interesting features of SWIG is that it can extend + structures and classes with new methods or constructors. Here is a + simple example:</P> +<DIV class="code"> +<PRE> +%module example +%{ +#include "someheader.h" +%} + +struct Vector { + double x,y,z; +}; + +%extend Vector { + char *toString() { + static char tmp[1024]; + sprintf(tmp,"Vector(%g,%g,%g)", $self->x,$self->y,$self->z); + return tmp; + } + Vector(double x, double y, double z) { + Vector *v = (Vector *) malloc(sizeof(Vector)); + v->x = x; + v->y = y; + v->z = z; + return v; + } +}; +</PRE> +</DIV> +<P> Now, in Java</P> +<DIV class="code"> +<PRE> +Vector v = new Vector(2,3,4); +System.out.println(v); +</PRE> +</DIV> +<P> will display</P> +<DIV class="code"> +<PRE> +Vector(2,3,4) +</PRE> +</DIV> +<P> <TT>%extend</TT> works with both C and C++ code. It does not modify + the underlying object in any way---the extensions only show up in the + Java interface.</P> +<H3><A name="exception_handling"></A>21.7.3 Exception handling with + %exception and %javaexception</H3> +<P> If a C or C++ function throws an error, you may want to convert that + error into a Java exception. To do this, you can use the <TT>%exception</TT> + directive. The <TT>%exception</TT> directive simply lets you rewrite + part of the generated wrapper code to include an error check. It is + detailed in full in the <A href="#exception">Exception handling with + %exception</A> section.</P> +<P> In C, a function often indicates an error by returning a status code + (a negative number or a NULL pointer perhaps). Here is a simple example + of how you might handle that:</P> +<DIV class="code"> +<PRE> +%exception malloc { + $action + if (!result) { + jclass clazz = (*jenv)->FindClass(jenv, "java/lang/OutOfMemoryError"); + (*jenv)->ThrowNew(jenv, clazz, "Not enough memory"); + return $null; + } +} +void *malloc(size_t nbytes); +</PRE> +</DIV> +<P> In Java,</P> +<DIV class="code"> +<PRE> +SWIGTYPE_p_void a = example.malloc(2000000000); +</PRE> +</DIV> +<P> will produce a familiar looking Java exception:</P> +<DIV class="code"> +<PRE> +Exception in thread "main" java.lang.OutOfMemoryError: Not enough memory + at exampleJNI.malloc(Native Method) + at example.malloc(example.java:16) + at runme.main(runme.java:112) +</PRE> +</DIV> +<P> If a library provides some kind of general error handling framework, + you can also use that. For example:</P> +<DIV class="code"> +<PRE> +%exception malloc { + $action + if (err_occurred()) { + jclass clazz = (*jenv)->FindClass(jenv, "java/lang/OutOfMemoryError"); + (*jenv)->ThrowNew(jenv, clazz, "Not enough memory"); + return $null; + } +} +void *malloc(size_t nbytes); +</PRE> +</DIV> +<P> If no declaration name is given to <TT>%exception</TT>, it is + applied to all wrapper functions. The <TT>$action</TT> is a SWIG + special variable and is replaced by the C/C++ function call being + wrapped. The <TT>return $null;</TT> handles all native method return + types, namely those that have a void return and those that do not. This + is useful for typemaps that will be used in native method returning all + return types. See the section on <A href="#special_variables">Java + special variables</A> for further explanation.</P> +<P> C++ exceptions are also easy to handle. We can catch the C++ + exception and rethrow it as a Java exception like this:</P> +<DIV class="code"> +<PRE> +%exception getitem { + try { + $action + } catch (std::out_of_range &e) { + jclass clazz = jenv->FindClass("java/lang/Exception"); + jenv->ThrowNew(clazz, "Range error"); + return $null; + } +} + +class FooClass { +public: + FooClass *getitem(int index); // Might throw std::out_of_range exception + ... +}; +</PRE> +</DIV> +<P> In the example above, <TT>java.lang.Exception</TT> is a checked + exception class and so ought to be declared in the throws clause of <TT> +getitem</TT>. Classes can be specified for adding to the throws clause + using <TT>%javaexception(classes)</TT> instead of <TT>%exception</TT>, + where <TT>classes</TT> is a string containing one or more comma + separated Java classes. The <TT>%clearjavaexception</TT> feature is the + equivalent to <TT>%clearexception</TT> and clears previously declared + exception handlers. The <TT>%nojavaexception</TT> feature is the + equivalent to <TT>%noexception</TT> and disables the exception handler. + See <A href="#Customization_clearing_features">Clearing features</A> + for the difference on disabling and clearing features.</P> +<DIV class="code"> +<PRE> +%javaexception("java.lang.Exception") getitem { + try { + $action + } catch (std::out_of_range &e) { + jclass clazz = jenv->FindClass("java/lang/Exception"); + jenv->ThrowNew(clazz, "Range error"); + return $null; + } +} + +class FooClass { +public: + FooClass *getitem(int index); // Might throw std::out_of_range exception + ... +}; +</PRE> +</DIV> +<P> The generated proxy method now generates a throws clause containing <TT> +java.lang.Exception</TT>:</P> +<DIV class="code"> +<PRE> +public class FooClass { + ... + public FooClass getitem(int index) throws java.lang.Exception { ... } + ... +} +</PRE> +</DIV> +<P> The examples above first use the C JNI calling syntax then the C++ + JNI calling syntax. The C++ calling syntax will not compile as C and + also vice versa. It is however possible to write JNI calls which will + compile under both C and C++ and is covered in the <A href="#typemaps_for_c_and_c++"> +Typemaps for both C and C++ compilation</A> section.</P> +<P> The language-independent <TT>exception.i</TT> library file can also + be used to raise exceptions. See the <A href="#Library">SWIG Library</A> + chapter. The typemap example <A href="#exception_typemap">Handling C++ + exception specifications as Java exceptions</A> provides further + exception handling capabilities.</P> +<H3><A name="method_access"></A>21.7.4 Method access with + %javamethodmodifiers</H3> +<P> A Java feature called <TT>%javamethodmodifiers</TT> can be used to + change the method modifiers from the default <TT>public</TT>. It + applies to both module class methods and proxy class methods. For + example:</P> +<DIV class="code"> +<PRE> +%javamethodmodifiers protect_me() "protected"; +void protect_me(); +</PRE> +</DIV> +<P> Will produce the method in the module class with protected access.</P> +<DIV class="code"> +<PRE> +protected static void protect_me() { + exampleJNI.protect_me(); +} +</PRE> +</DIV> +<H2><A name="tips_techniques"></A>21.8 Tips and techniques</H2> +<P> Although SWIG is largely automatic, there are certain types of + wrapping problems that require additional user input. Examples include + dealing with output parameters, strings and arrays. This chapter + discusses the common techniques for solving these problems.</P> +<H3><A name="input_output_parameters"></A>21.8.1 Input and output + parameters using primitive pointers and references</H3> +<P> A common problem in some C programs is handling parameters passed as + simple pointers or references. For example:</P> +<DIV class="code"> +<PRE> +void add(int x, int y, int *result) { + *result = x + y; +} +</PRE> +</DIV> +<P> or perhaps</P> +<DIV class="code"> +<PRE> +int sub(int *x, int *y) { + return *x-*y; +} +</PRE> +</DIV> +<P> The <TT>typemaps.i</TT> library file will help in these situations. + For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +void add(int, int, int *OUTPUT); +int sub(int *INPUT, int *INPUT); +</PRE> +</DIV> +<P> In Java, this allows you to pass simple values. For example:</P> +<DIV class="code"> +<PRE> +int result = example.sub(7,4); +System.out.println("7 - 4 = " + result); +int[] sum = {0}; +example.add(3,4,sum); +System.out.println("3 + 4 = " + sum[0]); +</PRE> +</DIV> +<P> Which will display:</P> +<DIV class="code"> +<PRE> +7 - 4 = 3 +3 + 4 = 7 +</PRE> +</DIV> +<P> Notice how the <TT>INPUT</TT> parameters allow integer values to be + passed instead of pointers and how the <TT>OUTPUT</TT> parameter will + return the result in the first element of the integer array.</P> +<P> If you don't want to use the names <TT>INPUT</TT> or <TT>OUTPUT</TT> +, use the <TT>%apply</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +%apply int *OUTPUT { int *result }; +%apply int *INPUT { int *x, int *y}; + +void add(int x, int y, int *result); +int sub(int *x, int *y); +</PRE> +</DIV> +<P> If a function mutates one of its parameters like this,</P> +<DIV class="code"> +<PRE> +void negate(int *x) { + *x = -(*x); +} +</PRE> +</DIV> +<P> you can use <TT>INOUT</TT> like this:</P> +<DIV class="code"> +<PRE> +%include "typemaps.i" +... +void negate(int *INOUT); +</PRE> +</DIV> +<P> In Java, the input parameter is the first element in a 1 element + array and is replaced by the output of the function. For example:</P> +<DIV class="code"> +<PRE> +int[] neg = {3}; +example.negate(neg); +System.out.println("Negative of 3 = " + neg[0]); +</PRE> +</DIV> +<P> And no prizes for guessing the output:</P> +<DIV class="code"> +<PRE> +Negative of 3 = -3 +</PRE> +</DIV> +<P> These typemaps can also be applied to C++ references. The above + examples would work the same if they had been defined using references + instead of pointers. For example, the Java code to use the <TT>negate</TT> + function would be the same if it were defined either as it is above:</P> +<DIV class="code"> +<PRE> +void negate(int *INOUT); +</PRE> +</DIV> +<P> or using a reference:</P> +<DIV class="code"> +<PRE> +void negate(int &INOUT); +</PRE> +</DIV> +<P> Note: Since most Java primitive types are immutable and are passed + by value, it is not possible to perform in-place modification of a type + passed as a parameter.</P> +<P> Be aware that the primary purpose of the <TT>typemaps.i</TT> file is + to support primitive datatypes. Writing a function like this</P> +<DIV class="code"> +<PRE> +void foo(Bar *OUTPUT); +</PRE> +</DIV> +<P> will not have the intended effect since <TT>typemaps.i</TT> does not + define an OUTPUT rule for <TT>Bar</TT>.</P> +<H3><A name="simple_pointers"></A>21.8.2 Simple pointers</H3> +<P> If you must work with simple pointers such as <TT>int *</TT> or <TT> +double *</TT> another approach to using <TT>typemaps.i</TT> is to use + the <TT>cpointer.i</TT> pointer library file. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "cpointer.i" + +%inline %{ +extern void add(int x, int y, int *result); +%} + +%pointer_functions(int, intp); +</PRE> +</DIV> +<P> The <TT>%pointer_functions(type,name)</TT> macro generates five + helper functions that can be used to create, destroy, copy, assign, and + dereference a pointer. In this case, the functions are as follows:</P> +<DIV class="code"> +<PRE> +int *new_intp(); +int *copy_intp(int *x); +void delete_intp(int *x); +void intp_assign(int *x, int value); +int intp_value(int *x); +</PRE> +</DIV> +<P> In Java, you would use the functions like this:</P> +<DIV class="code"> +<PRE> +SWIGTYPE_p_int intPtr = example.new_intp(); +example.add(3,4,intPtr); +int result = example.intp_value(intPtr); +System.out.println("3 + 4 = " + result); +</PRE> +</DIV> +<P> If you replace <TT>%pointer_functions(int,intp)</TT> by <TT> +%pointer_class(int,intp)</TT>, the interface is more class-like.</P> +<DIV class="code"> +<PRE> +intp intPtr = new intp(); +example.add(3,4,intPtr.cast()); +int result = intPtr.value(); +System.out.println("3 + 4 = " + result); +</PRE> +</DIV> +<P> See the <A href="#Library">SWIG Library</A> chapter for further + details.</P> +<H3><A name="c_arrays"></A>21.8.3 Wrapping C arrays with Java arrays</H3> +<P> SWIG can wrap arrays in a more natural Java manner than the default + by using the <TT>arrays_java.i</TT> library file. Let's consider an + example:</P> +<DIV class="code"> +<PRE> +%include "arrays_java.i"; +int array[4]; +void populate(int x[]) { + int i; + for (i=0; i<4; i++) + x[i] = 100 + i; +} +</PRE> +</DIV> +<P> These one dimensional arrays can then be used as if they were Java + arrays:</P> +<DIV class="code"> +<PRE> +int[] array = new int[4]; +example.populate(array); + +System.out.print("array: "); +for (int i=0; i<array.length; i++) + System.out.print(array[i] + " "); + +example.setArray(array); + +int[] global_array = example.getArray(); + +System.out.print("\nglobal_array: "); +for (int i=0; i<array.length; i++) + System.out.print(global_array[i] + " "); +</PRE> +</DIV> +<P> Java arrays are always passed by reference, so any changes a + function makes to the array will be seen by the calling function. Here + is the output after running this code:</P> +<DIV class="code"> +<PRE> +array: 100 101 102 103 +global_array: 100 101 102 103 +</PRE> +</DIV> +<P> Note that for assigning array variables the length of the C variable + is used, so it is possible to use a Java array that is bigger than the + C code will cope with. Only the number of elements in the C array will + be used. However, if the Java array is not large enough then you are + likely to get a segmentation fault or access violation, just like you + would in C. When arrays are used in functions like <TT>populate</TT>, + the size of the C array passed to the function is determined by the + size of the Java array.</P> +<P> Please be aware that the typemaps in this library are not efficient + as all the elements are copied from the Java array to a C array + whenever the array is passed to and from JNI code. There is an + alternative approach using the SWIG array library and this is covered + in the next section.</P> +<H3><A name="unbounded_c_arrays"></A>21.8.4 Unbounded C Arrays</H3> +<P> Sometimes a C function expects an array to be passed as a pointer. + For example,</P> +<DIV class="code"> +<PRE> +int sumitems(int *first, int nitems) { + int i, sum = 0; + for (i = 0; i < nitems; i++) { + sum += first[i]; + } + return sum; +} +</PRE> +</DIV> +<P> One of the ways to wrap this is to apply the Java array typemaps + that come in the <TT>arrays_java.i</TT> library file:</P> +<DIV class="code"> +<PRE> +%include "arrays_java.i" +%apply int[] {int *}; +</PRE> +</DIV> +<P> The <TT>ANY</TT> size will ensure the typemap is applied to arrays + of all sizes. You could narrow the typemap matching rules by specifying + a particular array size. Now you can use a pure Java array and pass it + to the C code:</P> +<DIV class="code"> +<PRE> +int[] array = new int[10000000]; // Array of 10-million integers +for (int i=0; i<array.length; i++) { // Set some values + array[i] = i; +} +int sum = example.sumitems(array,10000); +System.out.println("Sum = " + sum); +</PRE> +</DIV> +<P> and the sum would be displayed:</P> +<DIV class="code"> +<PRE> +Sum = 49995000 +</PRE> +</DIV> +<P> This approach is probably the most natural way to use arrays. + However, it suffers from performance problems when using large arrays + as a lot of copying of the elements occurs in transferring the array + from the Java world to the C++ world. An alternative approach to using + Java arrays for C arrays is to use an alternative SWIG library file <TT> +carrays.i</TT>. This approach can be more efficient for large arrays as + the array is accessed one element at a time. For example:</P> +<DIV class="code"> +<PRE> +%include "carrays.i" +%array_functions(int, intArray); +</PRE> +</DIV> +<P> The <TT>%array_functions(type,name)</TT> macro generates four helper + functions that can be used to create and destroy arrays and operate on + elements. In this case, the functions are as follows:</P> +<DIV class="code"> +<PRE> +int *new_intArray(int nelements); +void delete_intArray(int *x); +int intArray_getitem(int *x, int index); +void intArray_setitem(int *x, int index, int value); +</PRE> +</DIV> +<P> In Java, you would use the functions like this:</P> +<DIV class="code"> +<PRE> +SWIGTYPE_p_int array = example.new_intArray(10000000); // Array of 10-million integers +for (int i=0; i<10000; i++) { // Set some values + example.intArray_setitem(array,i,i); +} +int sum = example.sumitems(array,10000); +System.out.println("Sum = " + sum); +</PRE> +</DIV> +<P> If you replace <TT>%array_functions(int,intp)</TT> by <TT> +%array_class(int,intp)</TT>, the interface is more class-like and a + couple more helper functions are available for casting between the + array and the type wrapper class.</P> +<DIV class="code"> +<PRE> +%include "carrays.i" +%array_class(int, intArray); +</PRE> +</DIV> +<P> The <TT>%array_class(type, name)</TT> macro creates wrappers for an + unbounded array object that can be passed around as a simple pointer + like <TT>int *</TT> or <TT>double *</TT>. For instance, you will be + able to do this in Java:</P> +<DIV class="code"> +<PRE> +intArray array = new intArray(10000000); // Array of 10-million integers +for (int i=0; i<10000; i++) { // Set some values + array.setitem(i,i); +} +int sum = example.sumitems(array.cast(),10000); +System.out.println("Sum = " + sum); +</PRE> +</DIV> +<P> The array "object" created by <TT>%array_class()</TT> does not + encapsulate pointers inside a special array object. In fact, there is + no bounds checking or safety of any kind (just like in C). Because of + this, the arrays created by this library are extremely low-level + indeed. You can't iterate over them nor can you even query their + length. In fact, any valid memory address can be accessed if you want + (negative indices, indices beyond the end of the array, etc.). Needless + to say, this approach is not going to suit all applications. On the + other hand, this low-level approach is extremely efficient and well + suited for applications in which you need to create buffers, package + binary data, etc.</P> +<H3><A name="java_heap_allocations"></A>21.8.5 Overriding new and delete + to allocate from Java heap</H3> +<P> Unlike some languages supported by SWIG, Java has a true garbage + collection subsystem. Other languages will free SWIG wrapped objects + when their reference count reaches zero. Java only schedules these + objects for finalization, which may not occur for some time. Because + SWIG objects are allocated on the C heap, Java users may find the JVM + memory use quickly exceeds the assigned limits, as memory fills with + unfinalized proxy objects. Forcing garbage collection is clearly an + undesirable solution.</P> +<P> An elegant fix for C++ users is to override new and delete using the + following code (here shown included in a SWIG interface file)</P> +<DIV class="code"> +<PRE> +/* File: java_heap.i */ +%module test +%{ +#include <stdexcept> +#include "jni.h" + +/** + * A stash area embedded in each allocation to hold java handles + */ +struct Jalloc { + jbyteArray jba; + jobject ref; +}; + +static JavaVM *cached_jvm = 0; + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { + cached_jvm = jvm; + return JNI_VERSION_1_2; +} + +static JNIEnv * JNU_GetEnv() { + JNIEnv *env; + jint rc = cached_jvm->GetEnv((void **)&env, JNI_VERSION_1_2); + if (rc == JNI_EDETACHED) + throw std::runtime_error("current thread not attached"); + if (rc == JNI_EVERSION) + throw std::runtime_error("jni version not supported"); + return env; +} + +void * operator new(size_t t) { + if (cached_jvm != 0) { + JNIEnv *env = JNU_GetEnv(); + jbyteArray jba = env->NewByteArray((int) t + sizeof(Jalloc)); + if (env->ExceptionOccurred()) + throw bad_alloc(); + void *jbuffer = static_cast<void *>(env->GetByteArrayElements(jba, 0)); + if (env->ExceptionOccurred()) + throw bad_alloc(); + Jalloc *pJalloc = static_cast<Jalloc *>(jbuffer); + pJalloc->jba = jba; + /* Assign a global reference so byte array will persist until delete'ed */ + pJalloc->ref = env->NewGlobalRef(jba); + if (env->ExceptionOccurred()) + throw bad_alloc(); + return static_cast<void *>(static_cast<char *>(jbuffer) + sizeof(Jalloc)); + } + else { /* JNI_OnLoad not called, use malloc and mark as special */ + Jalloc *pJalloc = static_cast<Jalloc *>(malloc((int) t + sizeof(Jalloc))); + if (!pJalloc) + throw bad_alloc(); + pJalloc->ref = 0; + return static_cast<void *>( + static_cast<char *>(static_cast<void *>(pJalloc)) + sizeof(Jalloc)); + } +} + +void operator delete(void *v) { + if (v != 0) { + void *buffer = static_cast<void *>( static_cast<char *>(v) - sizeof(Jalloc)); + Jalloc *pJalloc = static_cast<Jalloc *>(buffer); + if (pJalloc->ref) { + JNIEnv *env = JNU_GetEnv(); + env->DeleteGlobalRef(pJalloc->ref); + env->ReleaseByteArrayElements(pJalloc->jba, static_cast<jbyte *>(buffer), 0); + } + else { + free(buffer); + } + } +} +%} +... +</PRE> +</DIV> +<P> This code caches the Java environment during initialization, and + when new is called, a Java ByteArray is allocated to provide the SWIG + objects with space in the Java heap. This has the combined effect of + re-asserting the Java virtual machine's limit on memory allocation, and + puts additional pressure on the garbage collection system to run more + frequently. This code is made slightly more complicated because + allowances must be made if new is called before the JNI_OnLoad is + executed. This can happen during static class initialization, for + example.</P> +<P> Unfortunately, because most Java implementations call malloc and + free, this solution will not work for C wrapped structures. However, + you are free to make functions that allocate and free memory from the + Java heap using this model and use these functions in place of malloc + and free in your own code.</P> +<H2><A name="java_typemaps"></A>21.9 Java typemaps</H2> +<P> This section describes how you can modify SWIG's default wrapping + behavior for various C/C++ datatypes using the <TT>%typemap</TT> + directive. You are advised to be familiar with the the material in the + "<A href="#Typemaps">Typemaps</A>" chapter. While not absolutely + essential knowledge, this section assumes some familiarity with the + Java Native Interface (JNI). JNI documentation can be consulted either + online at <A href="http://java.sun.com">Sun's Java web site</A> or from + a good JNI book. The following two books are recommended:</P> +<UL> +<LI> Title: 'Essential JNI: Java Native Interface.' Author: Rob Gordon. + Publisher: Prentice Hall. ISBN: 0-13-679895-0.</LI> +<LI> Title: 'The Java Native Interface: Programmer's Guide and + Specification.' Author: Sheng Liang. Publisher: Addison-Wesley. ISBN: + 0-201-32577-2. Also available <A href="http://java.sun.com/docs/books/jni"> +online</A> at the Sun Developer Network.</LI> +</UL> +<P> Before proceeding, it should be stressed that typemaps are not a + required part of using SWIG---the default wrapping behavior is enough + in most cases. Typemaps are only used if you want to change some aspect + of the generated code.</P> +<H3><A name="default_primitive_type_mappings"></A>21.9.1 Default + primitive type mappings</H3> +<P> The following table lists the default type mapping from Java to + C/C++.</P> +<TABLE BORDER summary="Default primitive type mappings"> +<TR><TD><B>C/C++ type</B></TD><TD><B>Java type</B></TD><TD><B>JNI type</B> +</TD></TR> +<TR><TD>bool +<BR> const bool &</TD><TD>boolean</TD><TD>jboolean</TD></TR> +<TR><TD>char +<BR>const char &</TD><TD>char</TD><TD>jchar</TD></TR> +<TR><TD>signed char +<BR>const signed char &</TD><TD>byte</TD><TD>jbyte</TD></TR> +<TR><TD>unsigned char +<BR>const unsigned char &</TD><TD>short</TD><TD>jshort</TD></TR> +<TR><TD>short +<BR>const short &</TD><TD>short</TD><TD>jshort</TD></TR> +<TR><TD>unsigned short +<BR> const unsigned short &</TD><TD>int</TD><TD>jint</TD></TR> +<TR><TD>int +<BR> const int &</TD><TD>int</TD><TD>jint</TD></TR> +<TR><TD>unsigned int +<BR> const unsigned int &</TD><TD>long</TD><TD>jlong</TD></TR> +<TR><TD>long +<BR>const long &</TD><TD>int</TD><TD>jint</TD></TR> +<TR><TD>unsigned long +<BR>const unsigned long &</TD><TD>long</TD><TD>jlong</TD></TR> +<TR><TD>long long +<BR> const long long &</TD><TD>long</TD><TD>jlong</TD></TR> +<TR><TD>unsigned long long +<BR>const unsigned long long &</TD><TD>java.math.BigInteger</TD><TD> +jobject</TD></TR> +<TR><TD>float +<BR>const float &</TD><TD>float</TD><TD>jfloat</TD></TR> +<TR><TD>double +<BR> const double &</TD><TD>double</TD><TD>jdouble</TD></TR> +<TR><TD>char * +<BR>char []</TD><TD>String</TD><TD>jstring</TD></TR> +</TABLE> +<P> Note that SWIG wraps the C <TT>char</TT> type as a character. + Pointers and arrays of this type are wrapped as strings. The <TT>signed + char</TT> type can be used if you want to treat <TT>char</TT> as a + signed number rather than a character. Also note that all const + references to primitive types are treated as if they are passed by + value.</P> +<P> Given the following C function:</P> +<DIV class="code"> +<PRE> +void func(unsigned short a, char *b, const long &c, unsigned long long d); +</PRE> +</DIV> +<P> The module class method would be:</P> +<DIV class="code"> +<PRE> +public static void func(int a, String b, int c, java.math.BigInteger d) {...} +</PRE> +</DIV> +<P> The intermediary JNI class would use the same types:</P> +<DIV class="code"> +<PRE> +public final static native void func(int jarg1, String jarg2, int jarg3, + java.math.BigInteger jarg4); +</PRE> +</DIV> +<P> and the JNI function would look like this:</P> +<DIV class="code"> +<PRE> +SWIGEXPORT void JNICALL Java_exampleJNI_func(JNIEnv *jenv, jclass jcls, + jint jarg1, jstring jarg2, jint jarg3, jobject jarg4) {...} +</PRE> +</DIV> +<P> The mappings for C <TT>int</TT> and C <TT>long</TT> are appropriate + for 32 bit applications which are used in the 32 bit JVMs. There is no + perfect mapping between Java and C as Java doesn't support all the + unsigned C data types. However, the mappings allow the full range of + values for each C type from Java.</P> +<H3><A name="Java_default_non_primitive_typemaps"></A>21.9.2 Default + typemaps for non-primitive types</H3> +<P> The previous section covered the primitive type mappings. + Non-primitive types such as classes and structs are mapped using + pointers on the C/C++ side and storing the pointer into a Java <TT>long</TT> + variable which is held by the proxy class or type wrapper class. This + applies whether the type is marshalled as a pointer, by reference or by + value. It also applies for any unknown/incomplete types which use type + wrapper classes.</P> +<P> So in summary, the C/C++ pointer to non-primitive types is cast into + the 64 bit Java <TT>long</TT> type and therefore the JNI type is a <TT> +jlong</TT>. The Java type is either the proxy class or type wrapper + class.</P> +<H3><A name="jvm64"></A>21.9.3 Sixty four bit JVMs</H3> +<P> If you are using a 64 bit JVM you may have to override the C long, + but probably not C int default mappings. Mappings will be system + dependent, for example long will need remapping on Unix LP64 systems + (long, pointer 64 bits, int 32 bits), but not on Microsoft 64 bit + Windows which will be using a P64 IL32 (pointer 64 bits and int, long + 32 bits) model. This may be automated in a future version of SWIG. Note + that the Java write once run anywhere philosophy holds true for all + pure Java code when moving to a 64 bit JVM. Unfortunately it won't of + course hold true for JNI code.</P> +<H3><A name="what_is_typemap"></A>21.9.4 What is a typemap?</H3> +<P> A typemap is nothing more than a code generation rule that is + attached to a specific C datatype. For example, to convert integers + from Java to C, you might define a typemap like this:</P> +<DIV class="code"> +<PRE> +%module example + +%typemap(in) int { + $1 = $input; + printf("Received an integer : %d\n", $1); +} +%inline %{ +extern int fact(int nonnegative); +%} +</PRE> +</DIV> +<P> Typemaps are always associated with some specific aspect of code + generation. In this case, the "in" method refers to the conversion of + input arguments to C/C++. The datatype <TT>int</TT> is the datatype to + which the typemap will be applied. The supplied C code is used to + convert values. In this code a number of special variables prefaced by + a <TT>$</TT> are used. The <TT>$1</TT> variable is a placeholder for a + local variable of type <TT>int</TT>. The <TT>$input</TT> variable + contains the Java data, the JNI <TT>jint</TT> in this case.</P> +<P> When this example is compiled into a Java module, it can be used as + follows:</P> +<DIV class="code"> +<PRE> +System.out.println(example.fact(6)); +</PRE> +</DIV> +<P> and the output will be:</P> +<DIV class="code"> +<PRE> +Received an integer : 6 +720 +</PRE> +</DIV> +<P> In this example, the typemap is applied to all occurrences of the <TT> +int</TT> datatype. You can refine this by supplying an optional + parameter name. For example:</P> +<DIV class="code"> +<PRE> +%module example + +%typemap(in) int nonnegative { + $1 = $input; + printf("Received an integer : %d\n", $1); +} + +%inline %{ +extern int fact(int nonnegative); +%} +</PRE> +</DIV> +<P> In this case, the typemap code is only attached to arguments that + exactly match <TT>int nonnegative</TT>.</P> +<P> The application of a typemap to specific datatypes and argument + names involves more than simple text-matching--typemaps are fully + integrated into the SWIG C++ type-system. When you define a typemap for + <TT>int</TT>, that typemap applies to <TT>int</TT> and qualified + variations such as <TT>const int</TT>. In addition, the typemap system + follows <TT>typedef</TT> declarations. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int nonnegative { + $1 = $input; + printf("Received an integer : %d\n", $1); +} +%inline %{ +typedef int Integer; +extern int fact(Integer nonnegative); // Above typemap is applied +%} +</PRE> +</DIV> +<P> However, the matching of <TT>typedef</TT> only occurs in one + direction. If you defined a typemap for <TT>Integer</TT>, it is not + applied to arguments of type <TT>int</TT>.</P> +<P> Typemaps can also be defined for groups of consecutive arguments. + For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (char *str, int len) { +... +}; + +int count(char c, char *str, int len); +</PRE> +</DIV> +<P> When a multi-argument typemap is defined, the arguments are always + handled as a single Java parameter. This allows the function to be used + like this (notice how the length parameter is omitted):</P> +<DIV class="code"> +<PRE> +int c = example.count('e',"Hello World"); +</PRE> +</DIV> +<H3><A name="typemaps_c_to_java_types"></A>21.9.5 Typemaps for mapping + C/C++ types to Java types</H3> +<P> The typemaps available to the Java module include the common + typemaps listed in the main typemaps section. There are a number of + additional typemaps which are necessary for using SWIG with Java. The + most important of these implement the mapping of C/C++ types to Java + types:</P> +<BR> +<TABLE BORDER summary="Typemap mappings for C/C++ types to Java types"> +<TR><TD><B>Typemap</B></TD><TD><B>Description</B></TD></TR> +<TR><TD>jni</TD><TD>JNI C types. These provide the default mapping of + types from C/C++ to JNI for use in the JNI (C/C++) code.</TD></TR> +<TR><TD>jtype</TD><TD>Java intermediary types. These provide the default + mapping of types from C/C++ to Java for use in the native functions in + the intermediary JNI class. The type must be the equivalent Java type + for the JNI C type specified in the "jni" typemap.</TD></TR> +<TR><TD>jstype</TD><TD>Java types. These provide the default mapping of + types from C/C++ to Java for use in the Java module class, proxy + classes and type wrapper classes.</TD></TR> +<TR><TD>javain</TD><TD>Conversion from jstype to jtype. These are Java + code typemaps which transform the type used in the Java module class, + proxy classes and type wrapper classes (as specified in the "jstype" + typemap) to the type used in the Java intermediary JNI class (as + specified in the "jtype" typemap). In other words the typemap provides + the conversion to the native method call parameter types.</TD></TR> +<TR><TD>javaout</TD><TD>Conversion from jtype to jstype. These are Java + code typemaps which transform the type used in the Java intermediary + JNI class (as specified in the "jtype" typemap) to the Java type used + in the Java module class, proxy classes and type wrapper classes (as + specified in the "jstype" typemap). In other words the typemap provides + the conversion from the native method call return type.</TD></TR> +<TR><TD>javadirectorin</TD><TD>Conversion from jtype to jstype for + director methods. These are Java code typemaps which transform the type + used in the Java intermediary JNI class (as specified in the "jtype" + typemap) to the Java type used in the Java module class, proxy classes + and type wrapper classes (as specified in the "jstype" typemap). This + typemap provides the conversion for the parameters in the director + methods when calling up from C++ to Java. See <A href="#java_directors_typemaps"> +Director typemaps</A>.</TD></TR> +<TR><TD>javadirectorout</TD><TD>Conversion from jstype to jtype for + director methods. These are Java code typemaps which transform the type + used in the Java module class, proxy classes and type wrapper classes + (as specified in the "jstype" typemap) to the type used in the Java + intermediary JNI class (as specified in the "jtype" typemap). This + typemap provides the conversion for the return type in the director + methods when returning from the C++ to Java upcall. See <A href="#java_directors_typemaps"> +Director typemaps</A>.</TD></TR> +<TR><TD>directorin</TD><TD>Conversion from C++ type to jni type for + director methods. These are C++ typemaps which convert the parameters + used in the C++ director method to the appropriate JNI intermediary + type. The conversion is done in JNI code prior to calling the Java + function from the JNI code. See <A href="#java_directors_typemaps"> +Director typemaps</A>.</TD></TR> +<TR><TD>directorout</TD><TD>Conversion from jni type to C++ type for + director methods. These are C++ typemaps which convert the JNI return + type used in the C++ director method to the appropriate C++ return + type. The conversion is done in JNI code after calling the Java + function from the JNI code. See <A href="#java_directors_typemaps"> +Director typemaps</A>.</TD></TR> +</TABLE> +<P> If you are writing your own typemaps to handle a particular type, + you will normally have to write a collection of them. The default + typemaps are in "<TT>java.swg</TT>" and so might be a good place for + finding typemaps to base any new ones on.</P> +<P> The "jni", "jtype" and "jstype" typemaps are usually defined + together to handle the Java to C/C++ type mapping. An "in" typemap + should be accompanied by a "javain" typemap and likewise an "out" + typemap by a "javaout" typemap. If an "in" typemap is written, a + "freearg" and "argout" typemap may also need to be written as some + types have a default "freearg" and/or "argout" typemap which may need + overriding. The "freearg" typemap sometimes releases memory allocated + by the "in" typemap. The "argout" typemap sometimes sets values in + function parameters which are passed by reference in Java.</P> +<P> Note that the "in" typemap marshals the JNI type held in the "jni" + typemap to the real C/C++ type and for the opposite direction, the + "out" typemap marshals the real C/C++ type to the JNI type held in the + "jni" typemap. For <A href="#Java_default_non_primitive_typemaps"> +non-primitive types</A> the "in" and "out" typemaps are responsible for + casting between the C/C++ pointer and the 64 bit <TT>jlong</TT> type. + There is no portable way to cast a pointer into a 64 bit integer type + and the approach taken by SWIG is mostly portable, but breaks C/C++ + aliasing rules. In summary, these rules state that a pointer to any + type must never be dereferenced by a pointer to any other incompatible + type. The following code snippet might aid in understand aliasing rules + better:</P> +<DIV class="code"> +<PRE> + short a; + short* pa = 0; + int i = 0x1234; + + a = (short)i; /* okay */ + a = *(short*)&i; /* breaks aliasing rules */ +</PRE> +</DIV> +<P> An email posting, <A href="http://mail-index.netbsd.org/tech-kern/2003/08/11/0001.html"> +Aliasing, pointer casts and gcc 3.3</A> elaborates further on the + subject. In SWIG, the "in" and "out" typemaps for pointers are + typically</P> +<DIV class="code"> +<PRE> + %typemap(in) struct Foo * %{ + $1 = *(struct Foo **)&$input; /* cast jlong into C ptr */ + %} + %typemap(out) struct Bar * %{ + *(struct Bar **)&$result = $1; /* cast C ptr into jlong */ + %} + struct Bar {...}; + struct Foo {...}; + struct Bar * FooBar(struct Foo *f); +</PRE> +</DIV> +<P> resulting in the following code which breaks the aliasing rules:</P> +<DIV class="code"> +<PRE> +SWIGEXPORT jlong JNICALL Java_exampleJNI_FooBar(JNIEnv *jenv, jclass jcls, + jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + struct Foo *arg1 = (struct Foo *) 0 ; + struct Bar *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(struct Foo **)&jarg1; + result = (struct Bar *)FooBar(arg1); + *(struct Bar **)&jresult = result; + return jresult; +} +</PRE> +</DIV> +<P> If you are using gcc as your C compiler, you might get a + "dereferencing type-punned pointer will break strict-aliasing rules" + warning about this. Please see <A href="#compiling_dynamic">Compiling a + dynamic module</A> to avoid runtime problems with these strict aliasing + rules.</P> +<P> The default code generated by SWIG for the Java module comes from + the typemaps in the "<TT>java.swg</TT>" library file which implements + the <A href="#default_primitive_type_mappings">Default primitive type + mappings</A> and <A href="#Java_default_non_primitive_typemaps">Default + typemaps for non-primitive types</A> covered earlier. There are other + type mapping typemaps in the Java library. These are listed below:</P> +<BR> +<TABLE BORDER summary="Java library typemap mappings"> +<TR VALIGN="TOP"><TD><B>C Type</B></TD><TD><B>Typemap</B></TD><TD><B> +File</B></TD><TD><B>Kind</B></TD><TD><B>Java Type</B></TD><TD><B> +Function</B></TD></TR> +<TR><TD>primitive pointers and references</TD><TD>INPUT</TD><TD> +typemaps.i</TD><TD>input</TD><TD>Java basic types</TD><TD>Allows values + to be used for C functions taking pointers for data input.</TD></TR> +<TR><TD>primitive pointers and references</TD><TD>OUTPUT</TD><TD> +typemaps.i</TD><TD>output</TD><TD>Java basic type arrays</TD><TD>Allows + values held within an array to be used for C functions taking pointers + for data output.</TD></TR> +<TR><TD>primitive pointers and references</TD><TD>INOUT</TD><TD> +typemaps.i</TD><TD>input +<BR>output</TD><TD>Java basic type arrays</TD><TD>Allows values held + within an array to be used for C functions taking pointers for data + input and output.</TD></TR> +<TR><TD>string +<BR> wstring</TD><TD>[unnamed]</TD><TD>std_string.i</TD><TD>input +<BR> output</TD><TD>String</TD><TD>Use for std::string mapping to Java + String.</TD></TR> +<TR><TD>arrays of primitive types</TD><TD>[unnamed]</TD><TD> +arrays_java.i</TD><TD>input +<BR> output</TD><TD>arrays of primitive Java types</TD><TD>Use for + mapping C arrays to Java arrays.</TD></TR> +<TR><TD>arrays of classes/structs/unions</TD><TD>JAVA_ARRAYSOFCLASSES + macro</TD><TD>arrays_java.i</TD><TD>input +<BR> output</TD><TD>arrays of proxy classes</TD><TD>Use for mapping C + arrays to Java arrays.</TD></TR> +<TR><TD>arrays of enums</TD><TD>ARRAYSOFENUMS</TD><TD>arrays_java.i</TD><TD> +input +<BR> output</TD><TD>int[]</TD><TD>Use for mapping C arrays to Java + arrays (typeunsafe and simple enum wrapping approaches only).</TD></TR> +<TR VALIGN="TOP"><TD>char *</TD><TD>BYTE</TD><TD>various.i</TD><TD>input</TD><TD> +byte[]</TD><TD VALIGN="TOP">Java byte array is converted to char array</TD> +</TR> +<TR><TD>char **</TD><TD>STRING_ARRAY</TD><TD>various.i</TD><TD>input +<BR> output</TD><TD>String[]</TD><TD>Use for mapping NULL terminated + arrays of C strings to Java String arrays</TD></TR> +</TABLE> +<H3><A name="typemap_attributes"></A>21.9.6 Java typemap attributes</H3> +<P> There are a few additional typemap attributes that the Java module + supports.</P> +<P> The first of these is the 'throws' attribute. The throws attribute + is optional and specified after the typemap name and contains one or + more comma separated classes for adding to the throws clause for any + methods that use that typemap. It is analogous to the <A href="#exception_handling"> +%javaexception</A> feature's throws attribute.</P> +<DIV class="code"> +<PRE> +%typemap(typemapname, throws="ExceptionClass1, ExceptionClass2") type { ... } +</PRE> +</DIV> +<P> The attribute is necessary for supporting Java checked exceptions + and can be added to just about any typemap. The list of typemaps + include all the C/C++ (JNI) typemaps in the "<A href="#Typemaps"> +Typemaps</A>" chapter and the Java specific typemaps listed in <A href="#typemaps_c_to_java_types"> +the previous section</A>, barring the "jni", "jtype" and "jstype" + typemaps as they could never contain code to throw an exception.</P> +<P> The throws clause is generated for the proxy method as well as the + JNI method in the JNI intermediary class. If a method uses more than + one typemap and each of those typemaps have classes specified in the + throws clause, the union of the exception classes is added to the + throws clause ensuring there are no duplicate classes. See the <A href="#nan_exception_typemap"> +NaN exception example</A> for further usage.</P> +<P> The "jtype" typemap has the optional 'nopgcpp' attribute which can + be used to suppress the generation of the <A href="java_pgcpp"> +premature garbage collection prevention parameter</A>.</P> +<P> The "javain" typemap has the optional 'pre', 'post' and 'pgcppname' + attributes. These are used for generating code before and after the JNI + call in the proxy class or module class. The 'pre' attribute contains + code that is generated before the JNI call and the 'post' attribute + contains code generated after the JNI call. The 'pgcppname' attribute + is used to change the <A href="java_pgcpp">premature garbage collection + prevention parameter</A> name passed to the JNI function. This is + sometimes needed when the 'pre' typemap creates a temporary variable + which is then passed to the JNI function.</P> +<P> <A name="java_constructor_helper_function"></A> Note that when the + 'pre' or 'post' attributes are specified and the associated type is + used in a constructor, a constructor helper function is generated. This + is necessary as the Java proxy constructor wrapper makes a call to a + support constructor using a<I> this</I> call. In Java the<I> this</I> + call must be the first statement in the constructor body. The + constructor body thus calls the helper function and the helper function + instead makes the JNI call, ensuring the 'pre' code is called before + the JNI call is made. There is a <A href="#java_date_marshalling">Date + marshalling</A> example showing 'pre', 'post' and 'pgcppname' + attributes in action.</P> +<H3><A name="special_variables"></A>21.9.7 Java special variables</H3> +<P> The standard SWIG special variables are available for use within + typemaps as described in the <A href="#Typemaps">Typemaps documentation</A> +, for example <TT>$1</TT>, <TT>$input</TT>,<TT>$result</TT> etc.</P> +<P> The Java module uses a few additional special variables:</P> +<P><B> <TT>$javaclassname</TT></B> +<BR> This special variable works like the other <A href="#Typemaps_special_variables"> +special variables</A> and <TT>$javaclassname</TT> is similar to <TT> +$1_type</TT>. It expands to the class name for use in Java given a + pointer. SWIG wraps unions, structs and classes using pointers and in + this case it expands to the Java proxy class name. For example, <TT> +$javaclassname</TT> is replaced by the proxy classname <TT>Foo</TT> when + wrapping a <TT>Foo *</TT> and <TT>$&javaclassname</TT> expands to the + proxy classname when wrapping the C/C++ type <TT>Foo</TT> and <TT> +$*javaclassname</TT> expands to the proxy classname when wrapping <TT> +Foo *&</TT>. If the type does not have an associated proxy class, it + expands to the type wrapper class name, for example, <TT> +SWIGTYPE_p_unsigned_short</TT> is generated when wrapping <TT>unsigned + short *</TT>.</P> +<P><B> <TT>$null</TT></B> +<BR> Used in input typemaps to return early from JNI functions that have + either void or a non-void return type. Example:</P> +<DIV class="code"> +<PRE> +%typemap(check) int * %{ + if (error) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array element error"); + return $null; + } +%} +</PRE> +</DIV> +<P> If the typemap gets put into a function with void as return, $null + will expand to nothing:</P> +<DIV class="code"> +<PRE> +SWIGEXPORT void JNICALL Java_jnifn(...) { + if (error) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array element error"); + return ; + } + ... +} +</PRE> +</DIV> +<P> otherwise $null expands to<I> NULL</I></P> +<DIV class="code"> +<PRE> +SWIGEXPORT jobject JNICALL Java_jnifn(...) { + if (error) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array element error"); + return NULL; + } + ... +} +</PRE> +</DIV> +<P><B> <TT>$javainput, $jnicall and $owner</TT></B> +<BR> The $javainput special variable is used in "javain" typemaps and + $jnicall and $owner are used in "javaout" typemaps. $jnicall is + analogous to $action in %exception. It is replaced by the call to the + native method in the intermediary JNI class. $owner is replaced by + either <TT>true</TT> if %newobject has been used, otherwise <TT>false</TT> +. $javainput is analogous to the $input special variable. It is replaced + by the parameter name.</P> +<P> Here is an example:</P> +<DIV class="code"> +<PRE> +%typemap(javain) Class "Class.getCPtr($javainput)" +%typemap(javain) unsigned short "$javainput" +%typemap(javaout) Class * { + return new Class($jnicall, $owner); + } + +%inline %{ + class Class {...}; + Class * bar(Class cls, unsigned short ush) { return new Class(); }; +%} +</PRE> +</DIV> +<P> The generated proxy code is then:</P> +<DIV class="code"> +<PRE> +public static Class bar(Class cls, int ush) { + return new Class(exampleJNI.bar(Class.getCPtr(cls), cls, ush), false); +} +</PRE> +</DIV> +<P> Here $javainput has been replaced by <TT>cls</TT> and <TT>ush</TT>. + $jnicall has been replaced by the native method call, <TT> +exampleJNI.bar(...)</TT> and $owner has been replaced by <TT>false</TT>. + If %newobject is used by adding the following at the beginning of our + example:</P> +<DIV class="code"> +<PRE> +%newobject bar(Class cls, unsigned short ush); +</PRE> +</DIV> +<P> The generated code constructs the return type using <TT>true</TT> + indicating the proxy class <TT>Class</TT> is responsible for destroying + the C++ memory allocated for it in <TT>bar</TT>:</P> +<DIV class="code"> +<PRE> +public static Class bar(Class cls, int ush) { + return new Class(exampleJNI.bar(Class.getCPtr(cls), cls, ush), true); +} +</PRE> +</DIV> +<P><B> <TT>$static</TT></B> +<BR> This special variable expands to either<I> static</I> or nothing + depending on whether the class is an inner Java class or not. It is + used in the "javaclassmodifiers" typemap so that global classes can be + wrapped as Java proxy classes and nested C++ classes/enums can be + wrapped with the Java equivalent, that is, static inner proxy classes.</P> +<P><B> <TT>$jniinput, $javacall and $packagepath</TT></B> +<BR> These special variables are used in the directors typemaps. See <A href="#java_directors_typemaps"> +Director specific typemaps</A> for details.</P> +<P><B> <TT>$module</TT></B> +<BR> This special variable expands to the module name, as specified by <TT> +%module</TT> or the <TT>-module</TT> commandline option.</P> +<P><B> <TT>$imclassname</TT></B> +<BR> This special variable expands to the intermediary class name. + Usually this is the same as '$moduleJNI', unless the jniclassname + attribute is specified in the <A href="#java_module_directive">%module + directive</A>.</P> +<H3><A name="typemaps_for_c_and_cpp"></A>21.9.8 Typemaps for both C and + C++ compilation</H3> +<P> JNI calls must be written differently depending on whether the code + is being compiled as C or C++. For example C compilation requires the + pointer to a function pointer struct member syntax like</P> +<DIV class="code"> +<PRE> +const jclass clazz = (*jenv)->FindClass(jenv, "java/lang/String"); +</PRE> +</DIV> +<P> whereas C++ code compilation of the same function call is a member + function call using a class pointer like</P> +<DIV class="code"> +<PRE> +const jclass clazz = jenv->FindClass("java/lang/String"); +</PRE> +</DIV> +<P> To enable typemaps to be used for either C or C++ compilation, a set + of JCALLx macros have been defined in Lib/java/javahead.swg, where x is + the number of arguments in the C++ version of the JNI call. The above + JNI calls would be written in a typemap like this</P> +<DIV class="code"> +<PRE> +const jclass clazz = JCALL1(FindClass, jenv, "java/lang/String"); +</PRE> +</DIV> +<P> Note that the SWIG preprocessor expands these into the appropriate C + or C++ JNI calling convention. The C calling convention is emitted by + default and the C++ calling convention is emitted when using the -c++ + SWIG commandline option. If you do not intend your code to be targeting + both C and C++ then your typemaps can use the appropriate JNI calling + convention and need not use the JCALLx macros.</P> +<H3><A name="java_code_typemaps"></A>21.9.9 Java code typemaps</H3> +<P> Most of SWIG's typemaps are used for the generation of C/C++ code. + The typemaps in this section are used solely for the generation of Java + code. Elements of proxy classes and type wrapper classes come from the + following typemaps (the defaults).</P> +<P><TT>%typemap(javabase)</TT></P> +<DIV class="indent"> base (extends) for Java class: empty default +<BR> Note that this typemap accepts a <TT>replace</TT> attribute as an + optional flag. When set to "1", it will replace/override any C++ base + classes that might have been parsed. If this flag is not specified and + there are C++ base classes, then a multiple inheritance warning is + issued and the code in the typemap is ignored. The typemap also accepts + a <TT>notderived</TT> attribute as an optional flag. When set to "1", + it will not apply to classes that are derived from a C++ base. When + used with the SWIGTYPE type, it is useful for giving a common base for + all proxy classes, that is, providing a base class that sits in between + all proxy classes and the Java base class <TT>Object</TT> for example: <TT> +%typemap(javabase, notderived="1") SWIGTYPE "CommonBase"</TT>.</DIV> +<P><TT>%typemap(javabody)</TT></P> +<DIV class="indent"> the essential support body for proxy classes (proxy + base classes only), typewrapper classes and enum classes. Default + contains extra constructors, memory ownership control member variables + (<TT>swigCMemOwn</TT>, <TT>swigCPtr</TT>), the <TT>getCPtr</TT> method + etc.</DIV> +<P><TT>%typemap(javabody_derived)</TT></P> +<DIV class="indent"> the essential support body for proxy classes + (derived classes only). Same as "javabody" typemap, but only used for + proxy derived classes.</DIV> +<P><TT>%typemap(javaclassmodifiers)</TT></P> +<DIV class="indent"> class modifiers for the Java class: default is + "public class"</DIV> +<P><TT>%typemap(javacode)</TT></P> +<DIV class="indent"> Java code is copied verbatim to the Java class: + empty default</DIV> +<P><TT>%typemap(javadestruct, methodname="delete", + methodmodifiers="public synchronized")</TT> +<BR></P> +<DIV class="indent"> destructor wrapper - the <TT>delete()</TT> method + (proxy classes only), used for all proxy classes except those which + have a base class : default calls C++ destructor (or frees C memory) + and resets <TT>swigCPtr</TT> and <TT>swigCMemOwn</TT> flags +<BR> +<BR> Note that the <TT>delete()</TT> method name is configurable and is + specified by the <TT>methodname</TT> attribute. The method modifiers + are also configurable via the <TT>methodmodifiers</TT> attribute.</DIV> +<P><TT>%typemap(javadestruct_derived, methodname="delete", + methodmodifiers="public synchronized")</TT></P> +<DIV class="indent"> destructor wrapper - the <TT>delete()</TT> method + (proxy classes only), same as "javadestruct" but only used for derived + proxy classes : default calls C++ destructor (or frees C memory) and + resets <TT>swigCPtr</TT> and <TT>swigCMemOwn</TT> flags +<BR> +<BR> Note that the <TT>delete()</TT> method name is configurable and is + specified by the <TT>methodname</TT> attribute. The method modifiers + are also configurable via the <TT>methodmodifiers</TT> attribute.</DIV> +<P><TT>%typemap(javaimports)</TT></P> +<DIV class="indent"> import statements for Java class: empty default</DIV> +<P><TT>%typemap(javainterfaces)</TT></P> +<DIV class="indent"> interfaces (extends) for Java class: empty default</DIV> +<P><TT>%typemap(javafinalize)</TT></P> +<DIV class="indent"> the <TT>finalize()</TT> method (proxy classes + only): default calls the <TT>delete()</TT> method</DIV> +<P><B> Compatibility Note:</B> In SWIG-1.3.21 and earlier releases, + typemaps called "javagetcptr" and "javaptrconstructormodifiers" were + available. These are deprecated and the "javabody" typemap can be used + instead.</P> +<P> In summary the contents of the typemaps make up a proxy class like + this:</P> +<DIV class="code"> +<PRE> +[ javaimports typemap ] +[ javaclassmodifiers typemap ] javaclassname extends [ javabase typemap ] + implements [ javainterfaces typemap ] { +[ javabody or javabody_derived typemap ] +[ javafinalize typemap ] +public synchronized void <I>delete</I>() [ javadestruct OR javadestruct_derived typemap ] +[ javacode typemap ] +... proxy functions ... +} +</PRE> +</DIV> +<P> Note the <TT><I>delete</I>()</TT> methodname and method modifiers + are configurable, see "javadestruct" and "javadestruct_derived" + typemaps above.</P> +<P> The type wrapper class is similar in construction:</P> +<DIV class="code"> +<PRE> +[ javaimports typemap ] +[ javaclassmodifiers typemap ] javaclassname extends [ javabase typemap ] + implements [ javainterfaces typemap ] { +[ javabody typemap ] +[ javacode typemap ] +} +</PRE> +</DIV> +<P>The enum class is also similar in construction:</P> +<DIV class="code"> +<PRE> +[ javaimports typemap ] +[ javaclassmodifiers typemap ] javaclassname extends [ javabase typemap ] + implements [ javainterfaces typemap ] { +... Enum values ... +[ javabody typemap ] +[ javacode typemap ] +} +</PRE> +</DIV> +<P> The "javaimports" typemap is ignored if the enum class is wrapped by + an inner Java class, that is when wrapping an enum declared within a + C++ class.</P> +<P> The defaults can be overridden to tailor these classes. Here is an + example which will change the <TT>getCPtr</TT> method and constructor + from the default protected access to public access. This has a + practical application if you are invoking SWIG more than once and + generating the wrapped classes into different packages in each + invocation. If the classes in one package are using the classes in + another package, then these methods need to be public.</P> +<DIV class="code"> +<PRE> +%typemap(javabody) SWIGTYPE %{ + private long swigCPtr; + protected boolean swigCMemOwn; + + public $javaclassname(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +%} +</PRE> +</DIV> +<P> The typemap code is the same that is in "<TT>java.swg</TT>", barring + the two method modifiers. Note that <TT>SWIGTYPE</TT> will target all + proxy classes, but not the type wrapper classes. Also the above typemap + is only used for proxy classes that are potential base classes. To + target proxy classes that are derived from a wrapped class as well, the + "javabody_derived" typemap should also be overridden.</P> +<P> For the typemap to be used in all type wrapper classes, all the + different types that type wrapper classes could be used for should be + targeted:</P> +<DIV class="code"> +<PRE> +%typemap(javabody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ + private long swigCPtr; + + public $javaclassname(long cPtr, boolean bFutureUse) { + swigCPtr = cPtr; + } + + protected $javaclassname() { + swigCPtr = 0; + } + + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +%} +</PRE> +</DIV> +<P> Again this is the same that is in "<TT>java.swg</TT>", barring the + method modifier for <TT>getCPtr</TT>.</P> +<H3><A name="java_directors_typemaps"></A>21.9.10 Director specific + typemaps</H3> +<P> The Java directors feature requires the "javadirectorin", + "javadirectorout", "directorin" and the "directorout" typemaps in order + to work properly. The "javapackage" typemap is an optional typemap used + to identify the Java package path for individual SWIG generated proxy + classes.</P> +<P><TT>%typemap(directorin)</TT></P> +<DIV class="indent"> +<P> The "directorin" typemap is used for converting arguments in the C++ + director class to the appropriate JNI type before the upcall to Java. + This typemap also specifies the JNI field descriptor for the type in + the "descriptor" attribute. For example, integers are converted as + follows:</P> +<DIV class="code"> +<PRE> +%typemap(directorin,descriptor="I") int "$input = (jint) $1;" +</PRE> +</DIV> +<P> <CODE>$input</CODE> is the SWIG name of the JNI temporary variable + passed to Java in the upcall. The <CODE>descriptor="I"</CODE> will put + an <CODE>I</CODE> into the JNI field descriptor that identifies the + Java method that will be called from C++. For more about JNI field + descriptors and their importance, refer to the <A href="#java_typemaps"> +JNI documentation mentioned earlier</A>. A typemap for C character + strings is:</P> +<DIV class="code"> +<PRE> +%typemap(directorin,descriptor="Ljava/lang/String;") char * + %{ $input = jenv->NewStringUTF($1); %} +</PRE> +</DIV> +<P> User-defined types have the default "descriptor" attribute "<CODE> +L$packagepath/$javaclassname;</CODE>" where <CODE>$packagepath</CODE> is + the package name passed from the SWIG command line and <CODE> +$javaclassname</CODE> is the Java proxy class' name. If the <TT>-package</TT> + commandline option is not used to specify the package, then + '$packagepath/' will be removed from the resulting output JNI field + descriptor.<B> Do not forget the terminating ';' for JNI field + descriptors starting with 'L'.</B> If the ';' is left out, Java will + generate a "method not found" runtime error.</P> +</DIV> +<P><TT>%typemap(directorout)</TT></P> +<DIV class="indent"> +<P> The "directorout" typemap is used for converting the JNI return type + in the C++ director class to the appropriate C++ type after the upcall + to Java. For example, integers are converted as follows:</P> +<DIV class="code"> +<PRE> +%typemap(directorout) int %{ $result = (int)$input; %} +</PRE> +</DIV> +<P> <CODE>$input</CODE> is the SWIG name of the JNI temporary variable + returned from Java after the upcall. <CODE>$result</CODE> is the + resulting output. A typemap for C character strings is:</P> +<DIV class="code"> +<PRE> +%typemap(directorout) char * { + $1 = 0; + if ($input) { + $result = (char *)jenv->GetStringUTFChars($input, 0); + if (!$1) return $null; + } +} +</PRE> +</DIV></DIV> +<P><TT>%typemap(javadirectorin)</TT></P> +<DIV class="indent"> +<P> Conversion from jtype to jstype for director methods. These are Java + code typemaps which transform the type used in the Java intermediary + JNI class (as specified in the "jtype" typemap) to the Java type used + in the Java module class, proxy classes and type wrapper classes (as + specified in the "jstype" typemap). This typemap provides the + conversion for the parameters in the director methods when calling up + from C++ to Java.</P> +<P> For primitive types, this typemap is usually specified as:</P> +<DIV class="code"> +<PRE> +%typemap(javadirectorin) int "$jniinput" +</PRE> +</DIV> +<P> The <CODE>$jniinput</CODE> special variable is analogous to <CODE> +$javainput</CODE> special variable. It is replaced by the input + parameter name.</P> +</DIV> +<P><TT>%typemap(javadirectorout)</TT></P> +<DIV class="indent"> +<P> Conversion from jstype to jtype for director methods. These are Java + code typemaps which transform the type used in the Java module class, + proxy classes and type wrapper classes (as specified in the "jstype" + typemap) to the type used in the Java intermediary JNI class (as + specified in the "jtype" typemap). This typemap provides the conversion + for the return type in the director methods when returning from the C++ + to Java upcall.</P> +<P> For primitive types, this typemap is usually specified as:</P> +<DIV class="code"> +<PRE> +%typemap(javadirectorout) int "$javacall" +</PRE> +</DIV> +<P> The <CODE>$javacall</CODE> special variable is analogous to the <CODE> +$jnicall</CODE> special variable. It is replaced by the call to the + target Java method. The target method is the method in the Java proxy + class which overrides the virtual C++ method in the C++ base class.</P> +</DIV> +<P><TT>%typemap(javapackage)</TT></P> +<DIV class="indent"> +<P> The "javapackage" typemap is optional; it serves to identify a + class's Java package. This typemap should be used in conjunction with + classes that are defined outside of the current SWIG interface file. + For example:</P> +<DIV class="code"> +<PRE> +// class Foo is handled in a different interface file: +%import "Foo.i" + +%feature("director") Example; + +%inline { + class Bar { }; + + class Example { + public: + virtual ~Example(); + void ping(Foo *arg1, Bar *arg2); + }; +} +</PRE> +</DIV> +<P> Assume that the Foo class is part of the Java package<I> + com.wombat.foo</I> but the above interface file is part of the Java + package<I> com.wombat.example</I>. Without the "javapackage" typemap, + SWIG will assume that the Foo class belongs to<I> com.wombat.example</I> + class. The corrected interface file looks like:</P> +<DIV class="code"> +<PRE> +// class Foo is handled in a different interface file: +%import "Foo.i" +%typemap("javapackage") Foo, Foo *, Foo & "com.wombat.foo"; +%feature("director") Example; + +%inline { + class Bar { }; + + class Example { + public: + virtual ~Example(); + void ping(Foo *arg1, Bar *arg2); + }; +} +</PRE> +</DIV> +<P> SWIG looks up the package based on the<B> actual</B> type (plain + Foo, Foo pointer and Foo reference), so it is important to associate + all three types with the desired package. Practically speaking, you + should create a separate SWIG interface file, which is %import-ed into + each SWIG interface file, when you have multiple Java packages. Note + the helper macros below, <CODE>OTHER_PACKAGE_SPEC</CODE> and <CODE> +ANOTHER_PACKAGE_SPEC</CODE>, which reduce the amount of extra typing. "<CODE> +TYPE...</CODE>" is useful when passing templated types to the macro, + since multiargument template types appear to the SWIG preprocessor as + multiple macro arguments.</P> +<DIV class="code"> +<PRE> +%typemap("javapackage") SWIGTYPE, SWIGTYPE *, SWIGTYPE & + "package.for.most.classes"; + +%define OTHER_PACKAGE_SPEC(TYPE...) +%typemap("javapackage") TYPE, TYPE *, TYPE & "package.for.other.classes"; +%enddef + +%define ANOTHER_PACKAGE_SPEC(TYPE...) +%typemap("javapackage") TYPE, TYPE *, TYPE & "package.for.another.set"; +%enddef + +OTHER_PACKAGE_SPEC(Package_2_class_one) +ANOTHER_PACKAGE_SPEC(Package_3_class_two) +/* etc */ +</PRE> +</DIV> +<P> The basic strategy here is to provide a default package typemap for + the majority of the classes, only providing "javapackage" typemaps for + the exceptions.</P> +</DIV> +<H2><A name="typemap_examples"></A>21.10 Typemap Examples</H2> +<P> This section includes a few examples of typemaps. For more examples, + you might look at the files "<TT>java.swg</TT>" and "<TT>typemaps.i</TT> +" in the SWIG library.</P> +<H3><A name="simpler_enum_classes"></A>21.10.1 Simpler Java enums for + enums without initializers</H3> +<P> The default <A href="#proper_enums_classes">Proper Java enums</A> + approach to wrapping enums is somewhat verbose. This is to handle all + possible C/C++ enums, in particular enums with initializers. The + generated code can be simplified if the enum being wrapped does not + have any initializers.</P> +<P> The following shows how to remove the support methods that are + generated by default and instead use the methods in the Java enum base + class <TT>java.lang.Enum</TT> and <TT>java.lang.Class</TT> for + marshalling enums between C/C++ and Java. The type used for the + typemaps below is <TT>enum SWIGTYPE</TT> which is the default type used + for all enums. The "enums.swg" file should be examined in order to see + the original overridden versions of the typemaps.</P> +<DIV class="code"> +<PRE> +%include "enums.swg" + +%typemap(javain) enum SWIGTYPE "$javainput.ordinal()" +%typemap(javaout) enum SWIGTYPE { + return $javaclassname.class.getEnumConstants()[$jnicall]; + } +%typemap(javabody) enum SWIGTYPE "" + +%inline %{ + enum HairType { blonde, ginger, brunette }; + void setHair(HairType h); + HairType getHair(); +%} +</PRE> +</DIV> +<P> SWIG will generate the following Java enum, which is somewhat + simpler than the default:</P> +<DIV class="code"> +<PRE> +public enum HairType { + blonde, + ginger, + brunette; +} +</PRE> +</DIV> +<P> and the two Java proxy methods will be:</P> +<DIV class="code"> +<PRE> +public static void setHair(HairType h) { + exampleJNI.setHair(h.ordinal()); +} + +public static HairType getHair() { + return HairType.class.getEnumConstants()[exampleJNI.getHair()]; +} +</PRE> +</DIV> +<P> For marshalling Java enums to C/C++ enums, the <TT>ordinal</TT> + method is used to convert the Java enum into an integer value for + passing to the JNI layer, see the "javain" typemap. For marshalling + C/C++ enums to Java enums, the C/C++ enum value is cast to an integer + in the C/C++ typemaps (not shown). This integer value is then used to + index into the array of enum constants that the Java language provides. + See the <TT>getEnumConstants</TT> method in the "javaout" typemap.</P> +<P> These typemaps can often be used as the default for wrapping enums + as in many cases there won't be any enum initializers. In fact a good + strategy is to always use these typemaps and to specifically handle + enums with initializers using %apply. This would be done by using the + original versions of these typemaps in "enums.swg" under another + typemap name for applying using %apply.</P> +<H3><A name="exception_typemap"></A>21.10.2 Handling C++ exception + specifications as Java exceptions</H3> +<P> This example demonstrates various ways in which C++ exceptions can + be tailored and converted into Java exceptions. Let's consider a simple + file class <TT>SimpleFile</TT> and an exception class <TT>FileException</TT> + which it may throw on error:</P> +<DIV class="code"> +<PRE> +%include "std_string.i" // for std::string typemaps +#include <string> + +class FileException { + std::string message; +public: + FileException(const std::string& msg) : message(msg) {} + std::string what() { + return message; + } +}; + +class SimpleFile { + std::string filename; +public: + SimpleFile(const std::string& filename) : filename(filename) {} + void open() throw(FileException) { + ... + } +}; +</PRE> +</DIV> +<P> As the <TT>open</TT> method has a C++ exception specification, SWIG + will parse this and know that the method can throw an exception. The <A href="#throws_typemap"> +"throws" typemap</A> is then used when SWIG encounters an exception + specification. The default generic "throws" typemap looks like this:</P> +<DIV class="code"> +<PRE> +%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE *, SWIGTYPE [ANY] %{ + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, + "C++ $1_type exception thrown"); + return $null; +%} +</PRE> +</DIV> +<P> Basically SWIG will generate a C++ try catch block and the body of + the "throws" typemap constitutes the catch block. The above typemap + calls a SWIG supplied method which throws a <TT> +java.lang.RuntimeException</TT>. This exception class is a runtime + exception and therefore not a checked exception. If, however, we wanted + to throw a checked exception, say <TT>java.io.IOException</TT>, then we + could use the following typemap:</P> +<DIV class="code"> +<PRE> +%typemap(throws, throws="java.io.IOException") FileException { + jclass excep = jenv->FindClass("java/io/IOException"); + if (excep) + jenv->ThrowNew(excep, $1.what().c_str()); + return $null; +} +</PRE> +</DIV> +<P> Note that this typemap uses the 'throws' <A href="#typemap_attributes"> +typemap attribute</A> to ensure a throws clause is generated. The + generated proxy method then specifies the checked exception by + containing <TT>java.io.IOException</TT> in the throws clause:</P> +<DIV class="code"> +<PRE> +public class SimpleFile { + ... + public void open() throws java.io.IOException { ... } +} +</PRE> +</DIV> +<P> Lastly, if you don't want to map your C++ exception into one of the + standard Java exceptions, the C++ class can be wrapped and turned into + a custom Java exception class. If we go back to our example, the first + thing we must do is get SWIG to wrap <TT>FileException</TT> and ensure + that it derives from <TT>java.lang.Exception</TT>. Additionally, we + might want to override the <TT>java.lang.Exception.getMessage()</TT> + method. The typemaps to use then are as follows:</P> +<DIV class="code"> +<PRE> +%typemap(javabase) FileException "java.lang.Exception"; +%typemap(javacode) FileException %{ + public String getMessage() { + return what(); + } +%} +</PRE> +</DIV> +<P> This generates:</P> +<DIV class="code"> +<PRE> +public class FileException extends java.lang.Exception { + ... + public String getMessage() { + return what(); + } + + public FileException(String msg) { ... } + + public String what() { + return exampleJNI.FileException_what(swigCPtr, this); + } +} +</PRE> +</DIV> +<P> We could alternatively have used <TT>%rename</TT> to rename <TT> +what()</TT> into <TT>getMessage()</TT>.</P> +<H3><A name="nan_exception_typemap"></A>21.10.3 NaN Exception - + exception handling for a particular type</H3> +<P> A Java exception can be thrown from any Java or JNI code. Therefore, + as most typemaps contain either Java or JNI code, just about any + typemap could throw an exception. The following example demonstrates + exception handling on a type by type basis by checking for 'Not a + number' (NaN) whenever a parameter of type <TT>float</TT> is wrapped.</P> +<P> Consider the following C++ code:</P> +<DIV class="code"> +<PRE> +bool calculate(float first, float second); +</PRE> +</DIV> +<P> To validate every <TT>float</TT> being passed to C++, we could + precede the code being wrapped by the following typemap which throws a + runtime exception whenever the <TT>float</TT> is 'Not a Number':</P> +<DIV class="code"> +<PRE> +%module example +%typemap(javain) float "$module.CheckForNaN($javainput)" +%pragma(java) modulecode=%{ + /** Simply returns the input value unless it is not a number, + whereupon an exception is thrown. */ + static protected float CheckForNaN(float num) { + if (Float.isNaN(num)) + throw new RuntimeException("Not a number"); + return num; + } +%} +</PRE> +</DIV> +<P> Note that the <TT>CheckForNaN</TT> support method has been added to + the module class using the <TT>modulecode</TT> pragma. The following + shows the generated code of interest:</P> +<DIV class="code"> +<PRE> +public class example { + ... + + /** Simply returns the input value unless it is not a number, + whereupon an exception is thrown. */ + static protected float CheckForNaN(float num) { + if (Float.isNaN(num)) + throw new RuntimeException("Not a number"); + return num; + } + + public static boolean calculate(float first, float second) { + return exampleJNI.calculate(example.CheckForNaN(first), example.CheckForNaN(second)); + } +} +</PRE> +</DIV> +<P> Note that the "javain" typemap is used for every occurrence of a <TT> +float</TT> being used as an input. Of course, we could have targeted the + typemap at a particular parameter by using <TT>float first</TT>, say, + instead of just <TT>float</TT>.</P> +<P> The exception checking could alternatively have been placed into the + 'pre' attribute that the "javain" typemap supports. The "javain" + typemap above could be replaced with the following:</P> +<DIV class="code"> +<PRE> +%typemap(javain, pre=" $module.CheckForNaN($javainput);") float "$javainput" +</PRE> +</DIV> +<P> which would modify the <TT>calculate</TT> function to instead be + generated as:</P> +<DIV class="code"> +<PRE> +public class example { + ... + public static boolean calculate(float first, float second) { + example.CheckForNaN(first); + example.CheckForNaN(second); + { + return exampleJNI.calculate(first, second); + } + } +} +</PRE> +</DIV> +<P> See the <A href="#java_date_marshalling">Date marshalling example</A> + for an example using further "javain" typemap attributes.</P> +<P> If we decide that what we actually want is a checked exception + instead of a runtime exception, we can change this easily enough. The + proxy method that uses <TT>float</TT> as an input, must then add the + exception class to the throws clause. SWIG can handle this as it + supports the 'throws' <A href="#typemap_attributes">typemap attribute</A> + for specifying classes for the throws clause. Thus we can modify the + pragma and the typemap for the throws clause:</P> +<DIV class="code"> +<PRE> +%typemap(javain, throws="java.lang.Exception") float "$module.CheckForNaN($javainput)" +%pragma(java) modulecode=%{ + /** Simply returns the input value unless it is not a number, + whereupon an exception is thrown. */ + static protected float CheckForNaN(float num) throws java.lang.Exception { + if (Float.isNaN(num)) + throw new RuntimeException("Not a number"); + return num; + } +%} +</PRE> +</DIV> +<P> The <TT>calculate</TT> method now has a throws clause and even + though the typemap is used twice for both <TT>float first</TT> and <TT> +float second</TT>, the throws clause contains a single instance of <TT> +java.lang.Exception</TT>:</P> +<DIV class="code"> +<PRE> +public class example { + ... + + /** Simply returns the input value unless it is not a number, + whereupon an exception is thrown. */ + static protected float CheckForNaN(float num) throws java.lang.Exception { + if (Float.isNaN(num)) + throw new RuntimeException("Not a number"); + return num; + } + + public static boolean calculate(float first, float second) throws java.lang.Exception { + return exampleJNI.calculate(example.CheckForNaN(first), example.CheckForNaN(second)); + } +} +</PRE> +</DIV> +<P> If we were a martyr to the JNI cause, we could replace the succinct + code within the "javain" typemap with a few pages of JNI code. If we + had, we would have put it in the "in" typemap which, like all JNI and + Java typemaps, also supports the 'throws' attribute.</P> +<H3><A name="converting_java_string_arrays"></A>21.10.4 Converting Java + String arrays to char **</H3> +<P> A common problem in many C programs is the processing of command + line arguments, which are usually passed in an array of NULL terminated + strings. The following SWIG interface file allows a Java String array + to be used as a <TT>char **</TT> object.</P> +<DIV class="code"> +<PRE> +%module example + +/* This tells SWIG to treat char ** as a special case when used as a parameter + in a function call */ +%typemap(in) char ** (jint size) { + int i = 0; + size = (*jenv)->GetArrayLength(jenv, $input); + $1 = (char **) malloc((size+1)*sizeof(char *)); + /* make a copy of each string */ + for (i = 0; i<size; i++) { + jstring j_string = (jstring)(*jenv)->GetObjectArrayElement(jenv, $input, i); + const char * c_string = (*jenv)->GetStringUTFChars(jenv, j_string, 0); + $1[i] = malloc((strlen(c_string)+1)*sizeof(char)); + strcpy($1[i], c_string); + (*jenv)->ReleaseStringUTFChars(jenv, j_string, c_string); + (*jenv)->DeleteLocalRef(jenv, j_string); + } + $1[i] = 0; +} + +/* This cleans up the memory we malloc'd before the function call */ +%typemap(freearg) char ** { + int i; + for (i=0; i<size$argnum-1; i++) + free($1[i]); + free($1); +} + +/* This allows a C function to return a char ** as a Java String array */ +%typemap(out) char ** { + int i; + int len=0; + jstring temp_string; + const jclass clazz = (*jenv)->FindClass(jenv, "java/lang/String"); + + while ($1[len]) len++; + jresult = (*jenv)->NewObjectArray(jenv, len, clazz, NULL); + /* exception checking omitted */ + + for (i=0; i<len; i++) { + temp_string = (*jenv)->NewStringUTF(jenv, *result++); + (*jenv)->SetObjectArrayElement(jenv, jresult, i, temp_string); + (*jenv)->DeleteLocalRef(jenv, temp_string); + } +} + +/* These 3 typemaps tell SWIG what JNI and Java types to use */ +%typemap(jni) char ** "jobjectArray" +%typemap(jtype) char ** "String[]" +%typemap(jstype) char ** "String[]" + +/* These 2 typemaps handle the conversion of the jtype to jstype typemap type + and vice versa */ +%typemap(javain) char ** "$javainput" +%typemap(javaout) char ** { + return $jnicall; + } + +/* Now a few test functions */ +%inline %{ + +int print_args(char **argv) { + int i = 0; + while (argv[i]) { + printf("argv[%d] = %s\n", i, argv[i]); + i++; + } + return i; +} + +char **get_args() { + static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0}; + return &values[0]; +} + +%} +</PRE> +</DIV> +<P> Note that the 'C' JNI calling convention is used. Checking for any + thrown exceptions after JNI function calls has been omitted. When this + module is compiled, our wrapped C functions can be used by the + following Java program:</P> +<DIV class="code"> +<PRE> +// File runme.java + +public class runme { + + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. " + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + String animals[] = {"Cat","Dog","Cow","Goat"}; + example.print_args(animals); + String args[] = example.get_args(); + for (int i=0; i<args.length; i++) + System.out.println(i + ":" + args[i]); + } +} +</PRE> +</DIV> +<P> When compiled and run we get:</P> +<DIV class="code"> +<PRE> +$ java runme +argv[0] = Cat +argv[1] = Dog +argv[2] = Cow +argv[3] = Goat +0:Dave +1:Mike +2:Susan +3:John +4:Michelle +</PRE> +</DIV> +<P> In the example, a few different typemaps are used. The "in" typemap + is used to receive an input argument and convert it to a C array. Since + dynamic memory allocation is used to allocate memory for the array, the + "freearg" typemap is used to later release this memory after the + execution of the C function. The "out" typemap is used for function + return values. Lastly the "jni", "jtype" and "jstype" typemaps are also + required to specify what Java types to use.</P> +<H3><A name="expanding_java_object"></A>21.10.5 Expanding a Java object + to multiple arguments</H3> +<P> Suppose that you had a collection of C functions with arguments such + as the following:</P> +<DIV class="code"> +<PRE> +int foo(int argc, char **argv); +</PRE> +</DIV> +<P> In the previous example, a typemap was written to pass a Java String + array as the <TT>char **argv</TT>. This allows the function to be used + from Java as follows:</P> +<DIV class="code"> +<PRE> +example.foo(4, new String[]{"red", "green", "blue", "white"}); +</PRE> +</DIV> +<P> Although this works, it's a little awkward to specify the argument + count. To fix this, a multi-argument typemap can be defined. This is + not very difficult--you only have to make slight modifications to the + previous example's typemaps:</P> +<DIV class="code"> +<PRE> +%typemap(in) (int argc, char **argv) { + int i = 0; + $1 = (*jenv)->GetArrayLength(jenv, $input); + $2 = (char **) malloc(($1+1)*sizeof(char *)); + /* make a copy of each string */ + for (i = 0; i<$1; i++) { + jstring j_string = (jstring)(*jenv)->GetObjectArrayElement(jenv, $input, i); + const char * c_string = (*jenv)->GetStringUTFChars(jenv, j_string, 0); + $2[i] = malloc((strlen(c_string)+1)*sizeof(char)); + strcpy($2[i], c_string); + (*jenv)->ReleaseStringUTFChars(jenv, j_string, c_string); + (*jenv)->DeleteLocalRef(jenv, j_string); + } + $2[i] = 0; +} + +%typemap(freearg) (int argc, char **argv) { + int i; + for (i=0; i<$1-1; i++) + free($2[i]); + free($2); +} + +%typemap(jni) (int argc, char **argv) "jobjectArray" +%typemap(jtype) (int argc, char **argv) "String[]" +%typemap(jstype) (int argc, char **argv) "String[]" + +%typemap(javain) (int argc, char **argv) "$javainput" +</PRE> +</DIV> +<P> When writing a multiple-argument typemap, each of the types is + referenced by a variable such as <TT>$1</TT> or <TT>$2</TT>. The + typemap code simply fills in the appropriate values from the supplied + Java parameter.</P> +<P> With the above typemap in place, you will find it no longer + necessary to supply the argument count. This is automatically set by + the typemap code. For example:</P> +<DIV class="code"> +<PRE> +example.foo(new String[]{"red", "green", "blue", "white"}); +</PRE> +</DIV> +<H3><A name="using_typemaps_return_arguments"></A>21.10.6 Using typemaps + to return arguments</H3> +<P> A common problem in some C programs is that values may be returned + in function parameters rather than in the return value of a function. + The <TT>typemaps.i</TT> file defines INPUT, OUTPUT and INOUT typemaps + which can be used to solve some instances of this problem. This library + file uses an array as a means of moving data to and from Java when + wrapping a C function that takes non const pointers or non const + references as parameters.</P> +<P> Now we are going to outline an alternative approach to using arrays + for C pointers. The INOUT typemap uses a <TT>double[]</TT> array for + receiving and returning the <TT>double*</TT> parameters. In this + approach we are able to use a Java class <TT>myDouble</TT> instead of <TT> +double[]</TT> arrays where the C pointer <TT>double*</TT> is required.</P> +<P> Here is our example function:</P> +<DIV class="code"> +<PRE> +/* Returns a status value and two values in out1 and out2 */ +int spam(double a, double b, double *out1, double *out2); +</PRE> +</DIV> +<P> If we define a structure <TT>MyDouble</TT> containing a <TT>double</TT> + member variable and use some typemaps we can solve this problem. For + example we could put the following through SWIG:</P> +<DIV class="code"> +<PRE> +%module example + +/* Define a new structure to use instead of double * */ +%inline %{ +typedef struct { + double value; +} MyDouble; +%} + + +%{ +/* Returns a status value and two values in out1 and out2 */ +int spam(double a, double b, double *out1, double *out2) { + int status = 1; + *out1 = a*10.0; + *out2 = b*100.0; + return status; +}; +%} + +/* +This typemap will make any double * function parameters with name <TT>OUTVALUE</TT> take an +argument of MyDouble instead of double *. This will +allow the calling function to read the double * value after returning from the function. +*/ +%typemap(in) double *OUTVALUE { + jclass clazz = jenv->FindClass("MyDouble"); + jfieldID fid = jenv->GetFieldID(clazz, "swigCPtr", "J"); + jlong cPtr = jenv->GetLongField($input, fid); + MyDouble *pMyDouble = NULL; + *(MyDouble **)&pMyDouble = *(MyDouble **)&cPtr; + $1 = &pMyDouble->value; +} + +%typemap(jtype) double *OUTVALUE "MyDouble" +%typemap(jstype) double *OUTVALUE "MyDouble" +%typemap(jni) double *OUTVALUE "jobject" + +%typemap(javain) double *OUTVALUE "$javainput" + +/* Now we apply the typemap to the named variables */ +%apply double *OUTVALUE { double *out1, double *out2 }; +int spam(double a, double b, double *out1, double *out2); +</PRE> +</DIV> +<P> Note that the C++ JNI calling convention has been used this time and + so must be compiled as C++ and the -c++ commandline must be passed to + SWIG. JNI error checking has been omitted for clarity.</P> +<P> What the typemaps do are make the named <TT>double*</TT> function + parameters use our new <TT>MyDouble</TT> wrapper structure. The "in" + typemap takes this structure, gets the C++ pointer to it, takes the <TT> +double value</TT> member variable and passes it to the C++ <TT>spam</TT> + function. In Java, when the function returns, we use the SWIG created <TT> +getValue()</TT> function to get the output value. The following Java + program demonstrates this:</P> +<DIV class="code"> +<PRE> +// File: runme.java + +public class runme { + + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. " + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + MyDouble out1 = new MyDouble(); + MyDouble out2 = new MyDouble(); + int ret = example.spam(1.2, 3.4, out1, out2); + System.out.println(ret + " " + out1.getValue() + " " + out2.getValue()); + } +} +</PRE> +</DIV> +<P> When compiled and run we get:</P> +<DIV class="code"> +<PRE> +$ java runme +1 12.0 340.0 +</PRE> +</DIV> +<H3><A name="adding_downcasts"></A>21.10.7 Adding Java downcasts to + polymorphic return types</H3> +<P> SWIG support for polymorphism works in that the appropriate virtual + function is called. However, the default generated code does not allow + for downcasting. Let's examine this with the following code:</P> +<DIV class="code"> +<PRE> +%include "std_string.i" + +#include <iostream> +using namespace std; +class Vehicle { +public: + virtual void start() = 0; +... +}; + +class Ambulance : public Vehicle { + string vol; +public: + Ambulance(string volume) : vol(volume) {} + virtual void start() { + cout << "Ambulance started" << endl; + } + void sound_siren() { + cout << vol << " siren sounded!" << endl; + } +... +}; + +Vehicle *vehicle_factory() { + return new Ambulance("Very loud"); +} +</PRE> +</DIV> +<P> If we execute the following Java code:</P> +<DIV class="code"> +<PRE> +Vehicle vehicle = example.vehicle_factory(); +vehicle.start(); + +Ambulance ambulance = (Ambulance)vehicle; +ambulance.sound_siren(); +</PRE> +</DIV> +<P> We get:</P> +<DIV class="code"> +<PRE> +Ambulance started +java.lang.ClassCastException + at runme.main(runme.java:16) +</PRE> +</DIV> +<P> Even though we know from examination of the C++ code that <TT> +vehicle_factory</TT> returns an object of type <TT>Ambulance</TT>, we + are not able to use this knowledge to perform the downcast in Java. + This occurs because the runtime type information is not completely + passed from C++ to Java when returning the type from <TT> +vehicle_factory()</TT>. Usually this is not a problem as virtual + functions do work by default, such as in the case of <TT>start()</TT>. + There are a few solutions to getting downcasts to work.</P> +<P> The first is not to use a Java cast but a call to C++ to make the + cast. Add this to your code:</P> +<DIV class="code"> +<PRE> +%exception Ambulance::dynamic_cast(Vehicle *vehicle) { + $action + if (!result) { + jclass excep = jenv->FindClass("java/lang/ClassCastException"); + if (excep) { + jenv->ThrowNew(excep, "dynamic_cast exception"); + } + } +} +%extend Ambulance { + static Ambulance *dynamic_cast(Vehicle *vehicle) { + return dynamic_cast<Ambulance *>(vehicle); + } +}; +</PRE> +</DIV> +<P> It would then be used from Java like this</P> +<DIV class="code"> +<PRE> +Ambulance ambulance = Ambulance.dynamic_cast(vehicle); +ambulance.sound_siren(); +</PRE> +</DIV> +<P> Should <TT>vehicle</TT> not be of type <TT>ambulance</TT> then a + Java <TT>ClassCastException</TT> is thrown. The next solution is a + purer solution in that Java downcasts can be performed on the types. + Add the following before the definition of <TT>vehicle_factory</TT>:</P> +<DIV class="code"> +<PRE> +%typemap(out) Vehicle * { + Ambulance *downcast = dynamic_cast<Ambulance *>($1); + *(Ambulance **)&$result = downcast; +} + +%typemap(javaout) Vehicle * { + return new Ambulance($jnicall, $owner); + } +</PRE> +</DIV> +<P> Here we are using our knowledge that <TT>vehicle_factory</TT> always + returns type <TT>Ambulance</TT> so that the Java proxy is created as a + type <TT>Ambulance</TT>. If <TT>vehicle_factory</TT> can manufacture + any type of <TT>Vehicle</TT> and we want to be able to downcast using + Java casts for any of these types, then a different approach is needed. + Consider expanding our example with a new Vehicle type and a more + flexible factory function:</P> +<DIV class="code"> +<PRE> +class FireEngine : public Vehicle { +public: + FireEngine() {} + virtual void start() { + cout << "FireEngine started" << endl; + } + void roll_out_hose() { + cout << "Hose rolled out" << endl; + } + ... +}; +Vehicle *vehicle_factory(int vehicle_number) { + if (vehicle_number == 0) + return new Ambulance("Very loud"); + else + return new FireEngine(); +} +</PRE> +</DIV> +<P> To be able to downcast with this sort of Java code:</P> +<DIV class="code"> +<PRE> +FireEngine fireengine = (FireEngine)example.vehicle_factory(1); +fireengine.roll_out_hose(); +Ambulance ambulance = (Ambulance)example.vehicle_factory(0); +ambulance.sound_siren(); +</PRE> +</DIV> +<P> the following typemaps targeted at the <TT>vehicle_factory</TT> + function will achieve this. Note that in this case, the Java class is + constructed using JNI code rather than passing a pointer across the JNI + boundary in a Java long for construction in Java code.</P> +<DIV class="code"> +<PRE> +%typemap(jni) Vehicle *vehicle_factory "jobject" +%typemap(jtype) Vehicle *vehicle_factory "Vehicle" +%typemap(jstype) Vehicle *vehicle_factory "Vehicle" +%typemap(javaout) Vehicle *vehicle_factory { + return $jnicall; + } + +%typemap(out) Vehicle *vehicle_factory { + Ambulance *ambulance = dynamic_cast<Ambulance *>($1); + FireEngine *fireengine = dynamic_cast<FireEngine *>($1); + if (ambulance) { + // call the Ambulance(long cPtr, boolean cMemoryOwn) constructor + jclass clazz = jenv->FindClass("Ambulance"); + if (clazz) { + jmethodID mid = jenv->GetMethodID(clazz, "<init>", "(JZ)V"); + if (mid) { + jlong cptr = 0; + *(Ambulance **)&cptr = ambulance; + $result = jenv->NewObject(clazz, mid, cptr, false); + } + } + } else if (fireengine) { + // call the FireEngine(long cPtr, boolean cMemoryOwn) constructor + jclass clazz = jenv->FindClass("FireEngine"); + if (clazz) { + jmethodID mid = jenv->GetMethodID(clazz, "<init>", "(JZ)V"); + if (mid) { + jlong cptr = 0; + *(FireEngine **)&cptr = fireengine; + $result = jenv->NewObject(clazz, mid, cptr, false); + } + } + } + else { + cout << "Unexpected type " << endl; + } + + if (!$result) + cout << "Failed to create new java object" << endl; +} +</PRE> +</DIV> +<P> Better error handling would need to be added into this code. There + are other solutions to this problem, but this last example demonstrates + some more involved JNI code. SWIG usually generates code which + constructs the proxy classes using Java code as it is easier to handle + error conditions and is faster. Note that the JNI code above uses a + number of string lookups to call a constructor, whereas this would not + occur using byte compiled Java code.</P> +<H3><A name="adding_equals_method"></A>21.10.8 Adding an equals method + to the Java classes</H3> +<P> When a pointer is returned from a JNI function, it is wrapped using + a new Java proxy class or type wrapper class. Even when the pointers + are the same, it will not be possible to know that the two Java classes + containing those pointers are actually the same object. It is common in + Java to use the <TT>equals()</TT> method to check whether two objects + are equivalent. The <TT>equals()</TT> method is usually accompanied by + a <TT>hashCode()</TT> method in order to fulfill the requirement that + the hash code is equal for equal objects. Pure Java code methods like + these can be easily added:</P> +<DIV class="code"> +<PRE> +%typemap(javacode) SWIGTYPE %{ + public boolean equals(Object obj) { + boolean equal = false; + if (obj instanceof $javaclassname) + equal = ((($javaclassname)obj).swigCPtr == this.swigCPtr); + return equal; + } + public int hashCode() { + return (int)getPointer(); + } +%} + +class Foo { }; +Foo* returnFoo(Foo *foo) { return foo; } +</PRE> +</DIV> +<P> The following would display <TT>false</TT> without the <TT>javacode</TT> + typemap above. With the typemap defining the <TT>equals</TT> method the + result is <TT>true</TT>.</P> +<DIV class="code"> +<PRE> +Foo foo1 = new Foo(); +Foo foo2 = example.returnFoo(foo1); +System.out.println("foo1? " + foo1.equals(foo2)); +</PRE> +</DIV> +<H3><A name="void_pointers"></A>21.10.9 Void pointers and a common Java + base class</H3> +<P> One might wonder why the common code that SWIG emits for the proxy + and type wrapper classes is not pushed into a base class. The reason is + that although <TT>swigCPtr</TT> could be put into a common base class + for all classes wrapping C structures, it would not work for C++ + classes involved in an inheritance chain. Each class derived from a + base needs a separate <TT>swigCPtr</TT> because C++ compilers sometimes + use a different pointer value when casting a derived class to a base. + Additionally as Java only supports single inheritance, it would not be + possible to derive wrapped classes from your own pure Java classes if + the base class has been 'used up' by SWIG. However, you may want to + move some of the common code into a base class. Here is an example + which uses a common base class for all proxy classes and type wrapper + classes:</P> +<DIV class="code"> +<PRE> +%typemap(javabase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], + SWIGTYPE (CLASS::*) "SWIG" + +%typemap(javacode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], + SWIGTYPE (CLASS::*) %{ + protected long getPointer() { + return swigCPtr; + } +%} +</PRE> +</DIV> +<P> Define new base class called SWIG:</P> +<DIV class="code"> +<PRE> +public abstract class SWIG { + protected abstract long getPointer(); + + public boolean equals(Object obj) { + boolean equal = false; + if (obj instanceof SWIG) + equal = (((SWIG)obj).getPointer() == this.getPointer()); + return equal; + } + + SWIGTYPE_p_void getVoidPointer() { + return new SWIGTYPE_p_void(getPointer(), false); + } +} +</PRE> +</DIV> +<P> This example contains some useful functionality which you may want + in your code.</P> +<UL> +<LI> It has an <TT>equals()</TT> method. Unlike the previous example, + the method code isn't replicated in all classes.</LI> +<LI> It also has a function which effectively implements a cast from the + type of the proxy/type wrapper class to a void pointer. This is + necessary for passing a proxy class or a type wrapper class to a + function that takes a void pointer.</LI> +</UL> +<H3><A name="struct_pointer_pointer"></A>21.10.10 Struct pointer to + pointer</H3> +<P> Pointers to pointers are often used as output parameters in C + factory type functions. These are a bit more tricky to handle. Consider + the following situation where a <TT>Butler</TT> can be hired and fired:</P> +<DIV class="code"> +<PRE> +typedef struct { + int hoursAvailable; + char *greeting; +} Butler; + +// Note: HireButler will allocate the memory +// The caller must free the memory by calling FireButler()!! +extern int HireButler(Butler **ppButler); +extern void FireButler(Butler *pButler); +</PRE> +</DIV> +<P> C code implementation:</P> +<DIV class="code"> +<PRE> +int HireButler(Butler **ppButler) { + Butler *pButler = (Butler *)malloc(sizeof(Butler)); + pButler->hoursAvailable = 24; + pButler->greeting = (char *)malloc(32); + strcpy(pButler->greeting, "At your service Sir"); + *ppButler = pButler; + return 1; +} +void FireButler(Butler *pButler) { + free(pButler->greeting); + free(pButler); +} +</PRE> +</DIV> +<P> Let's take two approaches to wrapping this code. The first is to + provide a functional interface, much like the original C interface. The + following Java code shows how we intend the code to be used:</P> +<DIV class="code"> +<PRE> + Butler jeeves = new Butler(); + example.HireButler(jeeves); + System.out.println("Greeting: " + jeeves.getGreeting()); + System.out.println("Availability: " + jeeves.getHoursAvailable() + " hours per day"); + example.FireButler(jeeves); +</PRE> +</DIV> +<P> Resulting in the following output when run:</P> +<DIV class="shell"> +<PRE> +Greeting: At your service Sir +Availability: 24 hours per day +</PRE> +</DIV> +<P> Note the usage is very much like it would be used if we were writing + C code, that is, explicit memory management is needed. No C memory is + allocated in the construction of the <TT>Butler</TT> proxy class and + the proxy class will not destroy the underlying C memory when it is + collected. A number of typemaps and features are needed to implement + this approach. The following interface file code should be placed + before SWIG parses the above C code.</P> +<DIV class="code"> +<PRE> +%module example + +// Do not generate the default proxy constructor or destructor +%nodefaultctor Butler; +%nodefaultdtor Butler; + +// Add in pure Java code proxy constructor +%typemap(javacode) Butler %{ + /** This constructor creates the proxy which initially does not create nor own any C memory */ + public Butler() { + this(0, false); + } +%} + +// Type typemaps for marshalling Butler ** +%typemap(jni) Butler ** "jobject" +%typemap(jtype) Butler ** "Butler" +%typemap(jstype) Butler ** "Butler" + +// Typemaps for Butler ** as a parameter output type +%typemap(in) Butler ** (Butler *ppButler = 0) %{ + $1 = &ppButler; +%} +%typemap(argout) Butler ** { + // Give Java proxy the C pointer (of newly created object) + jclass clazz = (*jenv)->FindClass(jenv, "Butler"); + jfieldID fid = (*jenv)->GetFieldID(jenv, clazz, "swigCPtr", "J"); + jlong cPtr = 0; + *(Butler **)&cPtr = *$1; + (*jenv)->SetLongField(jenv, $input, fid, cPtr); +} +%typemap(javain) Butler ** "$javainput" +</PRE> +</DIV> +<P> Note that the JNI code sets the proxy's <TT>swigCPtr</TT> member + variable to point to the newly created object. The <TT>swigCMemOwn</TT> + remains unchanged (at false), so that the proxy does not own the + memory.</P> +<P> Note: The old %nodefault directive disabled the default constructor + and destructor at the same time. This is unsafe in most of the cases, + and you can use the explicit %nodefaultctor and %nodefaultdtor + directives to achieve the same result if needed.</P> +<P> The second approach offers a more object oriented interface to the + Java user. We do this by making the Java proxy class's constructor call + the <TT>HireButler()</TT> method to create the underlying C object. + Additionally we get the proxy to take ownership of the memory so that + the finalizer will call the <TT>FireButler()</TT> function. The proxy + class will thus take ownership of the memory and clean it up when no + longer needed. We will also prevent the user from being able to + explicitly call the <TT>HireButler()</TT> and <TT>FireButler()</TT> + functions. Usage from Java will simply be:</P> +<DIV class="code"> +<PRE> +Butler jeeves = new Butler(); +System.out.println("Greeting: " + jeeves.getGreeting()); +System.out.println("Availability: " + jeeves.getHoursAvailable() + " hours per day"); +</PRE> +</DIV> +<P> Note that the Butler class is used just like any other Java class + and no extra coding by the user needs to be written to clear up the + underlying C memory as the finalizer will be called by the garbage + collector which in turn will call the <TT>FireButler()</TT> function. + To implement this, we use the above interface file code but remove the <TT> +javacode</TT> typemap and add the following:</P> +<DIV class="code"> +<PRE> +// Don't expose the memory allocation/de-allocation functions +%ignore FireButler(Butler *pButler); +%ignore HireButler(Butler **ppButler); + +// Add in a custom proxy constructor and destructor +%extend Butler { + Butler() { + Butler *pButler = 0; + HireButler(&pButler); + return pButler; + } + ~Butler() { + FireButler($self); + } +} +</PRE> +</DIV> +<P> Note that the code in <TT>%extend</TT> is using a C++ type + constructor and destructor, yet the generated code will still compile + as C code, see <A href="#SWIG_adding_member_functions">Adding member + functions to C structures</A>. The C functional interface has been + completely morphed into an object-oriented interface and the Butler + class would behave much like any pure Java class and feel more natural + to Java users.</P> +<H3><A name="java_memory_management_member_variables"></A>21.10.11 + Memory management when returning references to member variables</H3> +<P> This example shows how to prevent premature garbage collection of + objects when the underlying C++ class returns a pointer or reference to + a member variable.</P> +<P> Consider the following C++ code:</P> +<DIV class="code"> +<PRE> +struct Wheel { + int size; + Wheel(int sz) : size(sz) {} +}; + +class Bike { + Wheel wheel; +public: + Bike(int val) : wheel(val) {} + Wheel& getWheel() { return wheel; } +}; +</PRE> +</DIV> +<P> and the following usage from Java after running the code through + SWIG:</P> +<DIV class="code"> +<PRE> + Wheel wheel = new Bike(10).getWheel(); + System.out.println("wheel size: " + wheel.getSize()); + // Simulate a garbage collection + System.gc(); + System.runFinalization(); + System.out.println("wheel size: " + wheel.getSize()); +</PRE> +</DIV> +<P> Don't be surprised that if the resulting output gives strange + results such as...</P> +<DIV class="shell"> +<PRE> +wheel size: 10 +wheel size: 135019664 +</PRE> +</DIV> +<P> What has happened here is the garbage collector has collected the <TT> +Bike</TT> instance as it doesn't think it is needed any more. The proxy + instance, <TT>wheel</TT>, contains a reference to memory that was + deleted when the <TT>Bike</TT> instance was collected. In order to + prevent the garbage collector from collecting the <TT>Bike</TT> + instance a reference to the <TT>Bike</TT> must be added to the <TT> +wheel</TT> instance. You can do this by adding the reference when the <TT> +getWheel()</TT> method is called using the following typemaps.</P> +<DIV class="code"> +<PRE> +%typemap(javacode) Wheel %{ + // Ensure that the GC doesn't collect any Bike instance set from Java + private Bike bikeReference; + protected void addReference(Bike bike) { + bikeReference = bike; + } +%} + +// Add a Java reference to prevent premature garbage collection and resulting use +// of dangling C++ pointer. Intended for methods that return pointers or +// references to a member variable. +%typemap(javaout) Wheel& getWheel { + long cPtr = $jnicall; + $javaclassname ret = null; + if (cPtr != 0) { + ret = new $javaclassname(cPtr, $owner); + ret.addReference(this); + } + return ret; + } +</PRE> +</DIV> +<P> The code in the first typemap gets added to the <TT>Wheel</TT> proxy + class. The code in the second typemap constitutes the bulk of the code + in the generated <TT>getWheel()</TT> function:</P> +<DIV class="code"> +<PRE> +public class Wheel { + ... + // Ensure that the GC doesn't collect any bike set from Java + private Bike bikeReference; + protected void addReference(Bike bike) { + bikeReference = bike; + } +} + +public class Bike { + ... + public Wheel getWheel() { + long cPtr = exampleJNI.Bike_getWheel(swigCPtr, this); + Wheel ret = null; + if (cPtr != 0) { + ret = new Wheel(cPtr, false); + ret.addReference(this); + } + return ret; + } +} +</PRE> +</DIV> +<P> Note the <TT>addReference</TT> call.</P> +<H3><A name="java_memory_management_objects"></A>21.10.12 Memory + management for objects passed to the C++ layer</H3> +<P> Managing memory can be tricky when using C++ and Java proxy classes. + The previous example shows one such case and this example looks at + memory management for a class passed to a C++ method which expects the + object to remain in scope after the function has returned. Consider the + following two C++ classes:</P> +<DIV class="code"> +<PRE> +struct Element { + int value; + Element(int val) : value(val) {} +}; +class Container { + Element* element; +public: + Container() : element(0) {} + void setElement(Element* e) { element = e; } + Element* getElement() { return element; } +}; +</PRE> +</DIV> +<P> and usage from C++</P> +<DIV class="code"> +<PRE> + Container container; + Element element(20); + container.setElement(&element); + cout << "element.value: " << container.getElement()->value << endl; +</PRE> +</DIV> +<P> and more or less equivalent usage from Java</P> +<DIV class="code"> +<PRE> + Container container = new Container(); + container.setElement(new Element(20)); + System.out.println("element value: " + container.getElement().getValue()); +</PRE> +</DIV> +<P> The C++ code will always print out 20, but the value printed out may + not be this in the Java equivalent code. In order to understand why, + consider a garbage collection occuring...</P> +<DIV class="code"> +<PRE> + Container container = new Container(); + container.setElement(new Element(20)); + // Simulate a garbage collection + System.gc(); + System.runFinalization(); + System.out.println("element value: " + container.getElement().getValue()); +</PRE> +</DIV> +<P> The temporary element created with <TT>new Element(20)</TT> could + get garbage collected which ultimately means the <TT>container</TT> + variable is holding a dangling pointer, thereby printing out any old + random value instead of the expected value of 20. One solution is to + add in the appropriate references in the Java layer...</P> +<DIV class="code"> +<PRE> +public class Container { + + ... + + // Ensure that the GC doesn't collect any Element set from Java + // as the underlying C++ class stores a shallow copy + private Element elementReference; + private long getCPtrAndAddReference(Element element) { + elementReference = element; + return Element.getCPtr(element); + } + + public void setElement(Element e) { + exampleJNI.Container_setElement(swigCPtr, this, getCPtrAndAddReference(e), e); + } +} +</PRE> +</DIV> +<P> The following typemaps will generate the desired code. The 'javain' + typemap matches the input parameter type for the <TT>setElement</TT> + method. The 'javacode' typemap simply adds in the specified code into + the Java proxy class.</P> +<DIV class="code"> +<PRE> +%typemap(javain) Element *e "getCPtrAndAddReference($javainput)" + +%typemap(javacode) Container %{ + // Ensure that the GC doesn't collect any element set from Java + // as the underlying C++ class stores a shallow copy + private Element elementReference; + private long getCPtrAndAddReference(Element element) { + elementReference = element; + return Element.getCPtr(element); + } +%} +</PRE> +</DIV> +<H3><A name="java_date_marshalling"></A>21.10.13 Date marshalling using + the javain typemap and associated attributes</H3> +<P> The <A href="#nan_exception_typemap">NaN Exception example</A> is a + simple example of the "javain" typemap and its 'pre' attribute. This + example demonstrates how a C++ date class, say <TT>CDate</TT>, can be + mapped onto the standard Java date class, <TT> +java.util.GregorianCalendar</TT> by using the 'pre', 'post' and + 'pgcppname' attributes of the "javain" typemap. The idea is that the <TT> +GregorianCalendar</TT> is used wherever the C++ API uses a <TT>CDate</TT> +. Let's assume the code being wrapped is as follows:</P> +<DIV class="code"> +<PRE> +class CDate { +public: + CDate(int year, int month, int day); + int getYear(); + int getMonth(); + int getDay(); + ... +}; +struct Action { + static int doSomething(const CDate &dateIn, CDate &dateOut); + Action(const CDate &date, CDate &dateOut); +}; +</PRE> +</DIV> +<P> Note that <TT>dateIn</TT> is const and therefore read only and <TT> +dateOut</TT> is a non-const output type.</P> +<P> First let's look at the code that is generated by default, where the + Java proxy class <TT>CDate</TT> is used in the proxy interface:</P> +<DIV class="code"> +<PRE> +public class Action { + ... + public static int doSomething(CDate dateIn, CDate dateOut) { + return exampleJNI.Action_doSomething(CDate.getCPtr(dateIn), dateIn, + CDate.getCPtr(dateOut), dateOut); + } + + public Action(CDate date, CDate dateOut) { + this(exampleJNI.new_Action(CDate.getCPtr(date), date, + CDate.getCPtr(dateOut), dateOut), true); + } +} +</PRE> +</DIV> +<P> The <TT>CDate &</TT> and <TT>const CDate &</TT> Java code is + generated from the following two default typemaps:</P> +<DIV class="code"> +<PRE> +%typemap(jstype) SWIGTYPE & "$javaclassname" +%typemap(javain) SWIGTYPE & "$javaclassname.getCPtr($javainput)" +</PRE> +</DIV> +<P> where '$javaclassname' is translated into the proxy class name, <TT> +CDate</TT> and '$javainput' is translated into the name of the + parameter, eg <TT>dateIn</TT>. From Java, the intention is then to call + into a modifed API with something like:</P> +<DIV class="code"> +<PRE> +java.util.GregorianCalendar calendarIn = + new java.util.GregorianCalendar(2011, java.util.Calendar.APRIL, 13, 0, 0, 0); +java.util.GregorianCalendar calendarOut = new java.util.GregorianCalendar(); + +// Note in calls below, calendarIn remains unchanged and calendarOut +// is set to a new value by the C++ call +Action.doSomething(calendarIn, calendarOut); +Action action = new Action(calendarIn, calendarOut); +</PRE> +</DIV> +<P> To achieve this mapping, we need to alter the default code + generation slightly so that at the Java layer, a <TT>GregorianCalendar</TT> + is converted into a <TT>CDate</TT>. The JNI intermediary layer will + still take a pointer to the underlying <TT>CDate</TT> class. The + typemaps to achieve this are shown below.</P> +<DIV class="code"> +<PRE> +%typemap(jstype) const CDate& "java.util.GregorianCalendar" +%typemap(javain, + pre=" CDate temp$javainput = new CDate($javainput.get(java.util.Calendar.YEAR), " + "$javainput.get(java.util.Calendar.MONTH), $javainput.get(java.util.Calendar.DATE));", + pgcppname="temp$javainput") const CDate & + "$javaclassname.getCPtr(temp$javainput)" + +%typemap(jstype) CDate& "java.util.Calendar" +%typemap(javain, + pre=" CDate temp$javainput = new CDate($javainput.get(java.util.Calendar.YEAR), " + "$javainput.get(java.util.Calendar.MONTH), $javainput.get(java.util.Calendar.DATE));", + post=" $javainput.set(temp$javainput.getYear(), temp$javainput.getMonth(), " + "temp$javainput.getDay(), 0, 0, 0);", + pgcppname="temp$javainput") CDate & + "$javaclassname.getCPtr(temp$javainput)" +</PRE> +</DIV> +<P> The resulting generated proxy code in the <TT>Action</TT> class + follows:</P> +<DIV class="code"> +<PRE> +public class Action { + ... + public static int doSomething(java.util.GregorianCalendar dateIn, + java.util.Calendar dateOut) { + CDate tempdateIn = new CDate(dateIn.get(java.util.Calendar.YEAR), + dateIn.get(java.util.Calendar.MONTH), + dateIn.get(java.util.Calendar.DATE)); + CDate tempdateOut = new CDate(dateOut.get(java.util.Calendar.YEAR), + dateOut.get(java.util.Calendar.MONTH), + dateOut.get(java.util.Calendar.DATE)); + try { + return exampleJNI.Action_doSomething(CDate.getCPtr(tempdateIn), tempdateIn, + CDate.getCPtr(tempdateOut), tempdateOut); + } finally { + dateOut.set(tempdateOut.getYear(), tempdateOut.getMonth(), tempdateOut.getDay(), 0, 0, 0); + } + } + + static private long SwigConstructAction(java.util.GregorianCalendar date, + java.util.Calendar dateOut) { + CDate tempdate = new CDate(date.get(java.util.Calendar.YEAR), + date.get(java.util.Calendar.MONTH), + date.get(java.util.Calendar.DATE)); + CDate tempdateOut = new CDate(dateOut.get(java.util.Calendar.YEAR), + dateOut.get(java.util.Calendar.MONTH), + dateOut.get(java.util.Calendar.DATE)); + try { + return exampleJNI.new_Action(CDate.getCPtr(tempdate), tempdate, + CDate.getCPtr(tempdateOut), tempdateOut); + } finally { + dateOut.set(tempdateOut.getYear(), tempdateOut.getMonth(), tempdateOut.getDay(), 0, 0, 0); + } + } + + public Action(java.util.GregorianCalendar date, java.util.Calendar dateOut) { + this(Action.SwigConstructAction(date, dateOut), true); + } +} +</PRE> +</DIV> +<P> A few things to note:</P> +<UL> +<LI> The "javatype" typemap has changed the parameter type to <TT> +java.util.GregorianCalendar</TT> or <TT>java.util.Calendar</TT> instead + of the default generated <TT>CDate</TT> proxy.</LI> +<LI> The code in the 'pre' attribute appears before the JNI call (<TT> +exampleJNI.new_Action</TT> / <TT>exampleJNI.Action_doSomething</TT>).</LI> +<LI> The code in the 'post' attribute appears after the JNI call.</LI> +<LI> A try .. finally block is generated with the JNI call in the try + block and 'post' code in the finally block. The alternative of just + using a temporary variable for the return value from the JNI call and + the 'post' code being generated before the return statement is not + possible given that the JNI call is in one line and comes from the + "javaout" typemap.</LI> +<LI> The temporary variables in the "javain" typemaps are called <TT> +temp$javain</TT>, where "$javain" is replaced with the parameter name. + "$javain" is used to mangle the variable name so that more than one <TT> +CDate &</TT> type can be used as a parameter in a method, otherwise two + or more local variables with the same name would be generated.</LI> +<LI> The use of the "javain" typemap causes a constructor helper + function (<TT>SwigConstructAction</TT>) to be generated. This allows + Java code to be called before the JNI call and is required as the Java + compiler won't compile code inserted before the 'this' call.</LI> +<LI> The 'pgcppname' attribute is used to modify the object being passed + as the <A href="#java_pgcpp">premature garbage collection prevention + parameter</A> (the 2nd and 4th parameters in the JNI calls).</LI> +</UL> +<H2><A name="java_directors_faq"></A>21.11 Living with Java Directors</H2> +<P> This section is intended to address frequently asked questions and + frequently encountered problems when using Java directors.</P> +<OL> +<LI><I>When my program starts up, it complains that</I> method_foo<I> + cannot be found in a Java method called</I> swig_module_init<I>. How do + I fix this?</I> +<P> Open up the C++ wrapper source code file and look for <CODE> +"method_foo"</CODE> (include the double quotes, they are important!) + Look at the JNI field descriptor and make sure that each class that + occurs in the descriptor has the correct package name in front of it. + If the package name is incorrect, put a "javapackage" typemap in your + SWIG interface file.</P> +</LI> +<LI><I>I'm compiling my code and I'm using templates. I provided a + javapackage typemap, but SWIG doesn't generate the right JNI field + descriptor.</I> +<P> Use the template's renamed name as the argument to the "javapackage" + typemap:</P> +<DIV class="code"> +<PRE> +%typemap(javapackage) std::vector<int> "your.package.here" +%template(VectorOfInt) std::vector<int>; +</PRE> +</DIV></LI> +<LI> +<P><I>When I pass class pointers or references through a C++ upcall and + I try to type cast them, Java complains with a ClassCastException. What + am I doing wrong?</I></P> +<P> Normally, a non-director generated Java proxy class creates + temporary Java objects as follows:</P> +<DIV class="code"> +<PRE> +public static void MyClass_method_upcall(MyClass self, long jarg1) +{ + Foo darg1 = new Foo(jarg1, false); + + self.method_upcall(darg1); +} +</PRE> +</DIV> +<P>Unfortunately, this loses the Java type information that is part of + the underlying Foo director proxy class's Java object pointer causing + the type cast to fail. The SWIG Java module's director code attempts to + correct the problem,<B> but only for director-enabled classes</B>, + since the director class retains a global reference to its Java object. + Thus, for director-enabled classes<B> and only for director-enabled + classes</B>, the generated proxy Java code looks something like:</P> +<DIV class="code"> +<PRE> +public static void MyClass_method_upcall(MyClass self, long jarg1, + Foo jarg1_object) +{ + Foo darg1 = (jarg1_object != null ? jarg1_object : new Foo(jarg1, false)); + + self.method_upcall(darg1); +} +</PRE> +</DIV> +<P> When you import a SWIG interface file containing class definitions, + the classes you want to be director-enabled must be have the <CODE> +feature("director")</CODE> enabled for type symmetry to work. This + applies even when the class being wrapped isn't a director-enabled + class but takes parameters that are director-enabled classes.</P> +<P> The current "type symmetry" design will work for simple C++ + inheritance, but will most likely fail for anything more complicated + such as tree or diamond C++ inheritance hierarchies. Those who are + interested in challenging problems are more than welcome to hack the <CODE> +Java::Java_director_declaration</CODE> method in <CODE> +Source/Modules/java.cxx</CODE>.</P> +<P> If all else fails, you can use the downcastXXXXX() method to attempt + to recover the director class's Java object pointer. For the Java Foo + proxy class, the Foo director class's java object pointer can be + accessed through the javaObjectFoo() method. The generated method's + signature is:</P> +<DIV class="code"> +<PRE> + public static Foo javaObjectFoo(Foo obj); +</PRE> +</DIV> +<P> From your code, this method is invoked as follows:</P> +<DIV class="code"> +<PRE> +public class MyClassDerived { + public void method_upcall(Foo foo_object) + { + FooDerived derived = (foo_object != null ? + (FooDerived) Foo.downcastFoo(foo_object) : null); + /* rest of your code here */ + } +} +</PRE> +</DIV> +<P> An good approach for managing downcasting is placing a static method + in each derived class that performs the downcast from the superclass, + e.g.,</P> +<DIV class="code"> +<PRE> +public class FooDerived extends Foo { + /* ... */ + public static FooDerived downcastFooDerived(Foo foo_object) + { + try { + return (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object); + } + + catch (ClassCastException exc) { + // Wasn't a FooDerived object, some other subclass of Foo + return null; + } + } +} +</PRE> +</DIV> +<P> Then change the code in MyClassDerived as follows:</P> +<DIV class="code"> +<PRE> +public class MyClassDerived extends MyClass { + /* ... */ + public void method_upcall(Foo foo_object) + { + FooDerived derived = FooDerived.downcastFooDerived(foo_object); + /* rest of your code here */ + } +} +</PRE> +</DIV></LI> +<LI> +<P><I>Why isn't the proxy class declared abstract? Why aren't the + director upcall methods in the proxy class declared abstract?</I></P> +<P> Declaring the proxy class and its methods abstract would break the + JNI argument marshalling and SWIG's downcall functionality (going from + Java to C++.) Create an abstract Java subclass that inherits from the + director-enabled class instead. Using the previous Foo class example:</P> +<DIV class="code"> +<PRE> +public abstract class UserVisibleFoo extends Foo { + /** Make sure user overrides this method, it's where the upcall + * happens. + */ + public abstract void method_upcall(Foo foo_object); + + /// Downcast from Foo to UserVisibleFoo + public static UserVisibleFoo downcastUserVisibleFoo(Foo foo_object) + { + try { + return (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object) : null); + } + + catch (ClassCastException exc) { + // Wasn't a FooDerived object, some other subclass of Foo + return null; + } + } +} +</PRE> +</DIV> +<P>This doesn't prevent the user from creating subclasses derived from + Foo, however, UserVisibleFoo provides the safety net that reminds the + user to override the <CODE>method_upcall()</CODE> method.</P> +</LI> +</OL> +<H2><A name="odds_ends"></A>21.12 Odds and ends</H2> +<H3><A name="javadoc_comments"></A>21.12.1 JavaDoc comments</H3> +<P> The SWIG documentation system is currently deprecated. When it is + resurrected JavaDoc comments will be fully supported. If you can't wait + for the full documentation system a couple of workarounds are + available. The <TT>%javamethodmodifiers</TT> feature can be used for + adding proxy class method comments and module class method comments. + The "javaimports" typemap can be hijacked for adding in proxy class + JavaDoc comments. The <TT>jniclassimports</TT> or <TT> +jniclassclassmodifiers</TT> pragmas can also be used for adding + intermediary JNI class comments and likewise the <TT>moduleimports</TT> + or <TT>moduleclassmodifiers</TT> pragmas for the module class. Here is + an example adding in a proxy class and method comment:</P> +<DIV class="code"> +<PRE> +%javamethodmodifiers Barmy::lose_marbles() " + /** + * Calling this method will make you mad. + * Use with <b>utmost</b> caution. + */ + public"; + +%typemap(javaimports) Barmy " +/** The crazy class. Use as a last resort. */" + +class Barmy { +public: + void lose_marbles() {} +}; +</PRE> +</DIV> +<P> Note the "public" added at the end of the <TT>%javamethodmodifiers</TT> + as this is the default for this feature. The generated proxy class with + JavaDoc comments is then as follows:</P> +<DIV class="code"> +<PRE> +/** The crazy class. Use as a last resort. */ +public class Barmy { +... + /** + * Calling this method will make you mad. + * Use with <b>utmost</b> caution. + */ + public void lose_marbles() { + ... + } +... +} +</PRE> +</DIV> +<H3><A name="functional_interface"></A>21.12.2 Functional interface + without proxy classes</H3> +<P> It is possible to run SWIG in a mode that does not produce proxy + classes by using the -noproxy commandline option. The interface is + rather primitive when wrapping structures or classes and is accessed + through function calls to the module class. All the functions in the + module class are wrapped by functions with identical names as those in + the intermediary JNI class.</P> +<P> Consider the example we looked at when examining proxy classes:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int x; + int spam(int num, Foo* foo); +}; +</PRE> +</DIV> +<P> When using <TT>-noproxy</TT>, type wrapper classes are generated + instead of proxy classes. Access to all the functions and variables is + through a C like set of functions where the first parameter passed is + the pointer to the class, that is an instance of a type wrapper class. + Here is what the module class looks like:</P> +<DIV class="code"> +<PRE> +public class example { + public static void Foo_x_get(SWIGTYPE_p_Foo self, int x) {...} + public static int Foo_x_get(SWIGTYPE_p_Foo self) {...} + public static int Foo_spam(SWIGTYPE_p_Foo self, int num, SWIGTYPE_p_Foo foo) {...} + public static SWIGTYPE_p_Foo new_Foo() {...} + public static void delete_Foo(SWIGTYPE_p_Foo self) {...} +} +</PRE> +</DIV> +<P> This approach is not nearly as natural as using proxy classes as the + functions need to be used like this:</P> +<DIV class="code"> +<PRE> +SWIGTYPE_p_Foo foo = example.new_Foo(); +example.Foo_x_set(foo, 10); +int var = example.Foo_x_get(foo); +example.Foo_spam(foo, 20, foo); +example.delete_Foo(foo); +</PRE> +</DIV> +<P> Unlike proxy classes, there is no attempt at tracking memory. All + destructors have to be called manually for example the <TT> +delete_Foo(foo)</TT> call above.</P> +<H3><A name="using_own_jni_functions"></A>21.12.3 Using your own JNI + functions</H3> +<P> You may have some hand written JNI functions that you want to use in + addition to the SWIG generated JNI functions. Adding these to your SWIG + generated package is possible using the <TT>%native</TT> directive. If + you don't want SWIG to wrap your JNI function then of course you can + simply use the <TT>%ignore</TT> directive. However, if you want SWIG to + generate just the Java code for a JNI function then use the <TT>%native</TT> + directive. The C types for the parameters and return type must be + specified in place of the JNI types and the function name must be the + native method name. For example:</P> +<DIV class="code"> +<PRE> +%native (HandRolled) void HandRolled(int, char *); +%{ +JNIEXPORT void JNICALL Java_packageName_moduleName_HandRolled(JNIEnv *, jclass, + jlong, jstring); +%} +</PRE> +</DIV> +<P> No C JNI function will be generated and the <TT> +Java_packageName_moduleName_HandRolled</TT> function will be accessible + using the SWIG generated Java native method call in the intermediary + JNI class which will look like this:</P> +<DIV class="code"> +<PRE> + public final static native void HandRolled(int jarg1, String jarg2); +</PRE> +</DIV> +<P> and as usual this function is wrapped by another which for a global + C function would appear in the module class:</P> +<DIV class="code"> +<PRE> + public static void HandRolled(int arg0, String arg1) { + exampleJNI.HandRolled(arg0, arg1); + } +</PRE> +</DIV> +<P> The <TT>packageName</TT> and <TT>moduleName</TT> must of course be + correct else you will get linker errors when the JVM dynamically loads + the JNI function. You may have to add in some "jtype", "jstype", + "javain" and "javaout" typemaps when wrapping some JNI types. Here the + default typemaps work for <TT>int</TT> and <TT>char *</TT>.</P> +<P> In summary the <TT>%native</TT> directive is telling SWIG to + generate the Java code to access the JNI C code, but not the JNI C + function itself. This directive is only really useful if you want to + mix your own hand crafted JNI code and the SWIG generated code into one + Java class or package.</P> +<H3><A name="performance"></A>21.12.4 Performance concerns and hints</H3> +<P> If you're directly manipulating huge arrays of complex objects from + Java, performance may suffer greatly when using the array functions in <TT> +arrays_java.i</TT>. Try and minimise the expensive JNI calls to C/C++ + functions, perhaps by using temporary Java variables instead of + accessing the information directly from the C/C++ object.</P> +<P> Java classes without any finalizers generally speed up code + execution as there is less for the garbage collector to do. Finalizer + generation can be stopped by using an empty <TT>javafinalize</TT> + typemap:</P> +<DIV class="code"> +<PRE> +%typemap(javafinalize) SWIGTYPE "" +</PRE> +</DIV> +<P> However, you will have to be careful about memory management and + make sure that you code in a call to the <TT>delete()</TT> member + function. This method normally calls the C++ destructor or <TT>free()</TT> + for C code.</P> +<H3><A name="java_debugging"></A>21.12.5 Debugging</H3> +<P> The generated code can be debugged using both a Java debugger and a + C++ debugger using the usual debugging techniques. Breakpoints can be + set in either Java or C++ code and so both can be debugged + simultaneously. Most debuggers do not understand both Java and C++, + with one noteable exception of Sun Studio, where it is possible to step + from Java code into a JNI method within one environment.</P> +<P> Alternatively, debugging can involve placing debug printout + statements in the JNI layer using the <TT>%exception</TT> directive. + See the <A href="#Customization_exception_special_variables">special + variables for %exception</A> section. Many of the default typemaps can + also be overidden and modified for adding in extra logging/debug + display information.</P> +<P> The <TT>-Xcheck:jni</TT> and <TT>-Xcheck:nabounds</TT> Java + executable options are useful for debugging to make sure the JNI code + is behaving. The -verbose:jni and -verbose:gc are also useful options + for monitoring code behaviour.</P> +<H2><A name="java_examples"></A>21.13 Examples</H2> +<P> The directory Examples/java has a number of further examples. Take a + look at these if you want to see some of the techniques described in + action. The Examples/index.html file in the parent directory contains + the SWIG Examples Documentation and is a useful starting point. If your + SWIG installation went well Unix users should be able to type <TT>make</TT> + in each example directory, then <TT>java main</TT> to see them running. + For the benefit of Windows users, there are also Visual C++ project + files in a couple of the <A href="#Windows_examples">Windows Examples</A> +. There are also many regression tests in the Examples/test-suite + directory. Many of these have runtime tests in the java subdirectory.</P> +<HR NOSHADE> +<H1><A name="Lisp_nn1"></A>22 SWIG and Common Lisp</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Lisp_nn2">Allegro Common Lisp</A></LI> +<LI><A href="#Lisp_nn3">Common Foreign Function Interface(CFFI)</A> +<UL> +<LI><A href="#Lisp_nn4">Additional Commandline Options</A></LI> +<LI><A href="#Lisp_nn5">Generating CFFI bindings</A></LI> +<LI><A href="#Lisp_nn6">Generating CFFI bindings for C++ code</A></LI> +<LI><A href="#Lisp_nn7">Inserting user code into generated files</A></LI> +</UL> +</LI> +<LI><A href="#Lisp_nn8">CLISP</A> +<UL> +<LI><A href="#Lisp_nn9">Additional Commandline Options</A></LI> +<LI><A href="#Lisp_nn10">Details on CLISP bindings</A></LI> +</UL> +</LI> +<LI><A href="#Lisp_nn11">UFFI</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> Common Lisp is a high-level, all-purpose, object-oriented, dynamic, + functional programming language with long history. Common Lisp is used + in many fields, ranging from web development to finance, and also + common in computer science education. There are more than 9 different + implementations of common lisp which are available, all have different + foreign function interfaces. SWIG currently supports only the Allegro + Common Lisp, Common Foreign Function Interface(CFFI), CLisp and UFFI + foreign function interfaces.</P> +<H2><A name="Lisp_nn2"></A>22.1 Allegro Common Lisp</H2> +<P> Allegro Common Lisp support in SWIG has been updated to include + support for both C and C++. You can read about the interface <A href="#Allegrocl_nn1"> +here</A></P> +<H2><A name="Lisp_nn3"></A>22.2 Common Foreign Function Interface(CFFI)</H2> +<P> CFFI, the Common Foreign Function Interface, is a portable foreign + function interface for ANSI Common Lisp systems, similar in spirit to + UFFI. Unlike UFFI, CFFI requires only a small set of low-level + functionality from the Lisp implementation, such as calling a foreign + function by name, allocating foreign memory, and dereferencing + pointers.</P> +<P> To run the cffi module of SWIG requires very little effort, you just + need to run:</P> +<DIV class="code"> +<PRE> +swig -cffi -module <I>module-name</I> <I>file-name</I> + +</PRE> +</DIV> +<P> But a better was of using all the power of SWIG is to write SWIG + interface files. Below we will explain how to write interface files and + the various things which you can do with them.</P> +<H3><A name="Lisp_nn4"></A>22.2.1 Additional Commandline Options</H3> +<P> The following table list the additional commandline options + available for the CLISP module. They can also be seen by using:</P> +<DIV class="code"> +<PRE> +swig -cffi -help +</PRE> +</DIV> +<BR> +<TABLE summary="CFFI specific options"> +<TR><TH> CFFI specific options</TH></TR> +<TR><TD>-generate-typedef</TD><TD>If this option is given then defctype + will be used to generate +<!--br\--> + shortcuts according to the typedefs in the input.</TD></TR> +<TR><TD>-[no]cwrap</TD><TD>Turn on or turn off generation of an + intermediate C file when +<!--br\--> + creating a C interface. By default this is only done for C++ code.</TD></TR> +<TR><TD>-[no]swig-lisp</TD><TD>Turns on or off generation of code for + helper lisp macro, functions, etc. which SWIG uses while generating + wrappers. These macros, functions may still be used by generated + wrapper code.</TD></TR> +</TABLE> +<H3><A name="Lisp_nn5"></A>22.2.2 Generating CFFI bindings</H3> + As we mentioned earlier the ideal way to use SWIG is to use interface + files. To illustrate the use of it, lets assume that we have a file + named<I> test.h</I> with the following C code:<DIV class="code"> +<PRE> +#define y 5 +#define x (y >> 1) + +typedef int days; + +struct bar { + short p, q; + char a, b; + int *z[1000]; + struct bar * n; +}; + +struct bar * my_struct; + +struct foo { + int a; + struct foo * b[100]; + +}; + +int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p); + +int func123(div_t * p,int **q[100],int r[][1000][10]); + +void lispsort_double (int n, double * array); + +enum color { RED, BLUE, GREEN}; +</PRE> +</DIV> Corresponding to this we will write a simple interface file:<DIV class="code"> +<PRE> +%module test + +%include "test.h" + +</PRE> +</DIV> The generated SWIG Code will be:<DIV class="targetlang"> +<PRE> +;;;SWIG wrapper code starts here + +(cl:defmacro defanonenum (&body enums) + "Converts anonymous enums to defconstants." + `(cl:progn ,@(cl:loop for value in enums + for index = 0 then (cl:1+ index) + when (cl:listp value) do (cl:setf index (cl:second value) + value (cl:first value)) + collect `(cl:defconstant ,value ,index)))) + +(cl:eval-when (:compile-toplevel :load-toplevel) + (cl:unless (cl:fboundp 'swig-lispify) + (cl:defun swig-lispify (name flag cl:&optional (package cl:*package*)) + (cl:labels ((helper (lst last rest cl:&aux (c (cl:car lst))) + (cl:cond + ((cl:null lst) + rest) + ((cl:upper-case-p c) + (helper (cl:cdr lst) 'upper + (cl:case last + ((lower digit) (cl:list* c #\- rest)) + (cl:t (cl:cons c rest))))) + ((cl:lower-case-p c) + (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest))) + ((cl:digit-char-p c) + (helper (cl:cdr lst) 'digit + (cl:case last + ((upper lower) (cl:list* c #\- rest)) + (cl:t (cl:cons c rest))))) + ((cl:char-equal c #\_) + (helper (cl:cdr lst) '_ (cl:cons #\- rest))) + (cl:t + (cl:error "Invalid character: ~A" c))))) + (cl:let ((fix (cl:case flag + ((constant enumvalue) "+") + (variable "*") + (cl:t "")))) + (cl:intern + (cl:concatenate + 'cl:string + fix + (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil)) + fix) + package)))))) + +;;;SWIG wrapper code ends here + + +(cl:defconstant y 5) + +(cl:defconstant x (cl:ash 5 -1)) + +(cffi:defcstruct bar + (p :short) + (q :short) + (a :char) + (b :char) + (z :pointer) + (n :pointer)) + +(cffi:defcvar ("my_struct" my_struct) + :pointer) + +(cffi:defcstruct foo + (a :int) + (b :pointer)) + +(cffi:defcfun ("pointer_func" pointer_func) :int + (ClosureFun :pointer) + (p :int)) + +(cffi:defcfun ("func123" func123) :int + (p :pointer) + (q :pointer) + (r :pointer)) + +(cffi:defcfun ("lispsort_double" lispsort_double) :void + (n :int) + (array :pointer)) + +(cffi:defcenum color + :RED + :BLUE + :GREEN) +</PRE> +</DIV> +<P> The<I> SWIG wrapper</I> code refers to the special code which SWIG + may need to use while wrapping C code. You can turn on/off the + generation of this code by using the<I> -[no]swig-lisp</I> option. You + must have noticed that SWIG goes one extra step to ensure that CFFI + does not do automatic lispification of the C function names. The reason + SWIG does this is because quite often developers want to build a nice + CLOS based lispy API, and this one to one correspondence between C + function names and lisp function name helps.</P> +<P> Maybe you want to have your own convention for generating lisp + function names for corresponding C function names, or you just want to + lispify the names, also, before we forget you want to export the + generated lisp names. To do this, we will use the SWIG <A href="#features"> +feature directive</A>. Let's edit the interface file such that the C + type "div_t*" is changed to Lisp type ":my-pointer", we lispify all + names, export everything, and do some more stuff.</P> +<DIV class="code"> +<PRE> +%module test + +%typemap(cin) div_t* ":my-pointer"; + +%feature("intern_function","1"); +%feature("export"); + +%feature("inline") lispsort_double; + +%feature("intern_function", "my-lispify") lispsort_double; +%rename func123 renamed_cool_func; +%ignore "pointer_func"; + +%include "test.h" + +</PRE> +</DIV> +<P> The<I> typemap(cin)</I> ensures that for all arguments which are + input to C with the type "div_t*", the ":my-pointer" type be used. + Similarly<I> typemap(cout)</I> are used for all types which are + returned from C.</P> +<P> The feature<I> intern_function</I> ensures that all C names are + interned using the<B> swig-lispify</B> function. The "1" given to the + feature is optional. The use of feature like<I> + %feature("intern_function","1");</I> globally enables interning for + everything. If you want to target a single function, or declaration + then use the targeted version of feature,<I> + %feature("intern_function", "my-lispify") lispsort_double;</I>, here we + are using an additional feature which allows us to use our lispify + function.</P> +<P>The<I> export</I> feature allows us to export the symbols. The<I> + inline</I> feature declaims the declared function as inline. The<I> + rename</I> directive allows us to change the name(it is useful when + generating C wrapper code for handling overloaded functions). The<I> + ignore</I> directive ignores a certain declaration.</P> +<P>There are several other things which are possible, to see some + example of usage of SWIG look at the Lispbuilder and wxCL projects. The + generated code with 'noswig-lisp' option is:</P> +<DIV class="targetlang"> +<PRE> +(cl:defconstant #.(swig-lispify "y" 'constant) 5) + +(cl:export '#.(swig-lispify "y" 'constant)) + +(cl:defconstant #.(swig-lispify "x" 'constant) (cl:ash 5 -1)) + +(cl:export '#.(swig-lispify "x" 'constant)) + +(cffi:defcstruct #.(swig-lispify "bar" 'classname) + (#.(swig-lispify "p" 'slotname) :short) + (#.(swig-lispify "q" 'slotname) :short) + (#.(swig-lispify "a" 'slotname) :char) + (#.(swig-lispify "b" 'slotname) :char) + (#.(swig-lispify "z" 'slotname) :pointer) + (#.(swig-lispify "n" 'slotname) :pointer)) + +(cl:export '#.(swig-lispify "bar" 'classname)) + +(cl:export '#.(swig-lispify "p" 'slotname)) + +(cl:export '#.(swig-lispify "q" 'slotname)) + +(cl:export '#.(swig-lispify "a" 'slotname)) + +(cl:export '#.(swig-lispify "b" 'slotname)) + +(cl:export '#.(swig-lispify "z" 'slotname)) + +(cl:export '#.(swig-lispify "n" 'slotname)) + +(cffi:defcvar ("my_struct" #.(swig-lispify "my_struct" 'variable)) + :pointer) + +(cl:export '#.(swig-lispify "my_struct" 'variable)) + +(cffi:defcstruct #.(swig-lispify "foo" 'classname) + (#.(swig-lispify "a" 'slotname) :int) + (#.(swig-lispify "b" 'slotname) :pointer)) + +(cl:export '#.(swig-lispify "foo" 'classname)) + +(cl:export '#.(swig-lispify "a" 'slotname)) + +(cl:export '#.(swig-lispify "b" 'slotname)) + +(cffi:defcfun ("renamed_cool_func" #.(swig-lispify "renamed_cool_func" 'function)) :int + (p :my-pointer) + (q :pointer) + (r :pointer)) + +(cl:export '#.(swig-lispify "renamed_cool_func" 'function)) + +(cl:declaim (cl:inline #.(my-lispify "lispsort_double" 'function))) + +(cffi:defcfun ("lispsort_double" #.(my-lispify "lispsort_double" 'function)) :void + (n :int) + (array :pointer)) + +(cl:export '#.(my-lispify "lispsort_double" 'function)) + +(cffi:defcenum #.(swig-lispify "color" 'enumname) + #.(swig-lispify "RED" 'enumvalue :keyword) + #.(swig-lispify "BLUE" 'enumvalue :keyword) + #.(swig-lispify "GREEN" 'enumvalue :keyword)) + +(cl:export '#.(swig-lispify "color" 'enumname)) + +</PRE> +</DIV> +<H3><A name="Lisp_nn6"></A>22.2.3 Generating CFFI bindings for C++ code</H3> +<P>This feature to SWIG (for CFFI) is very new and still far from + complete. Pitch in with your patches, bug reports and feature requests + to improve it.</P> +<P> Generating bindings for C++ code, requires<I> -c++</I> option to be + present and it first generates C binding which will wrap the C++ code, + and then generates the corresponding CFFI wrapper code. In the + generated C wrapper code, you will often want to put your own C code, + such as the code to include various files. This can be done by making + use of "%{" and "%}" as shown below.</P> +<DIV class="code"> +<PRE> +%{ + #include "Test/test.h" +%} +</PRE> +</DIV> +<P> Also, while parsing the C++ file and generating C wrapper code SWIG + may need to be able to understand various symbols used in other header + files. To help SWIG in doing this while ensuring that wrapper code is + generated for the target file, use the "import" directive. The + "include" directive specifies the target file for which wrapper code + will be generated.</P> +<DIV class="code"> +<PRE> + +%import "ancillary/header.h" + +%include "target/header.h" + +</PRE> +</DIV> Various features which were available for C headers can also be + used here. The target header which we are going to use here is:<DIV class="code"> +<PRE> +namespace OpenDemo { + class Test + { + public: + float x; + // constructors + Test (void) {x = 0;} + Test (float X) {x = X;} + + // vector addition + Test operator+ (const Test& v) const {return Test (x+v.x);} + + // length squared + float lengthSquared (void) const {return this->dot (*this);} + + static float distance (const Test& a, const Test& b){return(a-b).length();} + + inline Test parallelComponent (const Test& unitBasis) const { + return unitBasis * projection; + } + + Test setYtoZero (void) const {return Test (this->x);} + + static const Test zero; + }; + + + inline Test operator* (float s, const Test& v) {return v*s;} + + + inline std::ostream& operator<< (std::ostream& o, const Test& v) + { + return o << "(" << v.x << ")"; + } + + + inline Test RandomUnitVectorOnXZPlane (void) + { + return RandomVectorInUnitRadiusSphere().setYtoZero().normalize(); + } +} +</PRE> +</DIV> +<P>The interface used is:</P> +<DIV class="code"> +<PRE> +%module test +%include "test.cpp" +</PRE> +</DIV> SWIG generates 3 files, the first one is a C wrap which we don't + show, the second is the plain CFFI wrapper which is as shown below:<DIV class="targetlang"> +<PRE> +(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void + (self :pointer) + (x :float)) + +(cffi:defcfun ("_wrap_Test_x_get" Test_x_get) :float + (self :pointer)) + +(cffi:defcfun ("_wrap_new_Test__SWIG_0" new_Test) :pointer) + +(cffi:defcfun ("_wrap_new_Test__SWIG_1" new_Test) :pointer + (X :float)) + +(cffi:defcfun ("_wrap_Test___add__" Test___add__) :pointer + (self :pointer) + (v :pointer)) + +(cffi:defcfun ("_wrap_Test_lengthSquared" Test_lengthSquared) :float + (self :pointer)) + +(cffi:defcfun ("_wrap_Test_distance" Test_distance) :float + (a :pointer) + (b :pointer)) + +(cffi:defcfun ("_wrap_Test_parallelComponent" Test_parallelComponent) :pointer + (self :pointer) + (unitBasis :pointer)) + +(cffi:defcfun ("_wrap_Test_setYtoZero" Test_setYtoZero) :pointer + (self :pointer)) + +(cffi:defcvar ("Test_zero" Test_zero) + :pointer) + +(cffi:defcfun ("_wrap_delete_Test" delete_Test) :void + (self :pointer)) + +(cffi:defcfun ("_wrap___mul__" __mul__) :pointer + (s :float) + (v :pointer)) + +(cffi:defcfun ("_wrap___lshift__" __lshift__) :pointer + (o :pointer) + (v :pointer)) + +(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer) +</PRE> +</DIV> The output is pretty good but it fails in disambiguating + overloaded functions such as the constructor, in this case. One way of + resolving this problem is to make the interface use the rename + directiv, but hopefully there are better solutions. In addition SWIG + also generates, a CLOS file<DIV class="targetlang"> +<PRE> +(clos:defclass test() + ((ff :reader ff-pointer))) + +(clos:defmethod (cl:setf x) (arg0 (obj test)) + (Test_x_set (ff-pointer obj) arg0)) + +(clos:defmethod x ((obj test)) + (Test_x_get (ff-pointer obj))) + +(cl:shadow "+") +(clos:defmethod + ((obj test) (self test) (v test)) + (Test___add__ (ff-pointer obj) (ff-pointer self) (ff-pointer v))) + +(clos:defmethod length-squared ((obj test) (self test)) + (Test_lengthSquared (ff-pointer obj) (ff-pointer self))) + +(clos:defmethod parallel-component ((obj test) (self test) (unitBasis test)) + (Test_parallelComponent (ff-pointer obj) (ff-pointer self) (ff-pointer unitBasis))) + +(clos:defmethod set-yto-zero ((obj test) (self test)) + (Test_setYtoZero (ff-pointer obj) (ff-pointer self))) +</PRE> +</DIV> +<P>I agree that the CFFI C++ module needs lot more work. But I hope it + provides a starting point, on which you can base your work of importing + C++ libraries to Lisp.</P> +<P> If you have any questions, suggestions, patches, etc., related to + CFFI module feel free to contact us on the SWIG mailing list, and also + please add a "[CFFI]" tag in the subject line.</P> +<H3><A name="Lisp_nn7"></A>22.2.4 Inserting user code into generated + files</H3> +<P> It is often necessary to <A href="#SWIG_nn40">include user-defined + code</A> into the automatically generated interface files. For example, + when building a C++ interface, example_wrap.cxx will likely not compile + unless you add a <TT>#include "header.h"</TT> directive. This can be + done using the SWIG <TT>%insert(section) %{ ...code... %}</TT> + directive:</P> +<DIV class="code"> +<PRE> +%module example + +%{ +#include "header.h" +%} + +%include "header.h" + +int fact(int n); +</PRE> +</DIV> +<P> Additional sections have been added for inserting into the generated + lisp interface file:</P> +<UL> +<LI><TT>lisphead</TT> - inserts before type declarations</LI> +<LI><TT>swiglisp</TT> - inserts after type declarations according to + where it appears in the .i file</LI> +</UL> +<P> Note that the block <TT>%{ ... %}</TT> is effectively a shortcut for + <TT>%insert("header") %{ ... %}</TT>.</P> +<H2><A name="Lisp_nn8"></A>22.3 CLISP</H2> +<P> <A href="http://clisp.cons.org">CLISP</A> is a feature-loaded + implementation of common lisp which is portable across most of the + operating system environments and hardware. CLISP includes an + interpreter, a compiler, a debugger, CLOS, MOP, a foreign language + interface, i18n, regular expressions, a socket interface, and more. An + X11 interface is available through CLX, Garnet and CLUE/CLIO. Command + line editing is provided by readline. CLISP runs Maxima, ACL2 and many + other Common Lisp packages.</P> +<P> To run the clisp module of SWIG requires very little effort, you + just need to execute:</P> +<DIV class="code"> +<PRE> +swig -clisp -module <I>module-name</I> <I>file-name</I> + +</PRE> +</DIV> +<P> Because of the high level nature of the CLISP FFI, the bindings + generated by SWIG may not be absolutely correct, and you may need to + modify them. The good thing is that you don't need to complex interface + file for the CLISP module. The CLISP module tries to produce code which + is both human readable and easily modifyable.</P> +<H3><A name="Lisp_nn9"></A>22.3.1 Additional Commandline Options</H3> +<P> The following table list the additional commandline options + available for the CLISP module. They can also be seen by using:</P> +<DIV class="code"> +<PRE> +swig -clisp -help +</PRE> +</DIV> +<BR> +<TABLE summary="CLISP specific options"> +<TR><TH>CLISP specific options</TH></TR> +<TR><TD>-extern-all</TD><TD>If this option is given then clisp + definitions for all the functions +<BR> and global variables will be created otherwise only definitions for +<BR> externed functions and variables are created.</TD></TR> +<TR><TD>-generate-typedef</TD><TD>If this option is given then + def-c-type will be used to generate +<BR> shortcuts according to the typedefs in the input.</TD></TR> +</TABLE> +<H3><A name="Lisp_nn10"></A>22.3.2 Details on CLISP bindings</H3> +<P> As mentioned earlier the CLISP bindings generated by SWIG may need + some modifications. The clisp module creates a lisp file with the same + name as the module name. This lisp file contains a 'defpackage' + declaration, with the package name same as the module name. This + package uses the 'common-lisp' and 'ffi' packages. Also, package + exports all the functions, structures and variables for which an ffi + binding was generated. +<BR> After generating the defpackage statement, the clisp module also + sets the default language.<DIV class="targetlang"> +<PRE> +(defpackage :test + (:use :common-lisp :ffi) + (:export + :make-bar + :bar-x + :bar-y + :bar-a + :bar-b + :bar-z + :bar-n + :pointer_func + :func123 + :make-cfunr + :lispsort_double + :test123)) + +(in-package :test) + +(default-foreign-language :stdc) +</PRE> +</DIV></P> +<P> The ffi wrappers for functions and variables are generated as shown + below. When functions have arguments of type "double * array", SWIG + doesn't knows whether it is an 'out' argument or it is an array which + will be passed, so SWIG plays it safe by declaring it as an '(array + (ffi:c-ptr DOUBLE-FLOAT))'. For arguments of type "int **z[100]" where + SWIG has more information, i.e., it knows that 'z' is an array of + pointers to pointers of integers, SWIG defines it to be '(z (ffi:c-ptr + (ffi:c-array (ffi:c-ptr (ffi:c-ptr ffi:int)) 100)))'</P> +<DIV class="code"> +<PRE> +extern "C" { +int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int y); + +int func123(div_t * x,int **z[100],int y[][1000][10]); + +void lispsort_double (int n, double * array); + +void test123(float x , double y); + +} +</PRE> +</DIV><DIV class="targetlang"> +<PRE> +(ffi:def-call-out pointer_func + (:name "pointer_func") + (:arguments (ClosureFun (ffi:c-function (:arguments (arg0 (ffi:c-pointer NIL)) + (arg1 (ffi:c-pointer NIL)) + (arg2 (ffi:c-pointer NIL))) + (:return-type NIL))) + (y ffi:int)) + (:return-type ffi:int) + (:library +library-name+)) + +(ffi:def-call-out func123 + (:name "func123") + (:arguments (x (ffi:c-pointer div_t)) + (z (ffi:c-ptr (ffi:c-array (ffi:c-ptr (ffi:c-ptr ffi:int)) 100))) + (y (ffi:c-ptr (ffi:c-ptr (ffi:c-array ffi:int (1000 10)))))) + (:return-type ffi:int) + (:library +library-name+)) + + +(ffi:def-call-out lispsort_double + (:name "lispsort_double") + (:arguments (n ffi:int) + (array (ffi:c-ptr DOUBLE-FLOAT))) + (:return-type NIL) + (:library +library-name+)) + +(ffi:def-call-out test123 + (:name "test") + (:arguments (x SINGLE-FLOAT) + (y DOUBLE-FLOAT)) + (:return-type NIL) + (:library +library-name+)) + +</PRE> +</DIV> +<P> The module also handles strutcures and #define constants as shown + below. SWIG automatically adds the constructors and accessors created + for the struct to the list of symbols exported by the package.</P> +<DIV class="code"> +<PRE> +struct bar { + short x, y; + char a, b; + int *z[1000]; + struct bar * n; +}; + +#define max 1000 +</PRE> +</DIV><DIV class="targetlang"> +<PRE> +(ffi:def-c-struct bar + (x :type ffi:short) + (y :type ffi:short) + (a :type character) + (b :type character) + (z :type (ffi:c-array (ffi:c-ptr ffi:int) 1000)) + (n :type (ffi:c-pointer bar))) + +(defconstant max 1000) + +</PRE> +</DIV> +<H2><A name="Lisp_nn11"></A>22.4 UFFI</H2> +<HR NOSHADE> +<H1><A name="Lua_nn1"></A>23 SWIG and Lua</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Lua_nn2">Preliminaries</A></LI> +<LI><A href="#Lua_nn3">Running SWIG</A> +<UL> +<LI><A href="#Lua_nn4">Compiling and Linking and Interpreter</A></LI> +<LI><A href="#Lua_nn5">Compiling a dynamic module</A></LI> +<LI><A href="#Lua_nn6">Using your module</A></LI> +</UL> +</LI> +<LI><A href="#Lua_nn7">A tour of basic C/C++ wrapping</A> +<UL> +<LI><A href="#Lua_nn8">Modules</A></LI> +<LI><A href="#Lua_nn9">Functions</A></LI> +<LI><A href="#Lua_nn10">Global variables</A></LI> +<LI><A href="#Lua_nn11">Constants and enums</A></LI> +<LI><A href="#Lua_nn12">Pointers</A></LI> +<LI><A href="#Lua_nn13">Structures</A></LI> +<LI><A href="#Lua_nn14">C++ classes</A></LI> +<LI><A href="#Lua_nn15">C++ inheritance</A></LI> +<LI><A href="#Lua_nn16">Pointers, references, values, and arrays</A></LI> +<LI><A href="#Lua_nn17">C++ overloaded functions</A></LI> +<LI><A href="#Lua_nn18">C++ operators</A></LI> +<LI><A href="#Lua_nn19">Class extension with %extend</A></LI> +<LI><A href="#Lua_nn20">C++ templates</A></LI> +<LI><A href="#Lua_nn21">C++ Smart Pointers</A></LI> +<LI><A href="#Lua_nn22">C++ Exceptions</A></LI> +</UL> +</LI> +<LI><A href="#Lua_nn23">Typemaps</A> +<UL> +<LI><A href="#Lua_nn24">What is a typemap?</A></LI> +<LI><A href="#Lua_nn25">Using typemaps</A></LI> +<LI><A href="#Lua_nn26">Typemaps and arrays</A></LI> +<LI><A href="#Lua_nn27">Typemaps and pointer-pointer functions</A></LI> +</UL> +</LI> +<LI><A href="#Lua_nn28">Writing typemaps</A> +<UL> +<LI><A href="#Lua_nn29">Typemaps you can write</A></LI> +<LI><A href="#Lua_nn30">SWIG's Lua-C API</A></LI> +</UL> +</LI> +<LI><A href="#Lua_nn31">Customization of your Bindings</A> +<UL> +<LI><A href="#Lua_nn32">Writing your own custom wrappers</A></LI> +<LI><A href="#Lua_nn33">Adding additional Lua code</A></LI> +</UL> +</LI> +<LI><A href="#Lua_nn34">Details on the Lua binding</A> +<UL> +<LI><A href="#Lua_nn35">Binding global data into the module.</A></LI> +<LI><A href="#Lua_nn36">Userdata and Metatables</A></LI> +<LI><A href="#Lua_nn37">Memory management</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> Lua is an extension programming language designed to support general + procedural programming with data description facilities. It also offers + good support for object-oriented programming, functional programming, + and data-driven programming. Lua is intended to be used as a powerful, + light-weight configuration language for any program that needs one. Lua + is implemented as a library, written in clean C (that is, in the common + subset of ANSI C and C++). Its also a<EM> really</EM> tiny language, + less than 6000 lines of code, which compiles to <100 kilobytes of + binary code. It can be found at <A href="http://www.lua.org"> +http://www.lua.org</A></P> +<H2><A name="Lua_nn2"></A>23.1 Preliminaries</H2> +<P> The current SWIG implementation is designed to work with Lua 5.0.x + and Lua 5.1.x. It should work with later versions of Lua, but certainly + not with Lua 4.0 due to substantial API changes. ((Currently SWIG + generated code has only been tested on Windows with MingW, though given + the nature of Lua, is should not have problems on other OS's)). It is + possible to either static link or dynamic link a Lua module into the + interpreter (normally Lua static links its libraries, as dynamic + linking is not available on all platforms).</P> +<H2><A name="Lua_nn3"></A>23.2 Running SWIG</H2> +<P> Suppose that you defined a SWIG module such as the following:</P> +<DIV class="code"> +<PRE> +%module example +%{ +#include "example.h" +%} +int gcd(int x, int y); +extern double Foo; +</PRE> +</DIV> +<P> To build a Lua module, run SWIG using the <TT>-lua</TT> option.</P> +<DIV class="shell"> +<PRE> +$ swig -lua example.i +</PRE> +</DIV> +<P> If building a C++ extension, add the <TT>-c++</TT> option:</P> +<DIV class="shell"> +<PRE> +$ swig -c++ -lua example.i +</PRE> +</DIV> +<P> This creates a C/C++ source file <TT>example_wrap.c</TT> or <TT> +example_wrap.cxx</TT>. The generated C source file contains the + low-level wrappers that need to be compiled and linked with the rest of + your C/C++ application to create an extension module.</P> +<P> The name of the wrapper file is derived from the name of the input + file. For example, if the input file is <TT>example.i</TT>, the name of + the wrapper file is <TT>example_wrap.c</TT>. To change this, you can + use the -o option. The wrappered module will export one function <TT> +"int luaopen_example(lua_State* L)"</TT> which must be called to + register the module with the Lua interpreter. The name + "luaopen_example" depends upon the name of the module.</P> +<H3><A name="Lua_nn4"></A>23.2.1 Compiling and Linking and Interpreter</H3> +<P> Normally Lua is embedded into another program and will be statically + linked. An extremely simple stand-alone interpreter (<TT>min.c</TT>) is + given below:</P> +<DIV class="code"> +<PRE> +#include <stdio.h> +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" + +extern int luaopen_example(lua_State* L); // declare the wrapped module + +int main(int argc,char* argv[]) +{ + lua_State *L; + if (argc<2) + { + printf("%s: <filename.lua>\n",argv[0]); + return 0; + } + L=lua_open(); + luaopen_base(L); // load basic libs (eg. print) + luaopen_example(L); // load the wrappered module + if (luaL_loadfile(L,argv[1])==0) // load and run the file + lua_pcall(L,0,0,0); + else + printf("unable to load %s\n",argv[1]); + lua_close(L); + return 0; +} +</PRE> +</DIV> +<P> A much improved set of code can be found in the Lua distribution <TT> +src/lua/lua.c</TT>. Include your module, just add the external + declaration & add a <TT>#define LUA_EXTRALIBS + {"example",luaopen_example}</TT>, at the relevant place.</P> +<P> The exact commands for compiling and linking vary from platform to + platform. Here is a possible set of commands of doing this:</P> +<DIV class="shell"> +<PRE> +$ swig -lua example.i -o example_wrap.c +$ gcc -I/usr/include/lua -c min.c -o min.o +$ gcc -I/usr/include/lua -c example_wrap.c -o example_wrap.o +$ gcc -c example.c -o example.o +$ gcc -I/usr/include/lua -L/usr/lib/lua min.o example_wrap.o example.o -o my_lua +</PRE> +</DIV> +<H3><A name="Lua_nn5"></A>23.2.2 Compiling a dynamic module</H3> +<P> Most, but not all platforms support the dynamic loading of modules + (Windows & Linux do). Refer to the Lua manual to determine if your + platform supports it. For compiling a dynamically loaded module the + same wrapper can be used. The commands will be something like this:</P> +<DIV class="shell"> +<PRE> +$ swig -lua example.i -o example_wrap.c +$ gcc -I/usr/include/lua -c example_wrap.c -o example_wrap.o +$ gcc -c example.c -o example.o +$ gcc -shared -I/usr/include/lua -L/usr/lib/lua example_wrap.o example.o -o example.so +</PRE> +</DIV> +<P> The wrappers produced by SWIG can be compiled and linked with Lua + 5.1.x. The loading is extremely simple.</P> +<DIV class="targetlang"> +<PRE> +require("example") +</PRE> +</DIV> +<P> For those using Lua 5.0.x, you will also need an interpreter with + the loadlib function (such as the default interpreter compiled with + Lua). In order to dynamically load a module you must call the loadlib + function with two parameters: the filename of the shared library, and + the function exported by SWIG. Calling loadlib should return the + function, which you then call to initialise the module</P> +<DIV class="targetlang"> +<PRE> +my_init=loadlib("example.so","luaopen_example") -- for Unix/Linux +--my_init=loadlib("example.dll","luaopen_example") -- for Windows +assert(my_init) -- name sure its not nil +my_init() -- call the init fn of the lib +</PRE> +</DIV> +<P> Or can be done in a single line of Lua code</P> +<DIV class="targetlang"> +<PRE> +assert(loadlib("example.so","luaopen_example"))() +</PRE> +</DIV> +<P> If the code didn't work, don't panic. The best thing to do is to + copy the module and your interpreter into a single directory and then + execute the interpreter and try to manually load the module (take care, + all this code is case sensitive).</P> +<DIV class="targetlang"> +<PRE> +a,b,c=package.loadlib("example.so","luaopen_example") -- for Unix/Linux +--a,b,c=package.loadlib("example.dll","luaopen_example") -- for Windows +print(a,b,c) +</PRE> +</DIV> +<P> Note: for Lua 5.0: +<BR> The loadlib() function is in the global namespace, not in package. + So its just loadlib().</P> +<P> if 'a' is a function, this its all working fine, all you need to do + is call it</P> +<DIV class="targetlang"> +<PRE> + a() +</PRE> +</DIV> +<P> to load your library which will add a table 'example' with all the + functions added.</P> +<P> If it doesn't work, look at the error messages, in particular mesage + 'b' +<BR> <TT> The specified module could not be found.</TT> +<BR> Means that is cannot find the module, check your the location and + spelling of the module. +<BR> <TT> The specified procedure could not be found.</TT> +<BR> Means that it loaded the module, but cannot find the named + function. Again check the spelling, and if possible check to make sure + the functions were exported correctly. +<BR> <TT> 'loadlib' not installed/supported</TT> +<BR> Is quite obvious (Go back and consult the Lua documents on how to + enable loadlib for your platform).</P> +<H3><A name="Lua_nn6"></A>23.2.3 Using your module</H3> +<P> Assuming all goes well, you will be able to this:</P> +<DIV class="targetlang"> +<PRE> +$ ./my_lua +> print(example.gcd(4,6)) +2 +> print(example.Foo) +3 +> example.Foo=4 +> print(example.Foo) +4 +> +</PRE> +</DIV> +<H2><A name="Lua_nn7"></A>23.3 A tour of basic C/C++ wrapping</H2> +<P> By default, SWIG tries to build a very natural Lua interface to your + C/C++ code. This section briefly covers the essential aspects of this + wrapping.</P> +<H3><A name="Lua_nn8"></A>23.3.1 Modules</H3> +<P> The SWIG module directive specifies the name of the Lua module. If + you specify `module example', then everything is wrapped into a Lua + table 'example' containing all the functions and variables. When + choosing a module name, make sure you don't use the same name as a + built-in Lua command or standard module name.</P> +<H3><A name="Lua_nn9"></A>23.3.2 Functions</H3> +<P> Global functions are wrapped as new Lua built-in functions. For + example,</P> +<DIV class="code"> +<PRE> +%module example +int fact(int n);</PRE> +</DIV> +<P> creates a built-in function <TT>example.fact(n)</TT> that works + exactly like you think it does:</P> +<DIV class="targetlang"> +<PRE> +> print example.fact(4) +24 +> +</PRE> +</DIV> +<P> To avoid name collisions, SWIG create a Lua table which it keeps all + the functions and global variables in. It is possible to copy the + functions out of this and into the global environment with the + following code. This can easily overwrite existing functions, so this + must be used with care.</P> +<DIV class="targetlang"> +<PRE> +> for k,v in pairs(example) do _G[k]=v end +> print(fact(4)) +24 +> +</PRE> +</DIV> +<P> It is also possible to rename the module with an assignment.</P> +<DIV class="targetlang"> +<PRE> +> e=example +> print(e.fact(4)) +24 +> print(example.fact(4)) +24 +</PRE> +</DIV> +<H3><A name="Lua_nn10"></A>23.3.3 Global variables</H3> +<P> Global variables (which are linked to C code) are supported, and + appear to be just another variable in Lua. However the actual mechanism + is more complex. Given a global variable:</P> +<DIV class="code"> +<PRE>%module example +extern double Foo; +</PRE> +</DIV> +<P> SWIG will effectively generate two functions <TT>example.Foo_set()</TT> + and <TT>example.Foo_get()</TT>. It then adds a metatable to the table + 'example' to call these functions at the correct time (when you attempt + to set or get examples.Foo). Therefore if you were to attempt to assign + the global to another variable, you will get a local copy within the + interpreter, which is no longer linked to the C code.</P> +<DIV class="targetlang"> +<PRE> +> print(example.Foo) +3 +> c=example.Foo -- c is a COPY of example.Foo, not the same thing +> example.Foo=4 +> print(c) +3 +> c=5 -- this will not effect the original example.Foo +> print(example.Foo,c) +4 5 +</PRE> +</DIV> +<P> Its is therefore not possible to 'move' the global variable into the + global namespace as it is with functions. It is however, possible to + rename the module with an assignment, to make it more convenient.</P> +<DIV class="targetlang"> +<PRE> +> e=example +> -- e and example are the same table +> -- so e.Foo and example.Foo are the same thing +> example.Foo=4 +> print(e.Foo) +4 +</PRE> +</DIV> +<P> If a variable is marked with the %immutable directive then any + attempts to set this variable will cause an Lua error. Given a global + variable:</P> +<DIV class="code"> +<PRE>%module example +%immutable; +extern double Foo; +%mutable; +</PRE> +</DIV> +<P> SWIG will allow the the reading of <TT>Foo</TT> but when a set + attempt is made, an error function will be called.</P> +<DIV class="targetlang"> +<PRE> +> print(e.Foo) -- reading works ok +4 +> example.Foo=40 -- but writing does not +This variable is immutable +stack traceback: + [C]: ? + [C]: ? + stdin:1: in main chunk + [C]: ? +</PRE> +</DIV> +<P> For those people who would rather that SWIG silently ignore the + setting of immutables (as previous versions of the Lua bindings did), + adding a <TT>-DSWIGLUA_IGNORE_SET_IMMUTABLE</TT> compile option will + remove this.</P> +<P> Unlike earlier versions of the binding, it is now possible to add + new functions or variables to the module, just as if it were a normal + table. This also allows the user to rename/remove existing functions + and constants (but not linked variables, mutable or immutable). + Therefore users are recommended to be careful when doing so.</P> +<DIV class="targetlang"> +<PRE> +> -- example.PI does not exist +> print(example.PI) +nil +> example.PI=3.142 -- new value added +> print(example.PI) +3.142 +</PRE> +</DIV> +<H3><A name="Lua_nn11"></A>23.3.4 Constants and enums</H3> +<P> Because Lua doesn't really have the concept of constants, C/C++ + constants are not really constant in Lua. They are actually just a copy + of the value into the Lua interpreter. Therefore they can be changed + just as any other value. For example given some constants:</P> +<DIV class="code"> +<PRE>%module example +%constant int ICONST=42; +#define SCONST "Hello World" +enum Days{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY}; +</PRE> +</DIV> +<P> This is 'effectively' converted into the following Lua code:</P> +<DIV class="targetlang"> +<PRE> +example.ICONST=42 +example.SCONST="Hello World" +example.SUNDAY=0 +.... +</PRE> +</DIV> +<P> Constants are not guaranteed to remain constant in Lua. The name of + the constant could be accidentally reassigned to refer to some other + object. Unfortunately, there is no easy way for SWIG to generate code + that prevents this. You will just have to be careful.</P> +<H3><A name="Lua_nn12"></A>23.3.5 Pointers</H3> +<P> C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no + problem working with incomplete type information. Given a wrapping of + the <file.h> interface:</P> +<DIV class="code"> +<PRE>%module example + +FILE *fopen(const char *filename, const char *mode); +int fputs(const char *, FILE *); +int fclose(FILE *); +</PRE> +</DIV> +<P> When wrapped, you will be able to use the functions in a natural way + from Lua. For example:</P> +<DIV class="targetlang"> +<PRE> +> f=example.fopen("junk","w") +> example.fputs("Hello World",f) +> example.fclose(f) +</PRE> +</DIV> +<P> Unlike many scripting languages, Lua has had support for pointers to + C/C++ object built in for a long time. They are called 'userdata'. + Unlike many other SWIG versions which use some kind of encoded + character string, all objects will be represented as a userdata. The + SWIG-Lua bindings provides a special function <TT>swig_type()</TT>, + which if given a userdata object will return the type of object pointed + to as a string (assuming it was a SWIG wrappered object).</P> +<DIV class="targetlang"> +<PRE> +> print(f) +userdata: 003FDA80 +> print(swig_type(f)) +FILE * -- its a FILE* +</PRE> +</DIV> +<P> Lua enforces the integrity of its userdata, so it is virtually + impossible to corrupt the data. But as the user of the pointer, you are + responsible for freeing it, or closing any resources associated with it + (just as you would in a C program). This does not apply so strictly to + classes & structs (see below). One final note: if a function returns a + NULL pointer, this is not encoded as a userdata, but as a Lua nil.</P> +<DIV class="targetlang"> +<PRE> +> f=example.fopen("not there","r") -- this will return a NULL in C +> print(f) +nil +</PRE> +</DIV> +<H3><A name="Lua_nn13"></A>23.3.6 Structures</H3> +<P> If you wrap a C structure, it is also mapped to a Lua userdata. By + adding a metatable to the userdata, this provides a very natural + interface. For example,</P> +<DIV class="code"> +<PRE>struct Point{ + int x,y; +}; +</PRE> +</DIV> +<P> is used as follows:</P> +<DIV class="targetlang"> +<PRE> +> p=example.new_Point() +> p.x=3 +> p.y=5 +> print(p.x,p.y) +3 5 +> +</PRE> +</DIV> +<P> Similar access is provided for unions and the data members of C++ + classes. +<BR> C structures are created using a function <TT>new_Point()</TT>, but + for C++ classes are created using just the name <TT>Point()</TT>.</P> +<P> If you print out the value of p in the above example, you will see + something like this:</P> +<DIV class="targetlang"> +<PRE> +> print(p) +userdata: 003FA320 +</PRE> +</DIV> +<P> Like the pointer in the previous section, this is held as a + userdata. However, additional features have been added to make this + more usable. SWIG effectivly creates some accessor/mutator functions to + get and set the data. These functions will be added to the userdata's + metatable. This provides the natural access to the member variables + that were shown above (see end of the document for full details).</P> +<P> <TT>const</TT> members of a structure are read-only. Data members + can also be forced to be read-only using the immutable directive. As + with other immutable's, setting attempts will be cause an error. For + example:</P> +<DIV class="code"> +<PRE>struct Foo { + ... + %immutable; + int x; // Read-only members + char *name; + %mutable; + ... +}; +</PRE> +</DIV> +<P> The mechanism for managing char* members as well as array members is + similar to other languages. It is somewhat cumbersome and should + probably be better handled by defining of typemaps (described later).</P> +<P> When a member of a structure is itself a structure, it is handled as + a pointer. For example, suppose you have two structures like this:</P> +<DIV class="code"> +<PRE>struct Foo { + int a; +}; + +struct Bar { + Foo f; +}; +</PRE> +</DIV> +<P> Now, suppose that you access the f attribute of Bar like this:</P> +<DIV class="targetlang"> +<PRE> +> b = Bar() +> x = b.f +</PRE> +</DIV> +<P> In this case, x is a pointer that points to the Foo that is inside + b. This is the same value as generated by this C code:</P> +<DIV class="code"> +<PRE> +Bar b; +Foo *x = &b->f; // Points inside b +</PRE> +</DIV> +<P> Because the pointer points inside the structure, you can modify the + contents and everything works just like you would expect. For example:</P> +<DIV class="targetlang"> +<PRE> +> b = Bar() +> b.f.a = 3 -- Modify attribute of structure member +> x = b.f +> x.a = 3 -- Modifies the same structure +</PRE> +</DIV> +<H3><A name="Lua_nn14"></A>23.3.7 C++ classes</H3> +<P> C++ classes are wrapped by a Lua userdata as well. For example, if + you have this class,</P> +<DIV class="code"> +<PRE>class List { +public: + List(); + ~List(); + int search(char *item); + void insert(char *item); + void remove(char *item); + char *get(int n); + int length; +}; +</PRE> +</DIV> +<P> you can use it in Lua like this:</P> +<DIV class="targetlang"> +<PRE> +> l = example.List() +> l:insert("Ale") +> l:insert("Stout") +> l:insert("Lager") +> print(l:get(1)) +Stout +> print(l:length) +3 +> +</PRE> +</DIV> +<P> (Note: for calling methods of a class, you use <TT> +class:method(args)</TT>, not <TT>class.method(args)</TT>, its an easy + mistake to make. However for data attributes it is <TT>class.attribute</TT> +)</P> +<P> Class data members are accessed in the same manner as C structures. + Static class members present a special problem for Lua, as Lua doesn't + have support for such features. Therefore, SWIG generates wrappers that + try to work around some of these issues. To illustrate, suppose you + have a class like this:</P> +<DIV class="targetlang"> +<PRE>class Spam { +public: + static void foo(); + static int bar; + +}; +</PRE> +</DIV> +<P> In Lua, the static members can be accessed as follows:</P> +<DIV class="code"> +<PRE> +> example.Spam_foo() -- calling Spam::foo() +> a=example.Spam_bar -- reading Spam::bar +> example.Spam_bar=b -- writing to Spam::bar +</PRE> +</DIV> +<P> It is not (currently) possible to access static members of an + instance:</P> +<DIV class="targetlang"> +<PRE> +> s=example.Spam() -- s is a Spam instance +> s.foo() -- Spam::foo() via an instance + -- does NOT work +</PRE> +</DIV> +<H3><A name="Lua_nn15"></A>23.3.8 C++ inheritance</H3> +<P> SWIG is fully aware of issues related to C++ inheritance. Therefore, + if you have classes like this</P> +<DIV class="code"> +<PRE>class Foo { +... +}; + +class Bar : public Foo { +... +}; +</PRE> +</DIV> +<P> And if you have functions like this</P> +<DIV class="code"> +<PRE>void spam(Foo *f); +</PRE> +</DIV> +<P> then the function <TT>spam()</TT> accepts a Foo pointer or a pointer + to any class derived from Foo.</P> +<P> It is safe to use multiple inheritance with SWIG.</P> +<H3><A name="Lua_nn16"></A>23.3.9 Pointers, references, values, and + arrays</H3> +<P> In C++, there are many different ways a function might receive and + manipulate objects. For example:</P> +<DIV class="code"> +<PRE>void spam1(Foo *x); // Pass by pointer +void spam2(Foo &x); // Pass by reference +void spam3(Foo x); // Pass by value +void spam4(Foo x[]); // Array of objects +</PRE> +</DIV> +<P> In SWIG, there is no detailed distinction like this--specifically, + there are only "objects". There are no pointers, references, arrays, + and so forth. Because of this, SWIG unifies all of these types together + in the wrapper code. For instance, if you actually had the above + functions, it is perfectly legal to do this:</P> +<DIV class="targetlang"> +<PRE> +> f = Foo() -- Create a Foo +> spam1(f) -- Ok. Pointer +> spam2(f) -- Ok. Reference +> spam3(f) -- Ok. Value. +> spam4(f) -- Ok. Array (1 element) +</PRE> +</DIV> +<P> Similar behaviour occurs for return values. For example, if you had + functions like this,</P> +<DIV class="code"> +<PRE>Foo *spam5(); +Foo &spam6(); +Foo spam7(); +</PRE> +</DIV> +<P> then all three functions will return a pointer to some Foo object. + Since the third function (spam7) returns a value, newly allocated + memory is used to hold the result and a pointer is returned (Lua will + release this memory when the return value is garbage collected). The + other two are pointers which are assumed to be managed by the C code + and so will not be garbage collected.</P> +<H3><A name="Lua_nn17"></A>23.3.10 C++ overloaded functions</H3> +<P> C++ overloaded functions, methods, and constructors are mostly + supported by SWIG. For example, if you have two functions like this:</P> +<DIV class="code"> +<PRE>void foo(int); +void foo(char *c); +</PRE> +</DIV> +<P> You can use them in Lua in a straightforward manner:</P> +<DIV class="targetlang"> +<PRE> +> foo(3) -- foo(int) +> foo("Hello") -- foo(char *c) +</PRE> +</DIV> +<P> However due to Lua's coercion mechanism is can sometimes do strange + things.</P> +<DIV class="targetlang"> +<PRE> +> foo("3") -- "3" can be coerced into an int, so it calls foo(int)! +</PRE> +</DIV> +<P> As this coercion mechanism is an integral part of Lua, there is no + easy way to get around this other than renaming of functions (see + below).</P> +<P> Similarly, if you have a class like this,</P> +<DIV class="code"> +<PRE>class Foo { +public: + Foo(); + Foo(const Foo &); + ... +}; +</PRE> +</DIV> +<P> you can write Lua code like this:</P> +<DIV class="targetlang"> +<PRE> +> f = Foo() -- Create a Foo +> g = Foo(f) -- Copy f +</PRE> +</DIV> +<P> Overloading support is not quite as flexible as in C++. Sometimes + there are methods that SWIG can't disambiguate. For example:</P> +<DIV class="code"> +<PRE>void spam(int); +void spam(short); +</PRE> +</DIV> +<P> or</P> +<DIV CLASS="CODE"> +<PRE>VOID FOO(bAR *B); +void foo(Bar &b); +</PRE> +</DIV> +<P> If declarations such as these appear, you will get a warning message + like this:</P> +<DIV class="shell"> +<PRE> +example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int) +at example.i:11. +</PRE> +</DIV> +<P> To fix this, you either need to ignore or rename one of the methods. + For example:</P> +<DIV class="code"> +<PRE>%rename(spam_short) spam(short); +... +void spam(int); +void spam(short); // Accessed as spam_short +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE>%ignore spam(short); +... +void spam(int); +void spam(short); // Ignored +</PRE> +</DIV> +<P> SWIG resolves overloaded functions and methods using a + disambiguation scheme that ranks and sorts declarations according to a + set of type-precedence rules. The order in which declarations appear in + the input does not matter except in situations where ambiguity + arises--in this case, the first declaration takes precedence.</P> +<P> Please refer to the "SWIG and C++" chapter for more information + about overloading.</P> +<P> Dealing with the Lua coercion mechanism, the priority is roughly + (integers, floats, strings, userdata). But it is better to rename the + functions rather than rely upon the ordering.</P> +<H3><A name="Lua_nn18"></A>23.3.11 C++ operators</H3> +<P> Certain C++ overloaded operators can be handled automatically by + SWIG. For example, consider a class like this:</P> +<DIV class="code"> +<PRE>class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c); + Complex operator+(const Complex &c) const; + Complex operator-(const Complex &c) const; + Complex operator*(const Complex &c) const; + Complex operator-() const; + + double re() const { return rpart; } + double im() const { return ipart; } +}; +</PRE> +</DIV> +<P> When wrapped, it works like you expect:</P> +<DIV class="targetlang"> +<PRE> +> c = Complex(3,4) +> d = Complex(7,8) +> e = c + d +> e:re() +10.0 +> e:im() +12.0 +</PRE> +</DIV> +<P> One restriction with operator overloading support is that SWIG is + not able to fully handle operators that aren't defined as part of the + class. For example, if you had code like this</P> +<DIV class="targetlang"> +<PRE>class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; +</PRE> +</DIV> +<P> then SWIG doesn't know what to do with the friend function--in fact, + it simply ignores it and issues a warning. You can still wrap the + operator, but you may have to encapsulate it in a special function. For + example:</P> +<DIV class="targetlang"> +<PRE>%rename(Complex_add_dc) operator+(double, const Complex &); +... +Complex operator+(double, const Complex &c); +</PRE> +</DIV> +<P> There are ways to make this operator appear as part of the class + using the <TT>%extend</TT> directive. Keep reading.</P> +<P> Also, be aware that certain operators don't map cleanly to Lua, and + some Lua operators don't map cleanly to C++ operators. For instance, + overloaded assignment operators don't map to Lua semantics and will be + ignored, and C++ doesn't support Lua's concatenation operator (<TT>..</TT> +).</P> +<P> In order to keep maximum compatibility within the different + languages in SWIG, the Lua bindings uses the same set of operator names + as python. Although internally it renames the functions to something + else (on order to work with Lua).</P> +<P> The current list of operators which can be overloaded (and the + alternative function names) are:</P> +<UL> +<LI><TT>__add__</TT> operator+</LI> +<LI><TT>__sub__</TT> operator-</LI> +<LI><TT>__mul__</TT> operator *</LI> +<LI><TT>__div__</TT> operator/</LI> +<LI><TT>__neg__</TT> unary minus</LI> +<LI><TT>__call__</TT> operator<TT>()</TT> (often used in functor + classes)</LI> +<LI><TT>__pow__</TT> the exponential fn (no C++ equivalent, Lua uses <TT> +^</TT>)</LI> +<LI><TT>__concat__</TT> the concatenation operator (SWIG maps C++'s <TT> +~</TT> to Lua's <TT>..</TT>)</LI> +<LI><TT>__eq__</TT> operator<TT>==</TT></LI> +<LI><TT>__lt__</TT> operator<TT><</TT></LI> +<LI><TT>__le__</TT> operator<TT><=</TT></LI> +</UL> +<P> Note: in Lua, only the equals, less than, and less than equals + operators are defined. The other operators (!=,>,>=) are achieved by + using a logical not applied to the results of other operators.</P> +<P> The following operators cannot be overloaded (mainly because they + are not supported in Lua)</P> +<UL> +<LI>++ and --</LI> +<LI>+=,-=,*= etc</LI> +<LI>% operator (you have to use math.mod)</LI> +<LI>assignment operator</LI> +<LI>all bitwise/logical operations</LI> +</UL> +<P> SWIG also accepts the <TT>__str__()</TT> member function which + converts an object to a string. This function should return a const + char*, preferably to static memory. This will be used for the <TT> +print()</TT> and <TT>tostring()</TT> functions in Lua. Assuming the + complex class has a function</P> +<DIV class="code"> +<PRE>const char* __str__() +{ + static char buffer[255]; + sprintf(buffer,"Complex(%g,%g)",this->re(),this->im()); + return buffer; +} +</PRE> +</DIV> +<P> Then this will support the following code in Lua</P> +<DIV class="targetlang"> +<PRE> +> c = Complex(3,4) +> d = Complex(7,8) +> e = c + d +> print(e) +Complex(10,12) +> s=tostring(e) -- s is the number in string form +> print(s) +Complex(10,12) +</PRE> +</DIV> +<P> It is also possible to overload the operator<TT>[]</TT>, but + currently this cannot be automatically performed. To overload the + operator<TT>[]</TT> you need to provide two functions, <TT> +__getitem__()</TT> and <TT>__setitem__()</TT></P> +<DIV class="code"> +<PRE>class Complex +{ + //.... + double __getitem__(int i)const; // i is the index, returns the data + void __setitem__(int i,double d); // i is the index, d is the data +}; +</PRE> +</DIV> +<H3><A name="Lua_nn19"></A>23.3.12 Class extension with %extend</H3> +<P> One of the more interesting features of SWIG is that it can extend + structures and classes with new methods. In the previous section, the + Complex class would have benefited greatly from an __str__() method as + well as some repairs to the operator overloading. It can also be used + to add additional functions to the class if they are needed.</P> +<P> Take the original Complex class</P> +<DIV class="code"> +<PRE>class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c); + Complex operator+(const Complex &c) const; + Complex operator-(const Complex &c) const; + Complex operator*(const Complex &c) const; + Complex operator-() const; + + double re() const { return rpart; } + double im() const { return ipart; } +}; +</PRE> +</DIV> +<P> Now we extend it with some new code</P> +<DIV class="code"> +<PRE>%extend Complex { + const char *__str__() { + static char tmp[1024]; + sprintf(tmp,"Complex(%g,%g)", $self->re(),$self->im()); + return tmp; + } + bool operator==(const Complex& c) + { return ($self->re()==c.re() && $self->im()==c.im();} +}; +</PRE> +</DIV> +<P> Now, in Lua</P> +<DIV class="targetlang"> +<PRE> +> c = Complex(3,4) +> d = Complex(7,8) +> e = c + d +> print(e) -- print uses __str__ to get the string form to print +Complex(10,12) +> print(e==Complex(10,12)) -- testing the == operator +true +> print(e!=Complex(12,12)) -- the != uses the == operator +true +</PRE> +</DIV> +<P> Extend works with both C and C++ code, on classes and structs. It + does not modify the underlying object in any way---the extensions only + show up in the Lua interface. The only item to take note of is the code + has to use the '$self' instead of 'this', and that you cannot access + protected/private members of the code (as you are not officially part + of the class).</P> +<H3><A name="Lua_nn20"></A>23.3.13 C++ templates</H3> +<P> C++ templates don't present a huge problem for SWIG. However, in + order to create wrappers, you have to tell SWIG to create wrappers for + a particular template instantiation. To do this, you use the template + directive. For example:</P> +<DIV class="code"> +<PRE>%module example +%{ +#include "pair.h" +%} + +template<class T1, class T2> +struct pair { + typedef T1 first_type; + typedef T2 second_type; + T1 first; + T2 second; + pair(); + pair(const T1&, const T2&); + ~pair(); +}; + +%template(pairii) pair<int,int>; +</PRE> +</DIV> +<P> In Lua:</P> +<DIV class="targetlang"> +<PRE> +> p = example.pairii(3,4) +> print(p.first,p.second) +3 4 +</PRE> +</DIV> +<P> Obviously, there is more to template wrapping than shown in this + example. More details can be found in the SWIG and C++ chapter. Some + more complicated examples will appear later.</P> +<H3><A name="Lua_nn21"></A>23.3.14 C++ Smart Pointers</H3> +<P> In certain C++ programs, it is common to use classes that have been + wrapped by so-called "smart pointers." Generally, this involves the use + of a template class that implements operator->() like this:</P> +<DIV class="code"> +<PRE>template<class T> class SmartPtr { + ... + T *operator->(); + ... +} +</PRE> +</DIV> +<P> Then, if you have a class like this,</P> +<DIV class="code"> +<PRE>class Foo { +public: + int x; + int bar(); +}; +</PRE> +</DIV> +<P> A smart pointer would be used in C++ as follows:</P> +<DIV class="code"> +<PRE>SmartPtr<Foo> p = CreateFoo(); // Created somehow (not shown) +... +p->x = 3; // Foo::x +int y = p->bar(); // Foo::bar +</PRE> +</DIV> +<P> To wrap this, simply tell SWIG about the SmartPtr class and the + low-level Foo object. Make sure you instantiate SmartPtr using template + if necessary. For example:</P> +<DIV class="code"> +<PRE>%module example +... +%template(SmartPtrFoo) SmartPtr<Foo>; +... +</PRE> +</DIV> +<P> Now, in Lua, everything should just "work":</P> +<DIV class="targetlang"> +<PRE> +> p = example.CreateFoo() -- Create a smart-pointer somehow +> p.x = 3 -- Foo::x +> print(p:bar()) -- Foo::bar +</PRE> +</DIV> +<P> If you ever need to access the underlying pointer returned by <TT> +operator->()</TT> itself, simply use the <TT>__deref__()</TT> method. + For example:</P> +<DIV class="targetlang"> +<PRE> +> f = p:__deref__() -- Returns underlying Foo * +</PRE> +</DIV> +<H3><A name="Lua_nn22"></A>23.3.15 C++ Exceptions</H3> +<P> Lua does not natively support exceptions, but it has errors which + are similar. When a Lua function terminates with an error it returns + one value back to the caller. SWIG automatically maps any basic type + which is thrown into a Lua error. Therefore for a function:</P> +<DIV class="code"> +<PRE> +int message() throw(const char *) { + throw("I died."); + return 1; +} +</PRE> +</DIV> +<P> SWIG will automatically convert this to a Lua error.</P> +<DIV class="targetlang"> +<PRE> +> message() +I died. +stack traceback: + [C]: in function 'message' + stdin:1: in main chunk + [C]: ? +> +</PRE> +</DIV> +<P> If you want to catch an exception, you must use either pcall() or + xpcall(), which are documented in the Lua manual. Using xpcall will + allow you to obtain additional debug information (such as a + stacktrace).</P> +<DIV class="targetlang"> +<PRE> +> function a() b() end -- function a() calls function b() +> function b() message() end -- function b() calls C++ function message(), which throws +> ok,res=pcall(a) -- call the function +> print(ok,res) +false I died. +> ok,res=xpcall(a,debug.traceback) -- call the function +> print(ok,res) +false I died. +stack traceback: + [C]: in function 'message' + runme.lua:70: in function 'b' + runme.lua:67: in function <runme.lua:66> + [C]: in function 'xpcall' + runme.lua:95: in main chunk + [C]: ? +</PRE> +</DIV> +<P> SWIG is able to throw numeric types, enums, chars, char*'s and + std::string's without problem. It has also written typemaps for + std::exception and its derived classes, which convert the exception + into and error string.</P> +<P> However its not so simple for to throw other types of objects. + Thrown objects are not valid outside the 'catch' block. Therefore they + cannot be returned to the interpreter. The obvious ways to overcome + this would be to either return a copy of the object, or so convert the + object to a string and return that. Though it seems obvious to perform + the former, in some cases this is not possible, most notably when SWIG + has no information about the object, or the object is not + copyable/creatable.</P> +<P> Therefore by default SWIG converts all thrown object into strings + and returns them. So given a function:</P> +<DIV class="code"> +<PRE> +void throw_A() throw(A*) { + throw new A(); +} +</PRE> +</DIV> +<P> SWIG will just convert it (poorly) to a string and use that as its + error. (Yes its not that useful, but it always works).</P> +<DIV class="targetlang"> +<PRE> +> throw_A() +object exception:A * +stack traceback: + [C]: in function 'unknown' + stdin:1: in main chunk + [C]: ? +> +</PRE> +</DIV> +<P> To get a more useful behaviour out of SWIG you must either: provide + a way to convert your exceptions into strings, or throw objects which + can be copied.</P> +<P> If you have your own class which you want output as a string you + will need to add a typemap something like this:</P> +<DIV class="code"> +<PRE> +%typemap(throws) my_except +%{ + lua_pushstring(L,$1.what()); // assuming my_except::what() returns a const char* message + SWIG_fail; // trigger the error handler +%} +</PRE> +</DIV> +<P> If you wish your exception to be returned to the interpreter, it + must firstly be copyable. Then you must have and additional <TT>%apply</TT> + statement, to inform SWIG to return a copy of this object to the + interpreter. For example:</P> +<DIV class="code"> +<PRE> +%apply SWIGTYPE EXCEPTION_BY_VAL {Exc}; // tell SWIG to return Exc by value to interpreter + +class Exc { +public: + Exc(int c, const char *m) { + code = c; + strncpy(msg,m,256); + } + int code; + char msg[256]; +}; + +void throw_exc() throw(Exc) { + throw(Exc(42,"Hosed")); +} +</PRE> +</DIV> +<P> Then the following code can be used (note: we use pcall to catch the + error so we can process the exception).</P> +<DIV class="targetlang"> +<PRE> +> ok,res=pcall(throw_exc) +> print(ok) +false +> print(res) +userdata: 0003D880 +> print(res.code,res.msg) +42 Hosed +> +</PRE> +</DIV> +<P> Note: is is also possible (though tedious) to have a function throw + several different kinds of exceptions. To process this will require a + pcall, followed by a set of if statements checking the type of the + error.</P> +<P> All of this code assumes that your C++ code uses exception + specification (which a lot doesn't). If it doesn't consult the "<A href="#SWIGPlus_catches"> +Exception handling with %catches</A>" section and the "<A href="#exception"> +Exception handling with %exception</A>" section, for more details on how + to add exception specification to functions or globally (respectively).</P> +<H2><A name="Lua_nn23"></A>23.4 Typemaps</H2> +<P>This section explains what typemaps are and the usage of them. The + default wrappering behaviour of SWIG is enough in most cases. However + sometimes SWIG may need a little additional assistance to know which + typemap to apply to provide the best wrappering. This section will be + explaining how to use typemaps to best effect</P> +<H3><A name="Lua_nn24"></A>23.4.1 What is a typemap?</H3> +<P>A typemap is nothing more than a code generation rule that is + attached to a specific C datatype. For example, to convert integers + from Lua to C, you might define a typemap like this:</P> +<DIV class="code"> +<PRE>%module example + +%typemap(in) int { + $1 = (int) lua_tonumber(L,$input); + printf("Received an integer : %d\n",$1); +} +%inline %{ +extern int fact(int n); +%} +</PRE> +</DIV> +<P><I>Note: you shouldn't use this typemap, as SWIG already has a + typemap for this task. This is purely for example.</I></P> +<P>Typemaps are always associated with some specific aspect of code + generation. In this case, the "in" method refers to the conversion of + input arguments to C/C++. The datatype int is the datatype to which the + typemap will be applied. The supplied C code is used to convert values. + In this code a number of special variable prefaced by a $ are used. The + $1 variable is placeholder for a local variable of type int. The $input + is the index on the Lua stack for the value to be used.</P> +<P>When this example is compiled into a Lua module, it operates as + follows:</P> +<DIV class="targetlang"> +<PRE>> require "example" +> print(example.fact(6)) +Received an integer : 6 +720 +</PRE> +</DIV> +<H3><A name="Lua_nn25"></A>23.4.2 Using typemaps</H3> +<P>There are many ready written typemaps built into SWIG for all common + types (int, float, short, long, char*, enum and more), which SWIG uses + automatically, with no effort required on your part.</P> +<P>However for more complex functions which use input/output parameters + or arrays, you will need to make use of <typemaps.i>, which contains + typemaps for these situations. For example, consider these functions:</P> +<DIV class="code"> +<PRE>void add(int x, int y, int *result) { + *result = x + y; +} + +int sub(int *x1, int *y1) { + return *x1-*y1; +} + +void swap(int *sx, int *sy) { + int t=*sx; + *sx=*sy; + *sy=t; +} +</PRE> +</DIV> +<P>It is clear to the programmer, that 'result' is an output parameter, + 'x1' and 'y1' are input parameters and 'sx' and 'sy' are input/output + parameters. However is not apparent to SWIG, so SWIG must to informed + about which kind they are, so it can wrapper accordingly.</P> +<P>One means would be to rename the argument name to help SWIG, eg <TT> +void add(int x, int y, int *OUTPUT)</TT>, however it is easier to use + the <TT>%apply</TT> to achieve the same result, as shown below.</P> +<DIV class="code"> +<PRE>%include <typemaps.i> +%apply int* OUTPUT {int *result}; // int *result is output +%apply int* INPUT {int *x1, int *y1}; // int *x1 and int *y1 are input +%apply int* INOUT {int *sx, int *sy}; // int *sx and int *sy are input and output + +void add(int x, int y, int *result); +int sub(int *x1, int *y1); +void swap(int *sx, int *sy); +</PRE> +</DIV> +<P>When wrapped, it gives the following results:</P> +<DIV class="targetlang"> +<PRE>> require "example" +> print(example.add(1,2)) +3 +> print(demo.sub(1,2)) +-1 +> a,b=1,2 +> c,d=demo.swap(a,b) +> print(a,b,c,d) +1 2 2 1 +</PRE> +</DIV> +<P>Notice, that 'result' is not required in the arguments to call the + function, as it an output parameter only. For 'sx' and 'sy' they must + be passed in (as they are input), but the original value is not + modified (Lua does not have a pass by reference feature). The modified + results are then returned as two return values. All INPUT/OUTPUT/INOUT + arguments will behave in a similar manner.</P> +<P>Note: C++ references must be handled exactly the same way. However + SWIG will automatically wrap a <TT>const int&</TT> as an input + parameter (since that it obviously input).</P> +<H3><A name="Lua_nn26"></A>23.4.3 Typemaps and arrays</H3> +<P>Arrays present a challenge for SWIG, because like pointers SWIG does + not know whether these are input or output values, nor does SWIG have + any indication of how large an array should be. However with the proper + guidance SWIG can easily wrapper arrays for convenient usage.</P> +<P>Given the functions:</P> +<DIV class="code"> +<PRE>extern void sort_int(int* arr, int len); +extern void sort_double(double* arr, int len); +</PRE> +</DIV> +<P>There are basically two ways that SWIG can deal with this. The first + way, uses the <TT><carrays.i></TT> library to create an array in C/C++ + then this can be filled within Lua and passed into the function. It + works, but its a bit tedious. More details can be found in the <A href="Library.html#Library_nn5"> +carrays.i</A> documention.</P> +<P>The second and more intuitive way, would be to pass a Lua table + directly into the function, and have SWIG automatically convert between + Lua-table and C-array. Within the <TT><typemaps.i></TT> file there are + typemaps ready written to perform this task. To use them is again a + matter of using %appy in the correct manner.</P> +<P>The wrapper file below, shows both the use of carrays as well as the + use of the typemap to wrap arrays.</P> +<DIV class="code"> +<PRE>// using the C-array +%include <carrays.i> +// this declares a batch of function for manipulating C integer arrays +%array_functions(int,int) + +extern void sort_int(int* arr, int len); // the function to wrap + +// using typemaps +%include <typemaps.i> +%apply (double *INOUT,int) {(double* arr,int len)}; + +extern void sort_double(double* arr, int len); // the function to wrap +</PRE> +</DIV> +<P>Once wrappered, the functions can both be called, though with + different ease of use:</P> +<DIV class="targetlang"> +<PRE>require "example" +ARRAY_SIZE=10 + +-- passing a C array to the sort_int() +arr=example.new_int(ARRAY_SIZE) -- create the array +for i=0,ARRAY_SIZE-1 do -- index 0..9 (just like C) + example.int_setitem(arr,i,math.random(1000)) +end +example.sort_int(arr,ARRAY_SIZE) -- call the function +example.delete_int(arr) -- must delete the allocated memory + +-- use a typemap to call with a Lua-table +-- one item of note: the typemap creates a copy, rather than edit-in-place +t={} -- a Lua table +for i=1,ARRAY_SIZE do -- index 1..10 (Lua style) + t[i]=math.random(1000)/10 +end +t=example.sort_double(t) -- replace t with the result +</PRE> +</DIV> +<P>Obviously the first version could be made less tedious by writing a + Lua function to perform the conversion from a table to a C-array. The <TT> +%luacode</TT> directive is good for this. See SWIG\Examples\lua\arrays + for an example of this.</P> +<P><B>Warning:</B> in C indexes start at ZERO, in Lua indexes start at + ONE. SWIG expects C-arrays to be filled for 0..N-1 and Lua tables to be + 1..N, (the indexing follows the norm for the language). In the typemap + when it converts the table to an array it quietly changes the indexing + accordingly. Take note of this behaviour if you have a C function which + returns indexes.</P> +<P>Note: SWIG also can support arrays of pointers in a similar manner.</P> +<H3><A name="Lua_nn27"></A>23.4.4 Typemaps and pointer-pointer functions</H3> +<P>Several C++ libraries use a pointer-pointer functions to create its + objects. These functions require a pointer to a pointer which is then + filled with the pointer to the new object. Microsoft's COM and DirectX + as well as many other libraries have this kind of function. An example + is given below:</P> +<DIV class="code"> +<PRE>struct iMath; // some structure +int Create_Math(iMath** pptr); // its creator (assume it mallocs) +</PRE> +</DIV> +<P>Which would be used with the following C code:</P> +<DIV class="code"> +<PRE>iMath* ptr; +int ok; +ok=Create_Math(&ptr); +// do things with ptr +//... +free(ptr); // dispose of iMath +</PRE> +</DIV> +<P>SWIG has a ready written typemap to deal with such a kind of function + in <typemaps.i>. It provides the correct wrappering as well as setting + the flag to inform Lua that the object in question should be garbage + collected. Therefore the code is simply:</P> +<DIV class="code"> +<PRE>%include <typemaps.i> +%apply SWIGTYPE** OUTPUT{iMath **pptr }; // tell SWIG its an output + +struct iMath; // some structure +int Create_Math(iMath** pptr); // its creator (assume it mallocs) +</PRE> +</DIV> +<P>The usage is as follows:</P> +<DIV class="targetlang"> +<PRE>ok,ptr=Create_Math() -- ptr is a iMath* which is returned with the int (ok) +ptr=nil -- the iMath* will be GC'ed as normal +</PRE> +</DIV> +<H2><A name="Lua_nn28"></A>23.5 Writing typemaps</H2> +<P>This section describes how you can modify SWIG's default wrapping + behavior for various C/C++ datatypes using the <TT>%typemap</TT> + directive. This is an advanced topic that assumes familiarity with the + Lua C API as well as the material in the "<A href="#Typemaps">Typemaps</A> +" chapter.</P> +<P>Before proceeding, it should be stressed that writing typemaps is + rarely needed unless you want to change some aspect of the wrappering, + or to achieve an effect which in not available with the default + bindings.</P> +<P>Before proceeding, you should read the previous section on using + typemaps, as well as read the ready written typemaps found in + luatypemaps.swg and typemaps.i. These are both well documented and + fairly easy to read. You should not attempt to write your own typemaps + until you have read and can understand both of these files (they may + well also give you a idea to base your worn on).</P> +<H3><A name="Lua_nn29"></A>23.5.1 Typemaps you can write</H3> +<P>There are many different types of typemap that can be written, the + full list can be found in the "<A href="#Typemaps">Typemaps</A>" + chapter. However the following are the most commonly used ones.</P> +<UL> +<LI><TT>in</TT> this is for input arguments to functions</LI> +<LI><TT>out</TT> this is for return types from functions</LI> +<LI><TT>argout</TT> this is for a function argument which is actually + returning something</LI> +<LI><TT>typecheck</TT> this is used to determine which overloaded + function should be called (the syntax for the typecheck is different + from the typemap, see typemaps for details).</LI> +</UL> +<H3><A name="Lua_nn30"></A>23.5.2 SWIG's Lua-C API</H3> +<P>This section explains the SWIG specific Lua-C API. It does not cover + the main Lua-C api, as this is well documented and not worth covering.</P> +<P><TT>int SWIG_ConvertPtr(lua_State* L,int index,void** + ptr,swig_type_info *type,int flags);</TT></P> +<DIV class="indent"> This is the standard function used for converting a + Lua userdata to a void*. It takes the value at the given index in the + Lua state and converts it to a userdata. It will then provide the + neccesary type checks, confirming that the pointer is compatible with + the type given in 'type'. Then finally setting '*ptr' to the pointer. + If flags is set to SWIG_POINTER_DISOWN, this is will clear any + ownership flag set on the object. +<BR> The returns a value which can be checked with the macro SWIG_IsOK()</DIV> +<P><TT>void SWIG_NewPointerObj(lua_State* L,void* ptr,swig_type_info + *type,int own);</TT></P> +<DIV class="indent"> This is the opposite of SWIG_ConvertPtr, as it + pushes a new userdata which wrappers the pointer 'ptr' of type 'type'. + The parameter 'own' specifies if the object is owned be Lua and if it + is 1 then Lua will GC the object when the userdata is disposed of.</DIV> +<P><TT>void* SWIG_MustGetPtr(lua_State* L,int index,swig_type_info + *type,int flags,int argnum,const char* func_name);</TT></P> +<DIV class="indent"> This function is a version of SWIG_ConvertPtr(), + except that it will either work, or it will trigger a lua_error() with + a text error message. This function is rarely used, and may be + deprecated in the future.</DIV> +<P><TT>SWIG_fail</TT></P> +<DIV class="indent"> This macro, when called within the context of a + SWIG wrappered function, will jump to the error handler code. This will + call any cleanup code (freeing any temp variables) and then triggers a + lua_error. +<BR> A common use for this code is: +<BR> +<PRE> +if (!SWIG_IsOK(SWIG_ConvertPtr( .....)){ + lua_pushstring(L,"something bad happened"); + SWIG_fail; +}</PRE> +</DIV> +<P><TT>SWIG_fail_arg(char* func_name,int argnum,char* type)</TT></P> +<DIV class="indent"> This macro, when called within the context of a + SWIG wrappered function, will display the error message and jump to the + error handler code. The error message is of the form +<PRE> +"Error in <I>func_name</I> (arg <I>argnum</I>), expected '<I>type</I>' got '<I>whatever the type was</I>'" +</PRE> +</DIV> +<P><TT>SWIG_fail_ptr(const char* fn_name,int argnum,swig_type_info* + type);</TT></P> +<DIV class="indent"> Similar to SWIG_fail_arg, except that it will + display the swig_type_info information instead.</DIV> +<H2><A name="Lua_nn31"></A>23.6 Customization of your Bindings</H2> +<P> This section covers adding of some small extra bits to your module + to add the last finishing touches.</P> +<H3><A name="Lua_nn32"></A>23.6.1 Writing your own custom wrappers</H3> +<P> Sometimes, it may be neccesary to add your own special functions, + which bypass the normal SWIG wrappering method, and just use the native + Lua API calls. These 'native' functions allow direct adding of your own + code into the module. This is performed with the <TT>%native</TT> + directive as follows:</P> +<DIV class="code"> +<PRE>%native(my_func) int native_function(lua_State*L); // registers native_function() with SWIG +... +%{ +int native_function(lua_State*L) // my native code +{ + ... +} +%} +</PRE> +</DIV> +<P> The <TT>%native</TT> directive in the above example, tells SWIG that + there is a function <TT>int native_function(lua_State*L);</TT> which is + to be added into the module under the name '<TT>my_func</TT>'. SWIG + will not add any wrappering for this function, beyond adding it into + the function table. How you write your code is entirely up to you.</P> +<H3><A name="Lua_nn33"></A>23.6.2 Adding additional Lua code</H3> +<P> As well as adding additional C/C++ code, its also possible to add + your own Lua code to the module as well. This code is executed once all + other initialisation, including the %init code has been called.</P> +<P> The directive <TT>%luacode</TT> adds code into the module which is + executed upon loading. Normally you would use this to add your own + functions to the module. Though you could easily perform other tasks.</P> +<DIV class="code"> +<PRE>%module example; + +%luacode { + function example.greet() + print "hello world" + end + + print "Module loaded ok" +} +... +%} +</PRE> +</DIV> +<P> Notice that the code is not part of the module table. Therefore any + references to the module must have the module name added.</P> +<P> Should there be an error in the Lua code, this will<EM> not</EM> + stop loading of the module. The default behaviour of SWIG is to print a + error message to stderr and then continue. It is possible to change + this behaviour by using a <TT>#define SWIG_DOSTRING_FAIL(STR)</TT> to + define a different behaviour should the code fail.</P> +<P> Good uses for this feature is adding of new code, or writing helper + functions to simplify some of the code. See Examples/lua/arrays for an + example of this code.</P> +<H2><A name="Lua_nn34"></A>23.7 Details on the Lua binding</H2> +<P> In the previous section, a high-level view of Lua wrapping was + presented. Obviously a lot of stuff happens behind the scenes to make + this happen. This section will explain some of the low-level details on + how this is achieved.</P> +<P><I> If you just want to use SWIG and don't care how it works, then + stop reading here. This is going into the guts of the code and how it + works. Its mainly for people who need to know whats going on within the + code.</I></P> +<H3><A name="Lua_nn35"></A>23.7.1 Binding global data into the module.</H3> +<P> Assuming that you had some global data that you wanted to share + between C and Lua. How does SWIG do it?</P> +<DIV class="code"> +<PRE>%module example; +extern double Foo; +</PRE> +</DIV> +<P> SWIG will effectively generate the pair of functions</P> +<DIV class="code"> +<PRE>void Foo_set(double); +double Foo_get(); +</PRE> +</DIV> +<P> At initialisation time, it will then add to the interpreter a table + called 'example', which represents the module. It will then add all its + functions to the module. (Note: older versions of SWIG actually added + the Foo_set() and Foo_get() functions, current implementation does not + add these functions any more.) But it also adds a metatable to this + table, which has two functions (<TT>__index</TT> and <TT>__newindex</TT> +) as well as two tables (<TT>.get</TT> and <TT>.set</TT>) The following + Lua code will show these hidden features.</P> +<DIV class="targetlang"> +<PRE> +> print(example) +table: 003F8F90 +> m=getmetatable(example) +> table.foreach(m,print) +.set table: 003F9088 +.get table: 003F9038 +__index function: 003F8FE0 +__newindex function: 003F8FF8 +> g=m['.get'] +> table.foreach(g,print) +Foo function: 003FAFD8 +> +</PRE> +</DIV> +<P> The .get and .set tables are lookups connecting the variable name + 'Foo' to the accessor/mutator functions (Foo_set,Foo_get)</P> +<P> The Lua equivalent of the code for the <TT>__index</TT> and <TT> +__newindex</TT> looks a bit like this</P> +<DIV class="targetlang"> +<PRE> +function __index(mod,name) + local g=getmetatable(mod)['.get'] -- gets the table + if not g then return nil end + local f=g[name] -- looks for the function + -- calls it & returns the value + if type(f)=="function" then return f() end + return nil +end + +function __newindex(mod,name,value) + local s=getmetatable(mod)['.set'] -- gets the table + if not s then return end + local f=s[name] -- looks for the function + -- calls it to set the value + if type(f)=="function" then f(value) + else rawset(mod,name,value) end +end +</PRE> +</DIV> +<P> That way when you call '<TT>a=example.Foo</TT>', the interpreter + looks at the table 'example' sees that there is no field 'Foo' and + calls __index. This will in turn check in '.get' table and find the + existence of 'Foo' and then return the value of the C function call + 'Foo_get()'. Similarly for the code '<TT>example.Foo=10</TT>', the + interpreter will check the table, then call the __newindex which will + then check the '.set' table and call the C function 'Foo_set(10)'.</P> +<H3><A name="Lua_nn36"></A>23.7.2 Userdata and Metatables</H3> +<P> As mentioned earlier, classes and structures, are all held as + pointer, using the Lua 'userdata' structure. This structure is actually + a pointer to a C structure 'swig_lua_userdata', which contains the + pointer to the data, a pointer to the swig_type_info (an internal SWIG + struct) and a flag which marks if the object is to be disposed of when + the interpreter no longer needs it. The actual accessing of the object + is done via the metatable attached to this userdata.</P> +<P> The metatable is a Lua 5.0 feature (which is also why SWIG cannot + wrap Lua 4.0). Its a table which holds a list of functions, operators + and attributes. This is what gives the userdata the feeling that it is + a real object and not just a hunk of memory.</P> +<P> Given a class</P> +<DIV class="code"> +<PRE>%module excpp; + +class Point +{ +public: + int x,y; + Point(){x=y=0;} + ~Point(){} + virtual void Print(){printf("Point @%p (%d,%d)\n",this,x,y);} +}; +</PRE> +</DIV> +<P> SWIG will create a module excpp, with all the various function + inside. However to allow the intuitive use of the userdata is also + creates up a set of metatables. As seen in the above section on global + variables, use of the metatables allows for wrappers to be used + intuitively. To save effort, the code creates one metatable per class + and stores it inside Lua's registry. Then when an new object is + instantiated, the metatable is found in the registry and the userdata + associated to the metatable. Currently derived classes make a complete + copy of the base classes table and then add on their own additional + function.</P> +<P> Some of the internals can be seen by looking at a classes metatable.</P> +<DIV class="targetlang"> +<PRE> +> p=excpp.Point() +> print(p) +userdata: 003FDB28 +> m=getmetatable(p) +> table.foreach(m,print) +.type Point +__gc function: 003FB6C8 +__newindex function: 003FB6B0 +__index function: 003FB698 +.get table: 003FB4D8 +.set table: 003FB500 +.fn table: 003FB528 +</PRE> +</DIV> +<P> The '.type' attribute is the name of the class. The '.get' and + '.set' tables work in a similar manner to the modules, the main + difference is the '.fn' table which also holds all the member + functions. (The '__gc' function is the classes destructor function)</P> +<P> The Lua equivalent of the code for enabling functions looks a little + like this</P> +<DIV class="targetlang"> +<PRE> +function __index(obj,name) + local m=getmetatable(obj) -- gets the metatable + if not m then return nil end + local g=m['.get'] -- gets the attribute table + if not g then return nil end + local f=g[name] -- looks for the get_attribute function + -- calls it & returns the value + if type(f)=="function" then return f() end + -- ok, so it not an attribute, maybe its a function + local fn=m['.fn'] -- gets the function table + if not fn then return nil end + local f=fn[name] -- looks for the function + -- if found the fn then return the function + -- so the interpreter can call it + if type(f)=="function" then return f end + return nil +end +</PRE> +</DIV> +<P> So when 'p:Print()' is called, the __index looks on the object + metatable for a 'Print' attribute, then looks for a 'Print' function. + When it finds the function, it returns the function, and then + interpreter can call 'Point_Print(p)'</P> +<P> In theory, you can play with this usertable & add new features, but + remember that it is a shared table between all instances of one class, + and you could very easily corrupt the functions in all the instances.</P> +<P> Note: Both the opaque structures (like the FILE*) and normal + wrappered classes/structs use the same 'swig_lua_userdata' structure. + Though the opaque structures has do not have a metatable attached, or + any information on how to dispose of them when the interpreter has + finished with them.</P> +<P> Note: Operator overloads are basically done in the same way, by + adding functions such as '__add' & '__call' to the classes metatable. + The current implementation is a bit rough as it will add any member + function beginning with '__' into the metatable too, assuming its an + operator overload.</P> +<H3><A name="Lua_nn37"></A>23.7.3 Memory management</H3> +<P> Lua is very helpful with the memory management. The + 'swig_lua_userdata' is fully managed by the interpreter itself. This + means that neither the C code nor the Lua code can damage it. Once a + piece of userdata has no references to it, it is not instantly + collected, but will be collected when Lua deems is necessary. (You can + force collection by calling the Lua function <TT>collectgarbage()</TT> +). Once the userdata is about to be free'ed, the interpreter will check + the userdata for a metatable and for a function '__gc'. If this exists + this is called. For all complete types (ie normal wrappered classes & + structs) this should exist. The '__gc' function will check the + 'swig_lua_userdata' to check for the 'own' field and if this is true + (which is will be for all owned data's) it will then call the + destructor on the pointer.</P> +<P> It is currently not recommended to edit this field or add some user + code, to change the behaviour. Though for those who wish to try, here + is where to look.</P> +<P> It is also currently not possible to change the ownership flag on + the data (unlike most other scripting languages, Lua does not permit + access to the data from within the interpreter)</P> +<HR NOSHADE> +<H1><A name="Modula3"></A>24 SWIG and Modula-3</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#modula3_overview">Overview</A> +<UL> +<LI><A href="#whyscripting">Why not scripting ?</A></LI> +<LI><A href="#whymodula3">Why Modula-3 ?</A></LI> +<LI><A href="#whycpp">Why C / C++ ?</A></LI> +<LI><A href="#whyswig">Why SWIG ?</A></LI> +</UL> +</LI> +<LI><A href="#conception">Conception</A> +<UL> +<LI><A href="#cinterface">Interfaces to C libraries</A></LI> +<LI><A href="#cppinterface">Interfaces to C++ libraries</A></LI> +</UL> +</LI> +<LI><A href="#preliminaries">Preliminaries</A> +<UL> +<LI><A href="#compilers">Compilers</A></LI> +<LI><A href="#commandline">Additional Commandline Options</A></LI> +</UL> +</LI> +<LI><A href="#modula3_typemaps">Modula-3 typemaps</A> +<UL> +<LI><A href="#inoutparam">Inputs and outputs</A></LI> +<LI><A href="#ordinals">Subranges, Enumerations, Sets</A></LI> +<LI><A href="#class">Objects</A></LI> +<LI><A href="#imports">Imports</A></LI> +<LI><A href="#exceptions">Exceptions</A></LI> +<LI><A href="#typemap_example">Example</A></LI> +</UL> +</LI> +<LI><A href="#hints">More hints to the generator</A> +<UL> +<LI><A href="#features">Features</A></LI> +<LI><A href="#pragmas">Pragmas</A></LI> +</UL> +</LI> +<LI><A href="#remarks">Remarks</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes SWIG's support of <A href="http://www.m3.org/"> +Modula-3</A>. You should be familiar with the <A href="#SWIG">basics</A> + of SWIG, especially <A href="Typemaps.html">typemaps</A>.</P> +<H2><A name="modula3_overview"></A>24.1 Overview</H2> +<P> The Modula-3 support is very basic and highly experimental! Many + features are still not designed satisfyingly and I need more discussion + about the odds and ends. Don't rely on any feature, incompatible + changes are likely in the future! The Modula-3 generator was already + useful for interfacing to the libraries</P> +<OL> +<LI> <A href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/"> + PLPlot</A></LI> +<LI> <A href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/"> + FFTW</A> .</LI> +</OL> +<P> I took some more time to explain why I think it's right what I'm + doing. So the introduction got a bit longer than it should ... ;-)</P> +<H3><A name="whyscripting"></A>24.1.1 Why not scripting ?</H3> +<P> SWIG started as wrapper from the fast compiled languages C and C++ + to high level scripting languages like Python. Although scripting + languages are designed to make programming life easier by hiding + machine internals from the programmer there are several aspects of + today's scripting languages that are unfavourable in my opinion.</P> +<P> Besides C, C++, Cluster (a Modula derivate for Amiga computers) I + evaluated several scripting like languages in the past: Different + dialects of BASIC, Perl, ARexx (a variant of Rexx for Amiga computers), + shell scripts. I found them too inconsistent, too weak in + distinguishing types, too weak in encapsulating pieces of code. + Eventually I have started several projects in Python because of the + fine syntax. But when projects became larger I lost the track. I got + convinced that one can not have maintainable code in a language that is + not statically typed. In fact the main advantages of scripting + languages e.g. matching regular expressions, complex built-in datatypes + like lists, dictionaries, are not advantages of the language itself but + can be provided by function libraries.</P> +<H3><A name="whymodula3"></A>24.1.2 Why Modula-3 ?</H3> +<P> Modula-3 is a compiler language in the tradition of Niklaus Wirth's + Modula 2, which is in turn a successor of the popular Pascal. I have + chosen Modula-3 because of its logical syntax, strong modularization, + the type system which is very detailed for machine types compared to + other languages. Of course it supports all of the modern games like + exceptions, objects, garbage collection, threads. While C++ programmers + must control three languages, namely the preprocessor, C and ++, + Modula-3 is made in one go and the language definition is really + compact.</P> +<P> On the one hand Modula-3 can be safe (but probably less efficient) + in normal modules while providing much static and dynamic safety. On + the other hand you can write efficient but less safe code in the style + of C within <TT>UNSAFE</TT> modules.</P> +<P> Unfortunately Modula's safety and strength requires more writing + than scripting languages do. Today if I want to safe characters I + prefer Haskell (similar to OCAML) - it's statically typed, too.</P> +<H3><A name="whycpp"></A>24.1.3 Why C / C++ ?</H3> +<P> Although it is no problem to write Modula-3 programs that performs + as fast as C most libraries are not written in Modula-3 but in C. + Fortunately the binary interface of most function libraries can be + addressed by Modula-3. Even more fortunately even non-C libraries may + provide C header files. This is where SWIG becomes helpful.</P> +<H3><A name="whyswig"></A>24.1.4 Why SWIG ?</H3> +<P> The C headers and the possibility to interface to C libraries still + leaves the work for you to write Modula-3 interfaces to them. To make + things comfortable you will also need wrappers that convert between + high-level features of Modula-3 (garbage collecting, exceptions) and + the low level of the C libraries.</P> +<P> SWIG converts C headers to Modula-3 interfaces for you. You could + call the C functions without loss of efficiency but it won't be joy + because you could not pass <TT>TEXT</TT>s or open arrays and you would + have to process error return codes rather then exceptions. But using + some typemaps SWIG will also generate wrappers that bring the whole + Modula-3 comfort to you. If the library API is ill designed writing + appropriate typemaps can be still time-consuming. E.g. C programmers + are very creative to work-around missing data types like (real) + enumerations and sets. You should turn such work-arounds back to the + Modula-3 way otherwise you lose static safety and consistency.</P> +<P> But you have still a problem: C library interfaces are often ill. + They lack for certain information because C compilers wouldn't care + about. You should integrate detailed type information by adding <TT> +typedef</TT>s and <TT>const</TT>s and you should persuade the C library + programmer to add this information to his interface. Only this way + other language users can benefit from your work and only this way you + can easily update your interfaces when a new library version is + released. You will realise that writing<B> good</B> SWIG interfaces is + very costly and it will only amortise when considering evolving + libraries.</P> +<P> Without SWIG you would probably never consider to call C++ libraries + from Modula-3. But with SWIG this is worth a consideration. SWIG can + write C wrappers to C++ functions and object methods that may throw + exceptions. In fact it breaks down C++ libraries to C interfaces which + can be in turn called from Modula-3. To make it complete you can hide + the C interface with Modula-3 classes and exceptions.</P> +<P> Although SWIG does the best it can do it can only serve as a one-way + strategy. That means you can use C++ libraries with Modula-3 (even with + call back functions), but it's certainly not possible to smoothly + integrate Modula-3 code into a C / C++ project.</P> +<H2><A name="conception"></A>24.2 Conception</H2> +<H3><A name="cinterface"></A>24.2.1 Interfaces to C libraries</H3> +<P> Modula-3 has an integrated support for calling C functions. This is + also extensively used by the standard Modula-3 libraries to call OS + functions. The Modula-3 part of SWIG and the corresponding SWIG library + <A href="../../Lib/modula3/modula3.swg"><TT>modula3.swg</TT></A> + contain code that uses these features. Because of the built-in support + there is no need for calling the SWIG kernel to generate wrappers + written in C. All conversion and argument checking can be done in + Modula-3 and the interfacing is quite efficient. All you have to do is + to write pieces of Modula-3 code that SWIG puts together.</P> +<TABLE border summary="Modula-3 C library support"> +<TR><TH colspan="2">C library support integrated in Modula-3</TH><TH></TH> +</TR> +<TR><TD>Pragma <TT><* EXTERNAL *></TT></TD><TD>Precedes a declaration of + a PROCEDURE that is implemented in an external library instead of a + Modula-3 module.</TD></TR> +<TR><TD>Pragma <TT><* CALLBACK *></TT></TD><TD>Precedes a declaration of + a PROCEDURE that should be called by external library code.</TD></TR> +<TR><TD>Module <TT>Ctypes</TT></TD><TD>Contains Modula-3 types that + match some basic C types.</TD></TR> +<TR><TD>Module <TT>M3toC</TT></TD><TD>Contains routines that convert + between Modula-3's <TT>TEXT</TT> type and C's <TT>char *</TT> type.</TD> +</TR> +</TABLE> +<P> In each run of SWIG the Modula-3 part generates several files:</P> +<TABLE border summary="Modula-3 generated files"> +<TR><TH>Module name scheme</TH><TH>Identifier for <TT>%insert</TT></TH><TH> +Description</TH></TR> +<TR><TD>Module<TT>Raw.i3</TT></TD><TD><TT>m3rawintf</TT></TD><TD> +Declaration of types that are equivalent to those of the C library, <TT> +EXTERNAL</TT> procedures as interface to the C library functions</TD></TR> +<TR><TD>Module<TT>Raw.m3</TT></TD><TD><TT>m3rawimpl</TT></TD><TD>Almost + empty.</TD></TR> +<TR><TD>Module<TT>.i3</TT></TD><TD><TT>m3wrapintf</TT></TD><TD> +Declaration of comfortable wrappers to the C library functions.</TD></TR> +<TR><TD>Module<TT>.m3</TT></TD><TD><TT>m3wrapimpl</TT></TD><TD> +Implementation of the wrappers that convert between Modula-3 and C + types, check for validity of values, hand-over resource management to + the garbage collector using <TT>WeakRef</TT>s and raises exceptions.</TD> +</TR> +<TR><TD><TT>m3makefile</TT></TD><TD><TT>m3makefile</TT></TD><TD>Add the + modules above to the Modula-3 project and specify the name of the + Modula-3 wrapper library to be generated. Today I'm not sure if it is a + good idea to create a <TT>m3makefile</TT> in each run, because SWIG + must be started for each Modula-3 module it creates. Thus the + m3makefile is overwritten each time. :-(</TD></TR> +</TABLE> +<P> Here's a scheme of how the function calls to Modula-3 wrappers are + redirected to C library functions:</P> +<TABLE summary="Modula-3 C library"> +<TR><TD align="center"> Modula-3 wrapper +<BR> Module<TT>.i3</TT> +<BR> generated by Modula-3 part of SWIG</TD><TD></TD><TD align="center"></TD> +</TR> +<TR><TD align="center"> +<!-- pre tag overrides centering --> + | +<BR> v</TD><TD></TD><TD align="center"></TD></TR> +<TR><TD align="center"> Modula-3 interface to C +<BR> Module<TT>Raw.i3</TT> +<BR> generated by Modula-3 part of SWIG</TD><TD>--></TD><TD align="center"> + C library</TD></TR> +</TABLE> +<P> I have still no good conception how one can split C library + interfaces into type oriented interfaces. A Module in Modula-3 + represents an Abstract DataType (or call it a static classes, i.e. a + class without virtual methods). E.g. if you have a principal type, say <TT> +Database</TT>, it is good Modula-3 style to set up one Module with the + name <TT>Database</TT> where the database type is declared with the + name <TT>T</TT> and where all functions are declared that operates on + it.</P> +<P> The normal operation of SWIG is to generate a fixed set of files per + call. To generate multiple modules one has to write one SWIG interface + (different SWIG interfaces can share common data) per module. + Identifiers belonging to a different module may ignored (<TT>%ignore</TT> +) and the principal type must be renamed (<TT>%typemap</TT>).</P> +<H3><A name="cppinterface"></A>24.2.2 Interfaces to C++ libraries</H3> +<P> Interfaces to C++ files are much more complicated and there are some + more design decisions that are not made, yet. Modula-3 has no support + for C++ functions but C++ compilers should support generating C++ + functions with a C interface.</P> +<P> Here's a scheme of how the function calls to Modula-3 wrappers a + redirected to C library functions:</P> +<TABLE summary="Modula-3 C++ library"> +<TR><TD align="center"> Modula-3 wrapper +<BR> Module<TT>.i3</TT> +<BR> generated by Modula-3 part of SWIG</TD><TD></TD><TD align="center"> +C++ library</TD></TR> +<TR><TD align="center"> +<!-- pre tag overrides centering --> + | +<BR> v</TD><TD></TD><TD align="center"> ^ +<BR> |</TD></TR> +<TR><TD align="center"> Modula-3 interface to C +<BR> Module<TT>Raw.i3</TT> +<BR> generated by Modula-3 part of SWIG</TD><TD>--></TD><TD align="center"> + C interface to C++ +<BR> module<TT>_wrap.cxx</TT> +<BR> generated by the SWIG core</TD></TR> +</TABLE> +<P> Wrapping C++ libraries arises additional problems:</P> +<UL> +<LI> Is it sensible to wrap C++ classes with Modula-3 classes?</LI> +<LI> How to find the wrapping Modula-3 class for a class pointer that is + returned by a C++ routine?</LI> +<LI> How to deal with multiple inheritance which was neglected for + Modula-3 for good reasons?</LI> +<LI> Is it possible to sub-class C++ classes with Modula-3 code? This + issue is addressed by directors, a feature that was experimentally + added to some Language modules like <A href="#java_directors">Java</A> + and <A href="Python.html#directors">Python</A>.</LI> +<LI> How to manage storage with the garbage collector of Modula-3? + Support for <A href="#ownership"> <TT>%newobject</TT> and <TT> +%typemap(newfree)</TT></A> isn't implemented, yet. What's about + resources that are managed by the garbage collector but shall be passed + back to the storage management of the C++ library? This is a general + issue which is not solved in a satisfying fashion as far as I know.</LI> +<LI> How to turn C++ exceptions into Modula-3 exceptions? There's also + no support for <A href="#exception"> <TT>%exception</TT></A>, yet.</LI> +</UL> +<P> Be warned: There is no C++ library I wrote a SWIG interface for, so + I'm not sure if this is possible or sensible, yet.</P> +<H2><A name="preliminaries"></A>24.3 Preliminaries</H2> +<H3><A name="compilers"></A>24.3.1 Compilers</H3> +<P> There are different Modula-3 compilers around: cm3, pm3, ezm3, + Klagenfurth Modula-3, Cambridge Modula-3. SWIG itself does not contain + compiler specific code but the library file <A href="../../Lib/modula3/modula3.swg"> +<TT>modula3.swg</TT></A> may do so. For testing examples I use Critical + Mass cm3.</P> +<H3><A name="commandline"></A>24.3.2 Additional Commandline Options</H3> +<P> There are some experimental command line options that prevent SWIG + from generating interface files. Instead files are emitted that may + assist you when writing SWIG interface files.</P> +<TABLE border summary="Modula-3 specific options"> +<TR><TH>Modula-3 specific options</TH><TH>Description</TH></TR> +<TR><TD valign="top">-generateconst <file></TD><TD> Disable generation + of interfaces and wrappers. Instead write code for computing numeric + values of constants to the specified file. +<BR> C code may contain several constant definitions written as + preprocessor macros. Other language modules of SWIG use + compute-once-use-readonly variables or functions to wrap such + definitions. All of them can invoke C code dynamically for computing + the macro values. But if one wants to turn them into Modula-3 integer + constants, enumerations or set types, the values of these expressions + has to be known statically. Although definitions like <TT>(1 << + FLAG_MAXIMIZEWINDOW)</TT> must be considered as good C style they are + hard to convert to Modula-3 since the value computation can use every + feature of C. +<BR> Thus I implemented these switch to extract all constant definitions + and write a C program that output the values of them. It works for + numeric constants only and treats all of them as <TT>double</TT>. + Future versions may generate a C++ program that can detect the type of + the macros by overloaded output functions. Then strings can also be + processed.</TD></TR> +<TR><TD valign="top">-generaterename <file></TD><TD> Disable generation + of interfaces and wrappers. Instead generate suggestions for <TT> +%rename</TT>. +<BR> C libraries use a naming style that is neither homogeneous nor + similar to that of Modula-3. C function names often contain a prefix + denoting the library and some name components separated by underscores + or capitalization changes. To get library interfaces that are really + Modula-3 like you should rename the function names with the <TT>%rename</TT> + directive. This switch outputs a list of such directives with a name + suggestion generated by a simple heuristic.</TD></TR> +<TR><TD valign="top">-generatetypemap <file></TD><TD> Disable generation + of interfaces and wrappers. Instead generate templates for some basic + typemaps.</TD></TR> +</TABLE> +<H2><A name="modula3_typemaps"></A>24.4 Modula-3 typemaps</H2> +<H3><A name="inoutparam"></A>24.4.1 Inputs and outputs</H3> +<P> Each C procedure has a bunch of inputs and outputs. Inputs are + passed as function arguments, outputs are updated referential arguments + and the function value.</P> +<P> Each C type can have several typemaps that apply only in case if a + type is used for an input argument, for an output argument, or for a + return value. A further typemap may specify the direction that is used + for certain parameters. I have chosen this separation in order to be + able to write general typemaps for the typemap library <A href="../../Lib/modula3/modula3.swg"> +<TT>modula3.swg</TT></A> . In the library code the final usage of the + type is not known. Using separate typemaps for each possible use allows + appropriate definitions for each case. If these pre-definitions are + fine then the direction of the function parameter is the only hint the + user must give.</P> +<P> The typemaps specific to Modula-3 have a common name scheme: A + typemap name starts with "m3", followed by "raw" or "wrap" depending on + whether it controls the generation of the Module<TT>Raw.i3</TT> or the + Module<TT>.i3</TT>, respectively. It follows an "in" for typemaps + applied to input argument, "out" for output arguments, "arg" for all + kind of arguments, "ret" for returned values.</P> +<P> The main task of SWIG is to build wrapper function, i.e. functions + that convert values between C and Modula-3 and call the corresponding C + function. Modula-3 wrapper functions generated by SWIG consist of the + following parts:</P> +<UL> +<LI>Generate <TT>PROCEDURE</TT> signature.</LI> +<LI>Declare local variables.</LI> +<LI>Convert input values from Modula-3 to C.</LI> +<LI>Check for input value integrity.</LI> +<LI>Call the C function.</LI> +<LI>Check returned values, e.g. error codes.</LI> +<LI>Convert and write back values into Modula-3 records.</LI> +<LI>Free temporary storage.</LI> +<LI>Return values.</LI> +</UL> +<TABLE border summary="Modula-3 typemaps"> +<TR><TH>Typemap</TH><TH>Example</TH><TH>Description</TH></TR> +<TR><TD>m3wrapargvar</TD><TD><TT>$1: INTEGER := $1_name;</TT></TD><TD> + Declaration of some variables needed for temporary results.</TD></TR> +<TR><TD>m3wrapargconst</TD><TD><TT>$1 = "$1_name";</TT></TD><TD> + Declaration of some constant, maybe for debug purposes.</TD></TR> +<TR><TD>m3wrapargraw</TD><TD><TT>ORD($1_name)</TT></TD><TD> The + expression that should be passed as argument to the raw Modula-3 + interface function.</TD></TR> +<TR><TD>m3wrapargdir</TD><TD><TT>out</TT></TD><TD> Referential arguments + can be used for input, output, update. ???</TD></TR> +<TR><TD>m3wrapinmode</TD><TD><TT>READONLY</TT></TD><TD> One of Modula-3 + parameter modes <TT>VALUE</TT> (or empty), <TT>VAR</TT>, <TT>READONLY</TT> +</TD></TR> +<TR><TD>m3wrapinname</TD><TD></TD><TD> New name of the input argument.</TD> +</TR> +<TR><TD>m3wrapintype</TD><TD></TD><TD> Modula-3 type of the input + argument.</TD></TR> +<TR><TD>m3wrapindefault</TD><TD></TD><TD> Default value of the input + argument</TD></TR> +<TR><TD>m3wrapinconv</TD><TD><TT>$1 := M3toC.SharedTtoS($1_name);</TT></TD><TD> + Statement for converting the Modula-3 input value to C compliant value.</TD> +</TR> +<TR><TD>m3wrapincheck</TD><TD><TT>IF Text.Length($1_name) > 10 THEN + RAISE E("str too long"); END;</TT></TD><TD> Check the integrity of the + input value.</TD></TR> +<TR><TD>m3wrapoutname</TD><TD></TD><TD> Name of the <TT>RECORD</TT> + field to be used for returning multiple values. This applies to + referential output arguments that shall be turned into return values.</TD> +</TR> +<TR><TD>m3wrapouttype</TD><TD></TD><TD> Type of the value that is + returned instead of a referential output argument.</TD></TR> +<TR><TD>m3wrapoutconv</TD><TD></TD><TD></TD></TR> +<TR><TD>m3wrapoutcheck</TD><TD></TD><TD></TD></TR> +<TR><TD>m3wrapretraw</TD><TD></TD><TD></TD></TR> +<TR><TD>m3wrapretname</TD><TD></TD><TD></TD></TR> +<TR><TD>m3wraprettype</TD><TD></TD><TD></TD></TR> +<TR><TD>m3wrapretvar</TD><TD></TD><TD></TD></TR> +<TR><TD>m3wrapretconv</TD><TD></TD><TD></TD></TR> +<TR><TD>m3wrapretcheck</TD><TD></TD><TD></TD></TR> +<TR><TD>m3wrapfreearg</TD><TD><TT>M3toC.FreeSharedS(str,arg1);</TT></TD><TD> + Free resources that were temporarily used in the wrapper. Since this + step should never be skipped, SWIG will put it in the <TT>FINALLY</TT> + branch of a <TT>TRY .. FINALLY</TT> structure.</TD></TR> +</TABLE> +<H3><A name="ordinals"></A>24.4.2 Subranges, Enumerations, Sets</H3> +<P> Subranges, enumerations, and sets are machine oriented types that + make Modula very strong and expressive compared with the type systems + of many other languages.</P> +<UL> +<LI> Subranges are used for statically restricted choices of integers.</LI> +<LI> Enumerations are used for named choices.</LI> +<LI> Sets are commonly used for flag (option) sets.</LI> +</UL> +<P> Using them extensively makes Modula code very safe and readable.</P> +<P> C supports enumerations, too, but they are not as safe as the ones + of Modula. Thus they are abused for many things: For named choices, for + integer constant definitions, for sets. To make it complete every way + of defining a value in C (<TT>#define</TT>, <TT>const int</TT>, <TT> +enum</TT>) is somewhere used for defining something that must be handled + completely different in Modula-3 (<TT>INTEGER</TT>, enumeration, <TT> +SET</TT>).</P> +<P> I played around with several <TT>%feature</TT>s and <TT>%pragma</TT> +s that split the task up into converting the C bit patterns (integer or + bit set) into Modula-3 bit patterns (integer or bit set) and change the + type as requested. See the corresponding example in the + Examples/modula3/enum/example.i file. This is quite messy and not + satisfying. So the best what you can currently do is to rewrite + constant definitions manually. Though this is a tedious work that I'd + like to automate.</P> +<H3><A name="class"></A>24.4.3 Objects</H3> +<P> Declarations of C++ classes are mapped to <TT>OBJECT</TT> types + while it is tried to retain the access hierarchy "public - protected - + private" using partial revelation. Though the example in + Examples/modula3/class/example.i is not really useful, yet.</P> +<H3><A name="imports"></A>24.4.4 Imports</H3> +<P> Pieces of Modula-3 code provided by typemaps may contain identifiers + from foreign modules. If the typemap <TT>m3wrapinconv</TT> for <TT>blah + *</TT> contains code using the function <TT>M3toC.SharedTtoS</TT> you + may declare <TT>%typemap("m3wrapinconv:import") blah * %{M3toC%}</TT>. + Then the module <TT>M3toC</TT> is imported if the <TT>m3wrapinconv</TT> + typemap for <TT>blah *</TT> is used at least once. Use <TT> +%typemap("m3wrapinconv:import") blah * %{MyConversions AS M3toC%}</TT> + if you need module renaming. Unqualified import is not supported.</P> +<P> It is cumbersome to add this typemap to each piece of Modula-3 code. + It is especially useful when writing general typemaps for the typemap + library <A href="../../Lib/modula3/modula3.swg"><TT>modula3.swg</TT></A> + . For a monolithic module you might be better off if you add the + imports directly:</P> +<DIV class="code"> +<PRE> +%insert(m3rawintf) %{ +IMPORT M3toC; +%} +</PRE> +</DIV> +<H3><A name="exceptions"></A>24.4.5 Exceptions</H3> +<P> Modula-3 provides another possibility of an output of a function: + exceptions.</P> +<P> Any piece of Modula-3 code that SWIG inserts due to a typemap can + raise an exception. This way you can also convert an error code from a + C function into a Modula-3 exception.</P> +<P> The <TT>RAISES</TT> clause is controlled by typemaps with the <TT> +throws</TT> extension. If the typemap <TT>m3wrapinconv</TT> for <TT>blah + *</TT> contains code that may raise the exceptions <TT>OSError.E</TT> + you should declare <TT>%typemap("m3wrapinconv:throws") blah * + %{OSError.E%}</TT>.</P> +<H3><A name="typemap_example"></A>24.4.6 Example</H3> +<P> The generation of wrappers in Modula-3 needs very fine control to + take advantage of the language features. Here is an example of a + generated wrapper where almost everything is generated by a typemap:</P> +<DIV class="code"> +<PRE> +<I> (* %relabel m3wrapinmode m3wrapinname m3wrapintype m3wrapindefault *)</I> + PROCEDURE Name (READONLY str : TEXT := "" ) +<I> (* m3wrapoutcheck:throws *)</I> + : NameResult RAISES {E} = + CONST + arg1name = "str"; <I>(* m3wrapargconst *)</I> + VAR + arg0 : C.char_star; <I>(* m3wrapretvar *)</I> + arg1 : C.char_star; <I>(* m3wrapargvar *)</I> + arg2 : C.int; + result : RECORD +<I> (*m3wrapretname m3wraprettype*)</I> + unixPath : TEXT; +<I> (*m3wrapoutname m3wrapouttype*)</I> + checksum : CARDINAL; + END; + BEGIN + TRY + arg1 := M3toC.SharedTtoS(str); <I>(* m3wrapinconv *)</I> + IF Text.Length(arg1) > 10 THEN <I>(* m3wrapincheck *)</I> + RAISE E("str too long"); + END; +<I> (* m3wrapretraw m3wrapargraw *)</I> + arg0 := MessyToUnix (arg1, arg2); + result.unixPath := M3toC.CopyStoT(arg0); <I>(* m3wrapretconv *)</I> + result.checksum := arg2; <I>(* m3wrapoutconv *)</I> + IF result.checksum = 0 THEN <I>(* m3wrapoutcheck *)</I> + RAISE E("invalid checksum"); + END; + FINALLY + M3toC.FreeSharedS(str,arg1); <I>(* m3wrapfreearg *)</I> + END; + END Name; +</PRE> +</DIV> +<H2><A name="hints"></A>24.5 More hints to the generator</H2> +<H3><A name="features"></A>24.5.1 Features</H3> +<TABLE border summary="Modula-3 features"> +<TR><TH>Feature</TH><TH>Example</TH><TH>Description</TH></TR> +<TR><TD>multiretval</TD><TD><TT>%m3multiretval get_box;</TT> or <TT> +%feature("modula3:multiretval") get_box;</TT></TD><TD>Let the denoted + function return a <TT>RECORD</TT> rather than a plain value. This <TT> +RECORD</TT> contains all arguments with "out" direction including the + return value of the C function (if there is one). If more than one + argument is "out" then the function<B> must</B> have the <TT> +multiretval</TT> feature activated, but it is explicitly requested from + the user to prevent mistakes.</TD></TR> +<TR><TD>constnumeric</TD><TD><TT>%constnumeric(12) twelve;</TT> or <TT> +%feature("constnumeric","12") twelve;</TT></TD><TD>This feature can be + used to tell Modula-3's back-end of SWIG the value of an identifier. + This is necessary in the cases where it was defined by a non-trivial C + expression. This feature is used by the <TT>-generateconst</TT> <A href="#options"> +option</A>. In future it may be generalized to other kind of values such + as strings.</TD></TR> +</TABLE> +<H3><A name="pragmas"></A>24.5.2 Pragmas</H3> +<TABLE border summary="Modula-3 pragmas"> +<TR><TH>Pragma</TH><TH>Example</TH><TH>Description</TH></TR> +<TR><TD>unsafe</TD><TD><TT>%pragma(modula3) unsafe="true";</TT></TD><TD> +Mark the raw interface modules as <TT>UNSAFE</TT>. This will be + necessary in many cases.</TD></TR> +<TR><TD>library</TD><TD><TT>%pragma(modula3) library="m3fftw";</TT></TD><TD> +Specifies the library name for the wrapper library to be created. It + should be distinct from the name of the library to be wrapped.</TD></TR> +</TABLE> +<H2><A name="remarks"></A>24.6 Remarks</H2> +<UL> +<LI> The Modula-3 part of SWIG doesn't try to generate nicely formatted + code. Use <TT>m3pp</TT> to postprocess the Modula files, it does a very + good job here.</LI> +</UL> +<HR NOSHADE> + +<!-- Hand-written HTML --> +<H1><A name="MzScheme"></A>25 SWIG and MzScheme</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#MzScheme_nn2">Creating native MzScheme structures</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This section contains information on SWIG's support of MzScheme.</P> +<H2><A name="MzScheme_nn2"></A>25.1 Creating native MzScheme structures</H2> +<P> Example interface file:</P> +<DIV class="code"> +<PRE> +/* define a macro for the struct creation */ +%define handle_ptr(TYPE,NAME) +%typemap(argout) TYPE *NAME{ + Scheme_Object *o = SWIG_NewStructFromPtr($1, $*1_mangle); + SWIG_APPEND_VALUE(o); +} + +%typemap(in,numinputs=0) TYPE *NAME (TYPE temp) { + $1 = &temp; +} +%enddef + +/* setup the typemaps for the pointer to an output parameter cntrs */ +handle_ptr(struct diag_cntrs, cntrs); +</PRE> +</DIV> +<P> Then in scheme, you can use regular struct access procedures like</P> +<DIV class="code"> +<PRE> + ; suppose a function created a struct foo as + ; (define foo (make-diag-cntrs (#x1 #x2 #x3) (make-inspector)) + ; Then you can do + (format "0x~x" (diag-cntrs-field1 foo)) + (format "0x~x" (diag-cntrs-field2 foo)) + ;etc... +</PRE> +</DIV> +<P> That's pretty much it. It works with nested structs as well.</P> +<HR NOSHADE> + <A name="n1"></A> +<H1><A name="Ocaml"></A>26 SWIG and Ocaml</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Ocaml_nn2">Preliminaries</A> +<UL> +<LI><A href="#Ocaml_nn3">Running SWIG</A></LI> +<LI><A href="#Ocaml_nn4">Compiling the code</A></LI> +<LI><A href="#Ocaml_nn5">The camlp4 module</A></LI> +<LI><A href="#Ocaml_nn6">Using your module</A></LI> +<LI><A href="#Ocaml_nn7">Compilation problems and compiling with C++</A></LI> +</UL> +</LI> +<LI><A href="#Ocaml_nn8">The low-level Ocaml/C interface</A> +<UL> +<LI><A href="#Ocaml_nn9">The generated module</A></LI> +<LI><A href="#Ocaml_nn10">Enums</A> +<UL> +<LI><A href="#Ocaml_nn11">Enum typing in Ocaml</A></LI> +</UL> +</LI> +<LI><A href="#Ocaml_nn12">Arrays</A> +<UL> +<LI><A href="#Ocaml_nn13">Simple types of bounded arrays</A></LI> +<LI><A href="#Ocaml_nn14">Complex and unbounded arrays</A></LI> +<LI><A href="#Ocaml_nn15">Using an object</A></LI> +<LI><A href="#Ocaml_nn16">Example typemap for a function taking float * + and int</A></LI> +</UL> +</LI> +<LI><A href="#Ocaml_nn17">C++ Classes</A> +<UL> +<LI><A href="#Ocaml_nn18">STL vector and string Example</A></LI> +<LI><A href="#Ocaml_nn19">C++ Class Example</A></LI> +<LI><A href="#Ocaml_nn20">Compiling the example</A></LI> +<LI><A href="#Ocaml_nn21">Sample Session</A></LI> +</UL> +</LI> +<LI><A href="#Ocaml_nn22">Director Classes</A> +<UL> +<LI><A href="#Ocaml_nn23">Director Introduction</A></LI> +<LI><A href="#Ocaml_nn24">Overriding Methods in Ocaml</A></LI> +<LI><A href="#Ocaml_nn25">Director Usage Example</A></LI> +<LI><A href="#Ocaml_nn26">Creating director objects</A></LI> +<LI><A href="#Ocaml_nn27">Typemaps for directors, <TT>directorin, + directorout, directorargout</TT></A></LI> +<LI><A href="#Ocaml_nn28"><TT>directorin</TT> typemap</A></LI> +<LI><A href="#Ocaml_nn29"><TT>directorout</TT> typemap</A></LI> +<LI><A href="#Ocaml_nn30"><TT>directorargout</TT> typemap</A></LI> +</UL> +</LI> +<LI><A href="#Ocaml_nn31">Exceptions</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes SWIG's support of Ocaml. Ocaml is a + relatively recent addition to the ML family, and is a recent addition + to SWIG. It's the second compiled, typed language to be added. Ocaml + has widely acknowledged benefits for engineers, mostly derived from a + sophisticated type system, compile-time checking which eliminates + several classes of common programming errors, and good native + performance. While all of this is wonderful, there are well-written C + and C++ libraries that Ocaml users will want to take advantage of as + part of their arsenal (such as SSL and gdbm), as well as their own + mature C and C++ code. SWIG allows this code to be used in a natural, + type-safe way with Ocaml, by providing the necessary, but repetitive + glue code which creates and uses Ocaml values to communicate with C and + C++ code. In addition, SWIG also produces the needed Ocaml source that + binds variants, functions, classes, etc.</P> +<P> If you're not familiar with the Objective Caml language, you can + visit <A href="http://www.ocaml.org/">The Ocaml Website</A>.</P> +<H2><A name="Ocaml_nn2"></A>26.1 Preliminaries</H2> +<P> SWIG 1.3 works with Ocaml 3.04 and above. Given the choice, you + should use the latest stable release. The SWIG Ocaml module has been + tested on Linux (x86,PPC,Sparc) and Cygwin on Windows. The best way to + determine whether your system will work is to compile the examples and + test-suite which come with SWIG. You can do this by running <TT>make + check</TT> from the SWIG root directory after installing SWIG. The + Ocaml module has been tested using the system's dynamic linking (the + usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's <A href="http://www.ocaml-programming.de/packages/documentation/dl/"> +Dl package</A> . The ocaml_dynamic and ocaml_dynamic_cpp targets in the + file Examples/Makefile illustrate how to compile and link SWIG modules + that will be loaded dynamically. This has only been tested on Linux so + far.</P> +<H3><A name="Ocaml_nn3"></A>26.1.1 Running SWIG</H3> +<P> The basics of getting a SWIG Ocaml module up and running can be seen + from one of SWIG's example Makefiles, but is also described here. To + build an Ocaml module, run SWIG using the <TT>-ocaml</TT> option.</P> +<DIV class="code"> +<PRE> +%swig -ocaml example.i + </PRE> +</DIV> +<P> This will produce 3 files. The file <TT>example_wrap.c</TT> contains + all of the C code needed to build an Ocaml module. To build the module, + you will compile the file <TT>example_wrap.c</TT> with <TT>ocamlc</TT> + or <TT>ocamlopt</TT> to create the needed .o file. You will need to + compile the resulting .ml and .mli files as well, and do the final link + with -custom (not needed for native link).</P> +<H3><A name="Ocaml_nn4"></A>26.1.2 Compiling the code</H3> +<P> The O'Caml SWIG module now requires you to compile a module (<TT> +Swig</TT>) separately. In addition to aggregating common SWIG + functionality, the Swig module contains the data structure that + represents C/C++ values. This allows easier data sharing between + modules if two or more are combined, because the type of each SWIG'ed + module's c_obj is derived from Swig.c_obj_t. This also allows SWIG to + acquire new conversions painlessly, as well as giving the user more + freedom with respect to custom typing. Use <TT>ocamlc</TT> or <TT> +ocamlopt</TT> to compile your SWIG interface like:</P> +<DIV class="code"> +<PRE> +% swig -ocaml -co swig.mli ; swig -ocaml co swig.ml +% ocamlc -c swig.mli ; ocamlc -c swig.ml +% ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c +% ocamlc -c example.mli +% ocamlc -c example.ml + </PRE> +</DIV> +<P> <TT>ocamlc</TT> is aware of .c files and knows how to handle them. + Unfortunately, it does not know about .cxx, .cc, or .cpp files, so when + SWIG is invoked in C++ mode, you must:</P> +<DIV class="code"> +<PRE> +% cp example_wrap.cxx example_wrap.cxx.c +<BR>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c +<BR>% ... +<BR> + </PRE> +</DIV> +<H3><A name="Ocaml_nn5"></A>26.1.3 The camlp4 module</H3> +<P> The camlp4 module (swigp4.ml -> swigp4.cmo) contains a simple + rewriter which makes C++ code blend more seamlessly with objective caml + code. It's use is optional, but encouraged. The source file is included + in the Lib/ocaml directory of the SWIG source distribution. You can + checkout this file with <TT>"swig -ocaml -co swigp4.ml"</TT>. You + should compile the file with <TT>"ocamlc -I `camlp4 -where` -pp + 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"</TT></P> +<P> The basic principle of the module is to recognize certain non-caml + expressions and convert them for use with C++ code as interfaced by + SWIG. The camlp4 module is written to work with generated SWIG + interfaces, and probably isn't great to use with anything else.</P> +<P> Here are the main rewriting rules:</P> +<TABLE border="1" summary="Rewriting rules"> +<TR><TH>Input</TH><TH>Rewritten to</TH></TR> +<TR><TD>f'( ... ) as in +<BR> atoi'("0") or +<BR> _exit'(0)</TD><TD>f(C_list [ ... ]) as in +<BR> atoi (C_list [ C_string "0" ]) or +<BR> _exit (C_list [ C_int 0 ])</TD></TR> +<TR><TD>object -> method ( ... )</TD><TD>(invoke object) "method" + (C_list [ ... ])</TD></TR> +<TR><TD> object<I> 'binop</I> argument as in +<BR> a '+= b</TD><TD> (invoke object) "+=" argument as in +<BR> (invoke a) "+=" b</TD><TD></TD></TR> +<TR><TH colspan="2">Note that because camlp4 always recognizes << and + >>, they are replaced by lsl and lsr in operator names.</TH></TR> +<TR><TD><I> 'unop</I> object as in +<BR> '! a</TD><TD> (invoke a) "!" C_void</TD></TR> +<TR><TD><B> Smart pointer access like this</B> +<BR> object '-> method ( args ) +<BR></TD><TD> (invoke (invoke object "->" C_void))</TD></TR> +<TR><TD><B> Invoke syntax</B> +<BR> object . '( ... )</TD><TD> (invoke object) "()" (C_list [ ... ])</TD> +</TR> +<TR><TD><B> Array syntax</B> +<BR> object '[ 10 ]</TD><TD> (invoke object) "[]" (C_int 10)</TD></TR> +<TR><TD><B> Assignment syntax</B> +<BR> let a = '10 and b = '"foo" and c = '1.0 and d = 'true</TD><TD> let + a = C_int 10 and b = C_string "foo" and c = C_double 1.0 and d = C_bool + true</TD></TR> +<TR><TD><B> Cast syntax</B> +<BR> let a = _atoi '("2") as int +<BR> let b = (getenv "PATH") to string +<BR> This works for int, string, float, bool</TD><TD> let a = get_int + (_atoi (C_string "2")) +<BR> let b = C_string (getenv "PATH")</TD></TR> +</TABLE> +<H3><A name="Ocaml_nn6"></A>26.1.4 Using your module</H3> +<P> You can test-drive your module by building a toplevel ocaml + interpreter. Consult the ocaml manual for details.</P> +<P> When linking any ocaml bytecode with your module, use the -custom + option to build your functions into the primitive list. This option is + not needed when you build native code.</P> +<H3><A name="Ocaml_nn7"></A>26.1.5 Compilation problems and compiling + with C++</H3> +<P> As mentioned above, .cxx files need special handling to be compiled + with <TT>ocamlc</TT>. Other than that, C code that uses <TT>class</TT> + as a non-keyword, and C code that is too liberal with pointer types may + not compile under the C++ compiler. Most code meant to be compiled as + C++ will not have problems.</P> +<H2><A name="Ocaml_nn8"></A>26.2 The low-level Ocaml/C interface</H2> +<P> In order to provide access to overloaded functions, and provide + sensible outputs from them, all C entities are represented as members + of the c_obj type:</P> +<P> In the code as seen by the typemap writer, there is a value, + swig_result, that always contains the current return data. It is a + list, and must be appended with the caml_list_append function, or with + functions and macros provided by objective caml. +<BR></P> +<DIV class="code"> +<PRE> +type c_obj = + C_void + | C_bool of bool + | C_char of char + | C_uchar of char + | C_short of int + | C_ushort of int + | C_int of int + | C_uint of int32 + | C_int32 of int32 + | C_int64 of int64 + | C_float of float + | C_double of float + | C_ptr of int64 * int64 + | C_array of c_obj array + | C_list of c_obj list + | C_obj of (string -> c_obj -> c_obj) + | C_string of string + | C_enum of c_enum_t +</PRE> +</DIV> +<P> A few functions exist which generate and return these:</P> +<UL> +<LI>caml_ptr_val receives a c_obj and returns a void *. This should be + used for all pointer purposes.</LI> +<LI>caml_long_val receives a c_obj and returns a long. This should be + used for most integral purposes. +<BR></LI> +<LI>caml_val_ptr receives a void * and returns a c_obj.</LI> +<LI>caml_val_bool receives a C int and returns a c_obj representing it's + bool value.</LI> +<LI>caml_val_(u)?(char|short|int|long|float|double) receives an + appropriate C value and returns a c_obj representing it.</LI> +<LI>caml_val_string receives a char * and returns a string value.</LI> +<LI>caml_val_string_len receives a char * and a length and returns a + string value.</LI> +<LI>caml_val_obj receives a void * and an object type and returns a + C_obj, which contains a closure giving method access.</LI> +</UL> +<P> Because of this style, a typemap can return any kind of value it + wants from a function. This enables out typemaps and inout typemaps to + work well. The one thing to remember about outputting values is that + you must append them to the return list with swig_result = + caml_list_append(swig_result,v).</P> +<P> This function will return a new list that has your element + appended. Upon return to caml space, the fnhelper function beautifies + the result. A list containing a single item degrades to only that item + (i.e. [ C_int 3 ] -> C_int 3), and a list containing more than one item + is wrapped in C_list (i.e. [ C_char 'a' ; C_char 'b' -> C_list [ C_char + 'a' ; C_char b ]). This is in order to make return values easier to + handle when functions have only one return value, such as constructors, + and operators. In addition, string, pointer, and object values are + interchangeable with respect to caml_ptr_val, so you can allocate + memory as caml strings and still use the resulting pointers for C + purposes, even using them to construct simple objects on. Note, though, + that foreign C++ code does not respect the garbage collector, although + the SWIG interface does.</P> +<P> The wild card type that you can use in lots of different ways is + C_obj. It allows you to wrap any type of thing you like as an object + using the same mechanism that the ocaml module does. When evaluated in + caml_ptr_val, the returned value is the result of a call to the + object's "&" operator, taken as a pointer.</P> +<P> You should only construct values using objective caml, or using the + functions caml_val_* functions provided as static functions to a SWIG + ocaml module, as well as the caml_list_* functions. These functions + provide everything a typemap needs to produce values. In addition, + value items pass through directly, but you must make your own type + signature for a function that uses value in this way.</P> +<H3><A name="Ocaml_nn9"></A>26.2.1 The generated module</H3> +<P> The SWIG <TT>%module</TT> directive specifies the name of the Ocaml + module to be generated. If you specified `<TT>%module example</TT>', + then your Ocaml code will be accessible in the module Example. The + module name is always capitalized as is the ocaml convention. Note that + you must not use any Ocaml keyword to name your module. Remember that + the keywords are not the same as the C++ ones.</P> +<P> You can introduce extra code into the output wherever you like with + SWIG. These are the places you can introduce code:</P> +<TABLE border="1" summary="Extra code sections"> +<TR><TD>"header"</TD><TD>This code is inserted near the beginning of the + C wrapper file, before any function definitions.</TD></TR> +<TR><TD>"wrapper"</TD><TD>This code is inserted in the function + definition section.</TD></TR> +<TR><TD>"runtime"</TD><TD>This code is inserted near the end of the C + wrapper file.</TD></TR> +<TR><TD>"mli"</TD><TD>This code is inserted into the caml interface + file. Special signatures should be inserted here.</TD></TR> +<TR><TD>"ml"</TD><TD>This code is inserted in the caml code defining the + interface to your C code. Special caml code, as well as any + initialization which should run when the module is loaded may be + inserted here.</TD></TR> +<TR><TD>"classtemplate"</TD><TD>The "classtemplate" place is special + because it describes the output SWIG will generate for class + definitions.</TD></TR> +</TABLE> +<H3><A name="Ocaml_nn10"></A>26.2.2 Enums</H3> +<P> SWIG will wrap enumerations as polymorphic variants in the output + Ocaml code, as above in C_enum. In order to support all C++-style uses + of enums, the function int_to_enum and enum_to_int are provided for + ocaml code to produce and consume these values as integers. Other than + that, correct uses of enums will not have a problem. Since enum labels + may overlap between enums, the enum_to_int and int_to_enum functions + take an enum type label as an argument. Example:</P> +<DIV class="code"> +<PRE> +%module enum_test +%{ +enum c_enum_type { a = 1, b, c = 4, d = 8 }; +%} +enum c_enum_type { a = 1, b, c = 4, d = 8 }; +</PRE> +</DIV> +<P> The output mli contains:</P> +<DIV class="code"> +<PRE> +type c_enum_type = [ + `unknown +| `c_enum_type +] +type c_enum_tag = [ + `int of int +| `a +| `b +| `c +| `d +] +val int_to_enum c_enum_type -> int -> c_obj +val enum_to_int c_enum_type -> c_obj -> c_obj +</PRE> +</DIV> +<P> So it's possible to do this:</P> +<DIV class="code"> +<PRE> +bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top +bash-2.05a$ ./enum_test_top + Objective Caml version 3.04 + +# open Enum_test ;; +# let x = C_enum `a ;; +val x : Enum_test.c_obj = C_enum `a +# enum_to_int `c_enum_type x ;; +- : Enum_test.c_obj = C_int 1 +# int_to_enum `c_enum_type 4 ;; +- : Enum_test.c_obj = C_enum `c +</PRE> +</DIV> +<H4><A name="Ocaml_nn11"></A>26.2.2.1 Enum typing in Ocaml</H4> +<P> The ocaml SWIG module now has support for loading and using multiple + SWIG modules at the same time. This enhances modularity, but presents + problems when used with a language which assumes that each module's + types are complete at compile time. In order to achieve total soundness + enum types are now isolated per-module. The type issue matters when + values are shared between functions imported from different modules. + You must convert values to master values using the swig_val function + before sharing them with another module.</P> +<H3><A name="Ocaml_nn12"></A>26.2.3 Arrays</H3> +<H4><A name="Ocaml_nn13"></A>26.2.3.1 Simple types of bounded arrays</H4> +<P> SWIG has support for array types, but you generally will need to + provide a typemap to handle them. You can currently roll your own, or + expand some of the macros provided (but not included by default) with + the SWIG distribution.</P> +<P> By including "carray.i", you will get access to some macros that + help you create typemaps for array types fairly easily.</P> +<P> <TT>%make_simple_array_typemap</TT> is the easiest way to get access + to arrays of simple types with known bounds in your code, but this only + works for arrays whose bounds are completely specified.</P> +<H4><A name="Ocaml_nn14"></A>26.2.3.2 Complex and unbounded arrays</H4> +<P> Unfortunately, unbounded arrays and pointers can't be handled in a + completely general way by SWIG, because the end-condition of such an + array can't be predicted. In some cases, it will be by consent (e.g. an + array of four or more chars), sometimes by explicit length (char + *buffer, int len), and sometimes by sentinel value (0,-1,etc.). SWIG + can't predict which of these methods will be used in the array, so you + have to specify it for yourself in the form of a typemap.</P> +<H4><A name="Ocaml_nn15"></A>26.2.3.3 Using an object</H4> +<P> It's possible to use C++ to your advantage by creating a simple + object that provides access to your array. This may be more desirable + in some cases, since the object can provide bounds checking, etc., that + prevents crashes.</P> +<P> Consider writing an object when the ending condition of your array + is complex, such as using a required sentinel, etc.</P> +<H4><A name="Ocaml_nn16"></A>26.2.3.4 Example typemap for a function + taking float * and int</H4> +<P> This is a simple example <TT>in</TT> typemap for an array of float, + where the length of the array is specified as an extra parameter. Other + such typemaps will work similarly. In the example, the function + printfloats is called with a float array, and specified length. The + actual length reported in the len argument is the length of the array + passed from ocaml, making passing an array into this type of function + convenient.</P> +<TABLE bgcolor="#dddddd" border="1" summary="float * and int typemap example"> +<TR><TH> +<CENTER>tarray.i</CENTER> +</TH></TR> +<TR><TD> +<PRE> +%module tarray +%{ +#include <stdio.h> + +void printfloats( float *tab, int len ) { + int i; + + for( i = 0; i < len; i++ ) { + printf( "%f ", tab[i] ); + } + + printf( "\n" ); +} +%} + +%typemap(in) (float *tab, int len) { + int i; + /* $*1_type */ + $2 = caml_array_len($input); + $1 = ($*1_type *)malloc( $2 * sizeof( float ) ); + for( i = 0; i < $2; i++ ) { + $1[i] = caml_double_val(caml_array_nth($input,i)); + } +} + +void printfloats( float *tab, int len ); +</PRE> +</TD></TR> +<TR><TH>Sample Run</TH></TR> +<TR><TD> +<PRE> +# open Tarray ;; +# _printfloats (C_array [| C_double 1.0 ; C_double 3.0 ; C_double 5.6666 |]) ;; +1.000000 3.000000 5.666600 +- : Tarray.c_obj = C_void +</PRE> +</TD></TR> +</TABLE> +<H3><A name="Ocaml_nn17"></A>26.2.4 C++ Classes</H3> +<P> C++ classes, along with structs and unions are represented by C_obj + (string -> c_obj -> c_obj) wrapped closures. These objects contain a + method list, and a type, which allow them to be used like C++ objects. + When passed into typemaps that use pointers, they degrade to pointers + through their "&" method. Every method an object has is represented as + a string in the object's method table, and each method table exists in + memory only once. In addition to any other operators an object might + have, certain builtin ones are provided by SWIG: (all of these take no + arguments (C_void))</P> +<TABLE summary="SWIG provided operators"> +<TR><TD>"~"</TD><TD>Delete this object</TD></TR> +<TR><TD>"&"</TD><TD>Return an ordinary C_ptr value representing this + object's address</TD></TR> +<TR><TD>"sizeof"</TD><TD>If enabled with ("sizeof"="1") on the module + node, return the object's size in char.</TD></TR> +<TR><TD>":methods"</TD><TD>Returns a list of strings containing the + names of the methods this object contains</TD></TR> +<TR><TD>":classof"</TD><TD>Returns the name of the class this object + belongs to.</TD></TR> +<TR><TD>":parents"</TD><TD>Returns a list of all direct parent classes + which have been wrapped by SWIG.</TD></TR> +<TR><TD>"::[parent-class]"</TD><TD>Returns a view of the object as the + indicated parent class. This is mainly used internally by the SWIG + module, but may be useful to client programs.</TD></TR> +<TR><TD>"[member-variable]"</TD><TD>Each member variable is wrapped as a + method with an optional parameter. Called with one argument, the member + variable is set to the value of the argument. With zero arguments, the + value is returned.</TD></TR> +</TABLE> +<P> Note that this string belongs to the wrapper object, and not the + underlying pointer, so using create_[x]_from_ptr alters the returned + value for the same object.</P> +<H4><A name="Ocaml_nn18"></A>26.2.4.1 STL vector and string Example</H4> +<P> Standard typemaps are now provided for STL vector and string. More + are in the works. STL strings are passed just like normal strings, and + returned as strings. STL string references don't mutate the original + string, (which might be surprising), because Ocaml strings are mutable + but have fixed length. Instead, use multiple returns, as in the + argout_ref example.</P> +<TABLE bgcolor="#dddddd" border="1" summary="STL vector and string example"> +<TR><TH> +<CENTER>example.i</CENTER> +</TH></TR> +<TR><TD> +<PRE> +%module example +%{ +#include "example.h" +%} + +%include <stl.i> + +namespace std { + %template(StringVector) std::vector < string >; +}; + +%include "example.h" +</PRE> +</TD></TR> +<TR><TD><FONT size="-1"><I>This example is in Examples/ocaml/stl</I></FONT> +</TD></TR> +</TABLE> +<P> Since there's a makefile in that directory, the example is easy to + build.</P> +<P> Here's a sample transcript of an interactive session using a string + vector after making a toplevel (make toplevel). This example uses the + camlp4 module.</P> +<DIV class="code"> +<PRE> +bash-2.05a$ ./example_top + Objective Caml version 3.06 + + Camlp4 Parsing version 3.06 + +# open Swig ;; +# open Example ;; +# let x = new_StringVector '() ;; +val x : Example.c_obj = C_obj <fun> +# x -> ":methods" () ;; +- : Example.c_obj = +C_list + [C_string "nop"; C_string "size"; C_string "empty"; C_string "clear"; + C_string "push_back"; C_string "[]"; C_string "="; C_string "set"; + C_string "~"; C_string "&"; C_string ":parents"; C_string ":classof"; + C_string ":methods"] +# x -> push_back ("foo") ;; +- : Example.c_obj = C_void +# x -> push_back ("bar") ;; +- : Example.c_obj = C_void +# x -> push_back ("baz") ;; +- : Example.c_obj = C_void +# x '[1] ;; +- : Example.c_obj = C_string "bar" +# x -> set (1,"spam") ;; +- : Example.c_obj = C_void +# x '[1] ;; +- : Example.c_obj = C_string "spam" +# for i = 0 to (x -> size() as int) - 1 do + print_endline ((x '[i to int]) as string) + done ;; +foo +bar +baz +- : unit = () +# +</PRE> +</DIV> +<H4><A name="Ocaml_nn19"></A>26.2.4.2 C++ Class Example</H4> +<P> Here's a simple example using Trolltech's Qt Library:</P> +<TABLE bgcolor="#dddddd" border="1" summary="Qt Library example"> +<TR><TH> +<CENTER>qt.i</CENTER> +</TH></TR> +<TR><TD> +<PRE> +%module qt +%{ +#include <qapplication.h> +#include <qpushbutton.h> +%} +class QApplication { +public: + QApplication( int argc, char **argv ); + void setMainWidget( QWidget *widget ); + void exec(); +}; + +class QPushButton { +public: + QPushButton( char *str, QWidget *w ); + void resize( int x, int y ); + void show(); +}; +</PRE> +</TD></TR> +</TABLE> +<H4><A name="Ocaml_nn20"></A>26.2.4.3 Compiling the example</H4> +<DIV class="code"> +<PRE> +bash-2.05a$ QTPATH=/your/qt/path +bash-2.05a$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done +bash-2.05a$ ocamlc -c swig.mli ; ocamlc -c swig.ml +bash-2.05a$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml +bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include qt.i +bash-2.05a$ mv qt_wrap.cxx qt_wrap.c +bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c +bash-2.05a$ ocamlc -c qt.mli +bash-2.05a$ ocamlc -c qt.ml +bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \ + camlp4o.cma swigp4.cmo qt_wrap.o qt.cmo -o qt_top -cclib \ + -L$QTPATH/lib -cclib -lqt +</PRE> +</DIV> +<H4><A name="Ocaml_nn21"></A>26.2.4.4 Sample Session</H4> +<DIV class="code"> +<PRE> +bash-2.05a$ ./qt_top + Objective Caml version 3.06 + + Camlp4 Parsing version 3.06 + +# open Swig ;; +# open Qt ;; +# let a = new_QApplication '(0,0) ;; +val a : Qt.c_obj = C_obj <fun> +# let hello = new_QPushButton '("hi",0) ;; +val hello : Qt.c_obj = C_obj <fun> +# hello -> resize (100,30) ;; +- : Qt.c_obj = C_void +# hello -> show () ;; +- : Qt.c_obj = C_void +# a -> exec () ;; +</PRE> +</DIV> +<P> Assuming you have a working installation of QT, you will see a + window containing the string "hi" in a button.</P> +<H3><A name="Ocaml_nn22"></A>26.2.5 Director Classes</H3> +<H4><A name="Ocaml_nn23"></A>26.2.5.1 Director Introduction</H4> +<P> Director classes are classes which allow Ocaml code to override the + public methods of a C++ object. This facility allows the user to use + C++ libraries that require a derived class to provide application + specific functionality in the context of an application or utility + framework.</P> +<P> You can turn on director classes by using an optional module + argument like this:</P> +<DIV class="code"> +<PRE> +%module(directors="1") + +... + +// Turn on the director class for a specific class like this: +%feature("director") +class foo { + ... +}; +</PRE> +</DIV> +<H4><A name="Ocaml_nn24"></A>26.2.5.2 Overriding Methods in Ocaml</H4> +<P> Because the Ocaml language module treats C++ method calls as calls + to a certain function, all you need to do is to define the function + that will handle the method calls in terms of the public methods of the + object, and any other relevant information. The function <TT> +new_derived_object</TT> uses a stub class to call your methods in place + of the ones provided by the underlying implementation. The object you + receive is the underlying object, so you are free to call any methods + you want from within your derived method. Note that calls to the + underlying object do not invoke Ocaml code. You need to handle that + yourself.</P> +<P> <TT>new_derived_object</TT> receives your function, the function + that creates the underlying object, and any constructor arguments, and + provides an object that you can use in any usual way. When C++ code + calls one of the object's methods, the object invokes the Ocaml + function as if it had been invoked from Ocaml, allowing any method + definitions to override the C++ ones.</P> +<P> In this example, I'll examine the objective caml code involved in + providing an overloaded class. This example is contained in + Examples/ocaml/shapes.</P> +<H4><A name="Ocaml_nn25"></A>26.2.5.3 Director Usage Example</H4> +<TABLE bgcolor="#dddddd" border="1" summary="Director usage example"> +<TR><TH> +<CENTER>example_prog.ml</CENTER> +</TH></TR> +<TR><TD> +<PRE> +open Swig +open Example + +... + +let triangle_class pts ob meth args = + match meth with + "cover" -> + (match args with + C_list [ x_arg ; y_arg ] -> + let xa = x_arg as float + and ya = y_arg as float in + (point_in_triangle pts xa ya) to bool + | _ -> raise (Failure "cover needs two double arguments.")) + | _ -> (invoke ob) meth args ;; + +let triangle = + new_derived_object + new_shape + (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0))) + '() ;; + +let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;; +</PRE> +</TD></TR> +</TABLE> +<P> This is the meat of what you need to do. The actual "class" + definition containing the overloaded method is defined in the function + triangle_class. This is a lot like the class definitions emitted by + SWIG, if you look at example.ml, which is generated when SWIG consumes + example.i. Basically, you are given the arguments as a c_obj and the + method name as a string, and you must intercept the method you are + interested in and provide whatever return value you need. Bear in mind + that the underlying C++ code needs the right return type, or an + exception will be thrown. This exception will generally be Failure, or + NotObject. You must call other ocaml methods that you rely on yourself. + Due to the way directors are implemented, method calls on your object + from with ocaml code will always invoke C++ methods even if they are + overridden in ocaml.</P> +<P> In the example, the draw_shape_coverage function plots the indicated + number of points as either covered (<TT>x</TT>) or uncovered ( ) + between 0 and 1 on the X and Y axes. Your shape implementation can + provide any coverage map it likes, as long as it responds to the + "cover" method call with a boolean return (the underlying method + returns bool). This might allow a tricky shape implementation, such as + a boolean combination, to be expressed in a more effortless style in + ocaml, while leaving the "engine" part of the program in C++.</P> +<H4><A name="Ocaml_nn26"></A>26.2.5.4 Creating director objects</H4> +<P> The definition of the actual object triangle can be described this + way:</P> +<DIV class="code"> +<PRE> +let triangle = + new_derived_object + new_shape + (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0))) + '() +</PRE> +</DIV> +<P> The first argument to <TT>new_derived_object</TT>, new_shape is the + method which returns a shape instance. This function will be invoked + with the third argument will be appended to the argument list [ C_void + ]. In the example, the actual argument list is sent as (C_list [ C_void + ; C_void ]). The augmented constructor for a director class needs the + first argument to determine whether it is being constructed as a + derived object, or as an object of the indicated type only (in this + case <TT>shape</TT>). The Second argument is a closure that will be + added to the final C_obj.</P> +<P> The actual object passed to the self parameter of the director + object will be a C_director_core, containing a c_obj option ref and a + c_obj. The c_obj provided is the same object that will be returned from + new_derived object, that is, the object exposing the overridden + methods. The other part is an option ref that will have its value + extracted before becoming the <TT>ob</TT> parameter of your class + closure. This ref will contain <TT>None</TT> if the C++ object + underlying is ever destroyed, and will consequently trigger an + exception when any method is called on the object after that point (the + actual raise is from an inner function used by new_derived_object, and + throws NotObject). This prevents a deleted C++ object from causing a + core dump, as long as the object is destroyed properly.</P> +<H4><A name="Ocaml_nn27"></A>26.2.5.5 Typemaps for directors, <TT> +directorin, directorout, directorargout</TT></H4> +<P> Special typemaps exist for use with directors, the <TT>directorin, + directorout, directorargout</TT> are used in place of <TT>in, out, + argout</TT> typemaps, except that their direction is reversed. They + provide for you to provide argout values, as well as a function return + value in the same way you provide function arguments, and to receive + arguments the same way you normally receive function returns.</P> +<H4><A name="Ocaml_nn28"></A>26.2.5.6 <TT>directorin</TT> typemap</H4> +<P> The <TT>directorin</TT> typemap is used when you will receive + arguments from a call made by C++ code to you, therefore, values will + be translated from C++ to ocaml. You must provide some valid C_obj + value. This is the value your ocaml code receives when you are called. + In general, a simple <TT>directorin</TT> typemap can use the same body + as a simple <TT>out</TT> typemap.</P> +<H4><A name="Ocaml_nn29"></A>26.2.5.7 <TT>directorout</TT> typemap</H4> +<P> The <TT>directorout</TT> typemap is used when you will send an + argument from your code back to the C++ caller. That is; directorout + specifies a function return conversion. You can usually use the same + body as an <TT>in</TT> typemap for the same type, except when there are + special requirements for object ownership, etc.</P> +<H4><A name="Ocaml_nn30"></A>26.2.5.8 <TT>directorargout</TT> typemap</H4> +<P> C++ allows function arguments which are by pointer (*) and by + reference (&) to receive a value from the called function, as well as + sending one there. Sometimes, this is the main purpose of the argument + given. <TT>directorargout</TT> typemaps allow your caml code to emulate + this by specifying additional return values to be put into the output + parameters. The SWIG ocaml module is a bit loose in order to make code + easier to write. In this case, your return to the caller must be a list + containing the normal function return first, followed by any argout + values in order. These argout values will be taken from the list and + assigned to the values to be returned to C++ through directorargout + typemaps. In the event that you don't specify all of the necessary + values, integral values will read zero, and struct or object returns + have undefined results.</P> +<H3><A name="Ocaml_nn31"></A>26.2.6 Exceptions</H3> +<P> Catching exceptions is now supported using SWIG's %exception + feature. A simple but not too useful example is provided by the + throw_exception testcase in Examples/test-suite. You can provide your + own exceptions, too.</P> +<HR NOSHADE> +<H1><A name="Octave"></A>27 SWIG and Octave</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Octave_nn2">Preliminaries</A></LI> +<LI><A href="#Octave_nn3">Running SWIG</A> +<UL> +<LI><A href="#Octave_nn5">Compiling a dynamic module</A></LI> +<LI><A href="#Octave_nn6">Using your module</A></LI> +</UL> +</LI> +<LI><A href="#Octave_nn7">A tour of basic C/C++ wrapping</A> +<UL> +<LI><A href="#Octave_nn8">Modules</A></LI> +<LI><A href="#Octave_nn9">Functions</A></LI> +<LI><A href="#Octave_nn10">Global variables</A></LI> +<LI><A href="#Octave_nn11">Constants and enums</A></LI> +<LI><A href="#Octave_nn12">Pointers</A></LI> +<LI><A href="#Octave_nn13">Structures and C++ classes</A></LI> +<LI><A href="#Octave_nn15">C++ inheritance</A></LI> +<LI><A href="#Octave_nn17">C++ overloaded functions</A></LI> +<LI><A href="#Octave_nn18">C++ operators</A></LI> +<LI><A href="#Octave_nn19">Class extension with %extend</A></LI> +<LI><A href="#Octave_nn20">C++ templates</A></LI> +<LI><A href="#Octave_nn21">C++ Smart Pointers</A></LI> +<LI><A href="#Octave_nn22">Directors (calling Octave from C++ code)</A></LI> +<LI><A href="#Octave_nn23">Threads</A></LI> +<LI><A href="#Octave_nn24">Memory management</A></LI> +<LI><A href="#Octave_nn25">STL support</A></LI> +<LI><A href="#Octave_nn26">Matrix typemaps</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> Octave is a high-level language intended for numerical programming + that is mostly compatible with MATLAB. More information can be found at + <A href="http://www.octave.org">www.octave.org</A>.</P> +<P> This chapter is intended to give an introduction to using the + module. You should also read the SWIG documentation that is not + specific to Octave. Also, there are a dozen or so examples in the + Examples/octave directory, and hundreds in the test suite + (Examples/test-suite and Examples/test-suite/octave).</P> +<H2><A name="Octave_nn2"></A>27.1 Preliminaries</H2> +<P> The current SWIG implemention is based on Octave 2.9.12. Support for + other versions (in particular the recent 3.0) has not been tested, nor + has support for any OS other than Linux.</P> +<H2><A name="Octave_nn3"></A>27.2 Running SWIG</H2> +<P> Let's start with a very simple SWIG interface file:</P> +<DIV class="code"> +<PRE>%module example +%{ +#include "example.h" +%} +int gcd(int x, int y); +extern double Foo; </PRE> +</DIV> +<P> To build an Octave module, run SWIG using the <TT>-octave</TT> + option. The <TT>-c++</TT> option is required (for now) as Octave itself + is written in C++ and thus the wrapper code must also be.</P> +<DIV class="shell"> +<PRE>$ swig -octave -c++ example.i </PRE> +</DIV> +<P> This creates a C/C++ source file <TT>example_wrap.cxx</TT>. The + generated C++ source file contains the low-level wrappers that need to + be compiled and linked with the rest of your C/C++ application (in this + case, the gcd implementation) to create an extension module.</P> +<P> The swig command line has a number of options you can use, like to + redirect it's output. Use <TT>swig --help</TT> to learn about these.</P> +<H3><A name="Octave_nn5"></A>27.2.1 Compiling a dynamic module</H3> +<P> Octave modules are DLLs/shared objects having the ".oct" suffix. + Building an oct file is usually done with the mkoctfile command (either + within Octave itself, or from the shell). For example,</P> +<DIV class="shell"> +<PRE> +$ swig -octave -c++ example.i -o example_wrap.cxx +$ mkoctfile example_wrap.cxx example.c +</PRE> +</DIV> +<P> where example.c is the file containing the gcd() implementation.</P> +<P> mkoctfile can also be used to extract the build parameters required + to invoke the compiler and linker yourself. See the Octave manual and + mkoctfile man page.</P> +<P> mkoctfile will produce example.oct, which contains the compiled + extension module. Loading it into Octave is then a matter of invoking</P> +<DIV class="targetlang"> +<PRE>octave:1> example</PRE> +</DIV> +<H3><A name="Octave_nn6"></A>27.2.2 Using your module</H3> +<P> Assuming all goes well, you will be able to do this: +<BR></P> +<DIV class="targetlang"> +<PRE>$ octave -q +octave:1> example +octave:2> example.gcd(4,6) +ans = 2 +octave:3> example.cvar.Foo +ans = 3 +octave:4> example.cvar.Foo=4; +octave:5> example.cvar.Foo +ans = 4 </PRE> +</DIV> +<H2><A name="Octave_nn7"></A>27.3 A tour of basic C/C++ wrapping</H2> +<H3><A name="Octave_nn8"></A>27.3.1 Modules</H3> +<P> The SWIG module directive specifies the name of the Octave module. + If you specify `module example', then in Octave everything in the + module will be accessible under "example", as in the above example. + When choosing a module name, make sure you don't use the same name as a + built-in Octave command or standard module name.</P> +<P> When Octave is asked to invoke <TT>example</TT>, it will try to find + the .m or .oct file that defines the function "example". It will thusly + find example.oct, that upon loading will register all of the module's + symbols.</P> +<P> Giving this function a parameter "global" will cause it to load all + symbols into the global namespace in addition to the <TT>example</TT> + namespace. For example:</P> +<DIV class="targetlang"> +<PRE>$ octave -q +octave:1> example("global") +octave:2> gcd(4,6) +ans = 2 +octave:3> cvar.Foo +ans = 3 +octave:4> cvar.Foo=4; +octave:5> cvar.Foo +ans = 4 +</PRE> +</DIV> +<P> It is also possible to rename the module namespace with an + assignment, as in: +<BR><DIV class="targetlang"> +<PRE>octave:1> example; +octave:2> c=example; +octave:3> c.gcd(10,4) +ans = 2 </PRE> +</DIV></P> +<P> All global variables are put into the cvar namespace object. This is + accessible either as <TT>my_module.cvar</TT>, or just <TT>cvar</TT> (if + the module is imported into the global namespace).</P> +<P> One can also rename it by simple assignment, e.g.,</P> +<DIV class="targetlang"> +<PRE> +octave:1> some_vars = cvar; +</PRE> +</DIV> +<H3><A name="Octave_nn9"></A>27.3.2 Functions</H3> +<P> Global functions are wrapped as new Octave built-in functions. For + example,</P> +<DIV class="code"> +<PRE>%module example +int fact(int n); </PRE> +</DIV> +<P> creates a built-in function <TT>example.fact(n)</TT> that works + exactly like you think it does:</P> +<DIV class="targetlang"> +<PRE>octave:1> example.fact(4) +24 </PRE> +</DIV> +<H3><A name="Octave_nn10"></A>27.3.3 Global variables</H3> +<P> Global variables are a little special in Octave. Given a global + variable:</P> +<DIV class="code"> +<PRE>%module example +extern double Foo; + </PRE> +</DIV> +<P> To expose variables, SWIG actually generates two functions, to get + and set the value. In this case, Foo_set and Foo_set would be + generated. SWIG then automatically calls these functions when you get + and set the variable-- in the former case creating a local copy in the + interpreter of the C variables, and in the latter case copying an + interpreter variables onto the C variable.</P> +<DIV class="targetlang"> +<PRE>octave:1> example; +octave:2> c=example.cvar.Foo +c = 3 +octave:3> example.cvar.Foo=4; +octave:4> c +c = 3 +octave:5> example.cvar.Foo +ans = 4</PRE> +</DIV> +<P> If a variable is marked with the %immutable directive then any + attempts to set this variable will cause an Octave error. Given a + global variable:</P> +<DIV class="code"> +<PRE>%module example +%immutable; +extern double Foo; +%mutable; +</PRE> +</DIV> +<P> SWIG will allow the the reading of <TT>Foo</TT> but when a set + attempt is made, an error function will be called.</P> +<DIV class="targetlang"> +<PRE>octave:1> example +octave:2> example.Foo=4 +error: attempt to set immutable member variable +error: assignment failed, or no method for `swig_type = scalar' +error: evaluating assignment expression near line 2, column 12 </PRE> +</DIV> +<P> It is possible to add new functions or variables to the module. This + also allows the user to rename/remove existing functions and constants + (but not linked variables, mutable or immutable). Therefore users are + recommended to be careful when doing so.</P> +<DIV class="targetlang"> +<PRE>octave:1> example; +octave:2> example.PI=3.142; +octave:3> example.PI +ans = 3.1420 </PRE> +</DIV> +<H3><A name="Octave_nn11"></A>27.3.4 Constants and enums</H3> +<P> Because Octave doesn't really have the concept of constants, C/C++ + constants are not really constant in Octave. They are actually just a + copy of the value into the Octave interpreter. Therefore they can be + changed just as any other value. For example given some constants:</P> +<DIV class="code"> +<PRE>%module example +%constant int ICONST=42; +#define SCONST "Hello World" +enum Days{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY}; +</PRE> +</DIV> +<P> This is 'effectively' converted into the following Octave code:</P> +<DIV class="targetlang"> +<PRE>example.ICONST=42 +example.SCONST="Hello World" +example.SUNDAY=0 +.... </PRE> +</DIV> +<H3><A name="Octave_nn12"></A>27.3.5 Pointers</H3> +<P> C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no + problem working with incomplete type information. Given a wrapping of + the <file.h> interface: C/C++ pointers are fully supported by SWIG. + Furthermore, SWIG has no problem working with incomplete type + information. Given a wrapping of the <file.h> interface:</P> +<DIV class="code"> +<PRE>%module example +FILE *fopen(const char *filename, const char *mode); +int fputs(const char *, FILE *); +int fclose(FILE *); +</PRE> +</DIV> +<P> When wrapped, you will be able to use the functions in a natural way + from Octave. For example:</P> +<DIV class="targetlang"> +<PRE> +octave:1> example; +octave:2> f=example.fopen("w","junk"); +octave:3> example.fputs("Hello world",f); +octave:4> example.fclose(f); +</PRE> +</DIV> +<P> Simply printing the value of a wrapped C++ type will print it's + typename. E.g.,</P> +<DIV class="targetlang"> +<PRE>octave:1> example; +octave:2> f=example.fopen("junk","w"); +octave:3> f +f = + +{ + _p_FILE, ptr = 0x9b0cd00 +} </PRE> +</DIV> +<P> As the user of the pointer, you are responsible for freeing it, or + closing any resources associated with it (just as you would in a C + program). This does not apply so strictly to classes and structs (see + below).</P> +<DIV class="targetlang"> +<PRE>octave:1> example; +octave:2> f=example.fopen("not there","r"); +error: value on right hand side of assignment is undefined +error: evaluating assignment expression near line 2, column 2 </PRE> +</DIV> +<H3><A name="Octave_nn13"></A>27.3.6 Structures and C++ classes</H3> +<P> SWIG wraps C structures and C++ classes by using a special Octave + type called a <TT>swig_ref</TT>. A <TT>swig_ref</TT> contains a + reference to one or more instances of C/C++ objects, or just the type + information for an object. For each wrapped structure and class, a <TT> +swig_ref</TT> will be exposed that has the name of the type. When + invoked as a function, it creates a new object of its type and returns + a <TT>swig_ref</TT> that points to that instance. This provides a very + natural interface. For example,</P> +<DIV class="code"> +<PRE>struct Point{ + int x,y; +}; +</PRE> +</DIV> +<P> is used as follows:</P> +<DIV class="targetlang"> +<PRE>octave:1> example; +octave:2> p=example.Point(); +octave:3> p.x=3; +octave:4> p.y=5; +octave:5> p.x, p.y +ans = 3 +ans = 5 +</PRE> +</DIV> +<P> In C++, invoking the type object in this way calls the object's + constructor. <TT>swig_ref</TT> objects can also be acquired by having a + wrapped function return a pointer, reference, or value of a + non-primitive type.</P> +<P> The swig_ref type handles indexing operations such that usage maps + closely to what you would have in C/C++. Structure members are accessed + as in the above example, by calling set and get methods for C++ + variables. Methods also work as expected. For example, code wrapped in + the following way</P> +<DIV class="code"> +<PRE>class Point{ +public: + int x,y; + Point(int _x,int _y) : x(_x),y(_y) {} + double distance(const Point& rhs) { + return sqrt(pow(x-rhs.x,2)+pow(y-rhs.y,2)); + } + void set(int _x,int _y) { + x=_x; y=_y; + } +}; +</PRE> +</DIV> +<P> can be used from Octave like this</P> +<DIV class="targetlang"> +<PRE>octave:1> example; +octave:2> p1=example.Point(3,5); +octave:3> p2=example.Point(1,2); +octave:4> p1.distance(p2) +ans = 3.6056 +</PRE> +</DIV> +<P> By using the <TT>swig_this()</TT> and <TT>swig_type()</TT> + functions, one can discover the pointers to and types of the underlying + C/C++ object.</P> +<DIV class="targetlang"> +<PRE> +octave:5> swig_this(p1) +ans = 162504808 +octave:6> swig_type(p1) +ans = Point +</PRE> +</DIV> +<P> Note that <TT>swig_ref</TT> is a reference-counted pointer to a + C/C++ object/type, and as such has pass-by-reference semantics. For + example if one has a allocated a single object but has two <TT>swig_ref</TT> +'s pointing to it, modifying the object through either of them will + change the single allocated object. This differs from the usual + pass-by-value (copy-on-write) semantics that Octave maintains for + built-in types. For example, in the following snippet, modifying <TT>b</TT> + does not modify <TT>a</TT>,</P> +<DIV class="targetlang"> +<PRE> +octave:7> a=struct('x',4) +a = +{ + x = 4 +} + +octave:8> b=a +b = +{ + x = 4 +} + +octave:9> b.y=4 +b = +{ + x = 4 + y = 4 +} + +octave:10> a +a = +{ + x = 4 +} +</PRE> +</DIV> +<P> However, when dealing with wrapped objects, one gets the behavior</P> +<DIV class="targetlang"> +<PRE> +octave:2> a=Point(3,5) +a = + +{ + Point, ptr = 0x9afbbb0 +} + +octave:3> b=a +b = + +{ + Point, ptr = 0x9afbbb0 +} + +octave:4> b.set(2,1); +octave:5> b.x, b.y +ans = 2 +ans = 1 +octave:6> a.x, a.y +ans = 2 +ans = 1 +</PRE> +</DIV> +<P> Depending on the ownership setting of a <TT>swig_ref</TT>, it may + call C++ destructors when its reference count goes to zero. See the + section on memory management below for details.</P> +<H3><A name="Octave_nn15"></A>27.3.7 C++ inheritance</H3> +<P> Single and multiple inheritance are fully supported. The <TT> +swig_ref</TT> type carries type information along with any C++ object + pointer it holds. This information contains the full class hierarchy. + When an indexing operation (such as a method invocation) occurs, the + tree is walked to find a match in the current class as well as any of + its bases. The lookup is then cached in the <TT>swig_ref</TT>.</P> +<H3><A name="Octave_nn17"></A>27.3.8 C++ overloaded functions</H3> +<P> Overloaded functions are supported, and handled as in other modules. + That is, each overload is wrapped separately (under internal names), + and a dispatch function is also emitted under the external/visible + name. The dispatch function selects which overload to call (if any) + based on the passed arguments. <TT>typecheck</TT> typemaps are used to + analyze each argument, as well as assign precedence. See the chapter on + typemaps for details.</P> +<H3><A name="Octave_nn18"></A>27.3.9 C++ operators</H3> +<P> C++ operator overloading is supported, in a way similar to other + modules. The <TT>swig_ref</TT> type supports all unary and binary + operators between itself and all other types that exist in the system + at module load time. When an operator is used (where one of the + operands is a <TT>swig_ref</TT>), the runtime routes the call to either + a member function of the given object, or to a global function whose + named is derived from the types of the operands (either both or just + the lhs or rhs).</P> +<P> For example, if <TT>a</TT> and <TT>b</TT> are SWIG variables in + Octave, <TT>a+b</TT> becomes <TT>a.__add(b)</TT>. The wrapper is then + free to implement __add to do whatever it wants. A wrapper may define + the <TT>__add</TT> function manually, %rename some other function to + it, or %rename a C++ operator to it.</P> +<P> By default the C++ operators are renamed to their corresponding + Octave operators. So without doing any work, the following interface</P> +<DIV class="code"> +<PRE> +%inline { +struct A { + int value; + A(int _value) : value(_value) {} + A operator+ (const A& x) { + return A(value+x.value); + } +}; +} +</PRE> +</DIV> +<P> is usable from Octave like this:</P> +<DIV class="targetlang"> +<PRE> +a=A(2), b=A(3), c=a+b +assert(c.value==5); +</PRE> +</DIV> +<P> Octave operators are mapped in the following way:</P> +<DIV class="code"> +<PRE> +__brace a{args} +__brace_asgn a{args} = rhs +__paren a(args) +__paren_asgn a(args) = rhs +__str generates string rep +__not !a +__uplus +a +__uminus -a +__transpose a.' +__hermitian a' +__incr a++ +__decr a-- +__add a + b +__sub a - b +__mul a * b +__div a / b +__pow a ^ b +__ldiv a \ b +__lshift a <<b +__rshift a >> b +__lt a <b +__le a <= b +__eq a == b +__ge a >= b +__gt a > b +__ne a != b +__el_mul a .* b +__el_div a ./ b +__el_pow a .^ b +__el_ldiv a .\ b +__el_and a & b +__el_or a | b +</PRE> +</DIV> +<P> On the C++ side, the default mappings are as follows:</P> +<DIV class="code"> +<PRE> +%rename(__add) *::operator+; +%rename(__add) *::operator+(); +%rename(__add) *::operator+() const; +%rename(__sub) *::operator-; +%rename(__uminus) *::operator-(); +%rename(__uminus) *::operator-() const; +%rename(__mul) *::operator*; +%rename(__div) *::operator/; +%rename(__mod) *::operator%; +%rename(__lshift) *::operator< +<!--; +%rename(__rshift) *::operator--> +>; +%rename(__el_and) *::operator&&; +%rename(__el_or) *::operator||; +%rename(__xor) *::operator^; +%rename(__invert) *::operator~; +%rename(__lt) *::operator +<!--; +%rename(__le) *::operator<=; +%rename(__gt) *::operator--> +; +%rename(__ge) *::operator>=; +%rename(__eq) *::operator==; +%rename(__ne) *::operator!=; +%rename(__not) *::operator!; +%rename(__incr) *::operator++; +%rename(__decr) *::operator--; +%rename(__paren) *::operator(); +%rename(__brace) *::operator[]; +</PRE> +</DIV> +<H3><A name="Octave_nn19"></A>27.3.10 Class extension with %extend</H3> +<P> The %extend directive works the same as in other modules.</P> +<P> You can use it to define special behavior, like for example defining + Octave operators not mapped to C++ operators, or defining certain + Octave mechanisms such as how an object prints. For example, the <TT> +octave_value::{is_string,string_value,print}</TT> functions are routed + to a special method <TT>__str</TT> that can be defined inside an + %extend.</P> +<DIV class="code"> +<PRE> +%extend A { +string __str() { + stringstream sout; + sout<<$self->value; + return sout.str(); +} +} +</PRE> +</DIV> +<P> Then in Octave one gets,</P> +<DIV class="targetlang"> +<PRE> +octave:1> a=A(4); +octave:2> a +a = 4 +octave:3> printf("%s\n",a); +4 +octave:4> a.__str() +4 +</PRE> +</DIV> +<H3><A name="Octave_nn20"></A>27.3.11 C++ templates</H3> +<P> C++ class and function templates are fully supported as in other + modules, in that the %template directive may used to create explicit + instantiations of templated types. For example, function templates can + be instantiated as follows:</P> +<DIV class="code"> +<PRE>%module example +%inline { + template<class __scalar> + __scalar mul(__scalar a,__scalar b) { + return a*b; + } +} +%include <std_complex.i> +%template(mul) mul<std::complex<double> > +%template(mul) mul<double> +</PRE> +</DIV> +<P> and then used from Octave</P> +<DIV class="targetlang"> +<PRE> +octave:1> mul(4,3) +ans = 12 +octave:2> mul(4.2,3.6) +ans = 15.120 +octave:3> mul(3+4i,10+2i) +ans = 22 + 46i +</PRE> +</DIV> +<P> Similarly, class templates can be instantiated as in the following + example,</P> +<DIV class="code"> +<PRE>%module example +%include <std_complex.i> +%include <std_string.i> +%inline { + #include <sstream> + template<class __scalar> class sum { + __scalar s; + public: + sum(__scalar _s=0) : s(_s) {} + sum& add(__scalar _s) { + s+=_s; + return *this; + } + std::string __str() const { + std::stringstream sout; + sout<<s; + return sout.str(); + } + }; +} +%template(sum_complex) sum<std::complex<double> >; +%template(sum_double) sum<double>; +</PRE> +</DIV> +<P> and then used from Octave</P> +<DIV class="targetlang"> +<PRE> +octave:2> a=sum_complex(2+3i); +octave:3> a.add(2) +ans = + +(4,3) +octave:4> a.add(3+i) +ans = + +(7,4) +</PRE> +</DIV> +<H3><A name="Octave_nn21"></A>27.3.12 C++ Smart Pointers</H3> +<P> C++ smart pointers are fully supported as in other modules.</P> +<H3><A name="Octave_nn22"></A>27.3.13 Directors (calling Octave from C++ + code)</H3> +<P> There is full support for SWIG Directors, which permits Octave code + to subclass C++ classes, and implement their virtual methods.</P> +<P> Octave has no direct support for object oriented programming, + however the <TT>swig_ref</TT> type provides some of this support. You + can manufacture a <TT>swig_ref</TT> using the <TT>subclass</TT> + function (provided by the SWIG/Octave runtime).</P> +<P> For example,</P> +<DIV class="targetlang"> +<PRE> +octave:1> a=subclass(); +octave:2> a.my_var = 4; +octave:3> a.my_method = @(self) printf("my_var = ",self.my_var); +octave:4> a.my_method(); +my_var = 4 +</PRE> +</DIV> +<P> <TT>subclass()</TT> can also be used to subclass one or more C++ + types. Suppose you have an interface defined by</P> +<DIV class="code"> +<PRE> +%inline { +class A { +public: + virtual my_method() { + printf("c-side routine called\n"); + } +}; +void call_your_method(A& a) { + a.my_method(); +} +} +</PRE> +</DIV> +<P> Then from Octave you can say:</P> +<DIV class="targetlang"> +<PRE> +octave:1> B=@() subclass(A(),@my_method); +octave:2> function my_method(self) +octave:3> printf("octave-side routine called\n"); +octave:4> end +octave:5> call_your_method(B()); +octave-side routine called +</PRE> +</DIV> +<P> or more concisely,</P> +<DIV class="targetlang"> +<PRE> +octave:1> B=@() subclass(A(),'my_method',@(self) printf("octave-side routine called\n")); +octave:2> call_your_method(B()); +octave-side routine called +</PRE> +</DIV> +<P> Note that you have to enable directors via the %feature directive + (see other modules for this).</P> +<P> <TT>subclass()</TT> will accept any number of C++ bases or other <TT> +subclass()</TT>'ed objects, <TT>(string,octave_value)</TT> pairs, and <TT> +function_handles</TT>. In the first case, these are taken as base + classes; in the second case, as named members (either variables or + functions, depending on whether the given value is a function handle); + in the third case, as member functions whose name is taken from the + given function handle. E.g.,</P> +<DIV class="targetlang"> +<PRE> +octave:1> B=@(some_var=2) subclass(A(),'some_var',some_var,@some_func,'another_func',@(self) do_stuff()) +</PRE> +</DIV> +<P> You can also assign non-C++ member variables and functions after + construct time. There is no support for non-C++ static members.</P> +<P> There is limited support for explicitly referencing C++ bases. So, + in the example above, we could have</P> +<DIV class="targetlang"> +<PRE> +octave:1> B=@() subclass(A(),@my_method); +octave:2> function my_method(self) +octave:3> self.A.my_method(); +octave:4> printf("octave-side routine called\n"); +octave:5> end +octave:6> call_your_method(B()); +c-side routine called +octave-side routine called +</PRE> +</DIV> +<H3><A name="Octave_nn23"></A>27.3.14 Threads</H3> +<P> The use of threads in wrapped Director code is not supported; i.e., + an Octave-side implementation of a C++ class must be called from the + Octave interpreter's thread. Anything fancier (apartment/queue model, + whatever) is left to the user. Without anything fancier, this amounts + to the limitation that Octave must drive the module... like, for + example, an optimization package that calls Octave to evaluate an + objective function.</P> +<H3><A name="Octave_nn24"></A>27.3.15 Memory management</H3> +<P> As noted above, <TT>swig_ref</TT> represents a reference counted + pointer to a C/C++-side object. It also contains a flag indicating + whether Octave or the C/C++ code owns the object. If Octave owns it, + any destructors will be called when the reference count reaches zero. + If the C/C++ side owns the object, then destructors will not be called + when the reference count goes to zero.</P> +<P> For example,<DIV class="code"> +<PRE> +%inline { +class A { +public: + A() { printf("A constructing\n"); } + ~A() { printf("A destructing\n"); } +}; +} +</PRE> +</DIV></P> +<P> Would produce this behavior in Octave:</P> +<DIV class="targetlang"> +<PRE> +octave:1> a=A(); +A constructing +octave:2> b=a; +octave:3> clear a; +octave:4> b=4; +A destructing +</PRE> +</DIV> +<P> The %newobject directive may be used to control this behavior for + pointers returned from functions.</P> +<P> In the case where one wishes for the C++ side to own an object that + was created in Octave (especially a Director object), one can use the + __disown() method to invert this logic. Then letting the Octave + reference count go to zero will not destroy the object, but destroying + the object will invalidate the Octave-side object if it still exists + (and call destructors of other C++ bases in the case of multiple + inheritance/<TT>subclass()</TT>'ing).</P> +<H3><A name="Octave_nn25"></A>27.3.16 STL support</H3> +<P> This is some skeleton support for various STL containers.</P> +<H3><A name="Octave_nn26"></A>27.3.17 Matrix typemaps</H3> +<P> Octave provides a rich set of classes for dealing with matrices. + Currently there are no built-in typemaps to deal with those. However, + these are relatively straight forward for users to add themselves (see + the docs on typemaps). Without much work (a single typemap decl-- say, + 5 lines of code in the interface file), it would be possible to have a + function</P> +<DIV class="code"> +<PRE> +double my_det(const double* mat,int m,int n); +</PRE> +</DIV> +<P> that is accessed from Octave as,</P> +<DIV class="targetlang"> +<PRE> +octave:1> my_det(rand(4)); +ans = -0.18388 +</PRE> +</DIV> <TT> +<BR></TT><HR NOSHADE> +<H1><A name="Perl5"></A>28 SWIG and Perl5</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Perl5_nn2">Overview</A></LI> +<LI><A href="#Perl5_nn3">Preliminaries</A> +<UL> +<LI><A href="#Perl5_nn4">Getting the right header files</A></LI> +<LI><A href="#Perl5_nn5">Compiling a dynamic module</A></LI> +<LI><A href="#Perl5_nn6">Building a dynamic module with MakeMaker</A></LI> +<LI><A href="#Perl5_nn7">Building a static version of Perl</A></LI> +<LI><A href="#Perl5_nn8">Using the module</A></LI> +<LI><A href="#Perl5_nn9">Compilation problems and compiling with C++</A></LI> +<LI><A href="#Perl5_nn10">Compiling for 64-bit platforms</A></LI> +</UL> +</LI> +<LI><A href="#Perl5_nn11">Building Perl Extensions under Windows</A> +<UL> +<LI><A href="#Perl5_nn12">Running SWIG from Developer Studio</A></LI> +<LI><A href="#Perl5_nn13">Using other compilers</A></LI> +</UL> +</LI> +<LI><A href="#Perl5_nn14">The low-level interface</A> +<UL> +<LI><A href="#Perl5_nn15">Functions</A></LI> +<LI><A href="#Perl5_nn16">Global variables</A></LI> +<LI><A href="#Perl5_nn17">Constants</A></LI> +<LI><A href="#Perl5_nn18">Pointers</A></LI> +<LI><A href="#Perl5_nn19">Structures</A></LI> +<LI><A href="#Perl5_nn20">C++ classes</A></LI> +<LI><A href="#Perl5_nn21">C++ classes and type-checking</A></LI> +<LI><A href="#Perl5_nn22">C++ overloaded functions</A></LI> +<LI><A href="#Perl5_nn23">Operators</A></LI> +<LI><A href="#Perl5_nn24">Modules and packages</A></LI> +</UL> +</LI> +<LI><A href="#Perl5_nn25">Input and output parameters</A></LI> +<LI><A href="#Perl5_nn26">Exception handling</A></LI> +<LI><A href="#Perl5_nn27">Remapping datatypes with typemaps</A> +<UL> +<LI><A href="#Perl5_nn28">A simple typemap example</A></LI> +<LI><A href="#Perl5_nn29">Perl5 typemaps</A></LI> +<LI><A href="#Perl5_nn30">Typemap variables</A></LI> +<LI><A href="#Perl5_nn31">Useful functions</A></LI> +</UL> +</LI> +<LI><A href="#Perl5_nn32">Typemap Examples</A> +<UL> +<LI><A href="#Perl5_nn33">Converting a Perl5 array to a char **</A></LI> +<LI><A href="#Perl5_nn34">Return values</A></LI> +<LI><A href="#Perl5_nn35">Returning values from arguments</A></LI> +<LI><A href="#Perl5_nn36">Accessing array structure members</A></LI> +<LI><A href="#Perl5_nn37">Turning Perl references into C pointers</A></LI> +<LI><A href="#Perl5_nn38">Pointer handling</A></LI> +</UL> +</LI> +<LI><A href="#Perl5_nn39">Proxy classes</A> +<UL> +<LI><A href="#Perl5_nn40">Preliminaries</A></LI> +<LI><A href="#Perl5_nn41">Structure and class wrappers</A></LI> +<LI><A href="#Perl5_nn42">Object Ownership</A></LI> +<LI><A href="#Perl5_nn43">Nested Objects</A></LI> +<LI><A href="#Perl5_nn44">Proxy Functions</A></LI> +<LI><A href="#Perl5_nn45">Inheritance</A></LI> +<LI><A href="#Perl5_nn46">Modifying the proxy methods</A></LI> +</UL> +</LI> +<LI><A href="#Perl5_nn47">Adding additional Perl code</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P><B> Caution: This chapter is under repair!</B></P> +<P> This chapter describes SWIG's support of Perl5. Although the Perl5 + module is one of the earliest SWIG modules, it has continued to evolve + and has been improved greatly with the help of SWIG users. For the best + results, it is recommended that SWIG be used with Perl5.003 or later. + Earlier versions are problematic and SWIG generated extensions may not + compile or run correctly.</P> +<H2><A name="Perl5_nn2"></A>28.1 Overview</H2> +<P> To build Perl extension modules, SWIG uses a layered approach. At + the lowest level, simple procedural wrappers are generated for + functions, classes, methods, and other declarations in the input file. + Then, for structures and classes, an optional collection of Perl proxy + classes can be generated in order to provide a more natural object + oriented Perl interface. These proxy classes simply build upon the + low-level interface.</P> +<P> In describing the Perl interface, this chapter begins by covering + the essentials. First, the problem of configuration, compiling, and + installing Perl modules is discussed. Next, the low-level procedural + interface is presented. Finally, proxy classes are described. Advanced + customization features, typemaps, and other options are found near the + end of the chapter.</P> +<H2><A name="Perl5_nn3"></A>28.2 Preliminaries</H2> +<P> To build a Perl5 module, run Swig using the <TT>-perl</TT> option as + follows :</P> +<DIV class="code"> +<PRE> +swig -perl example.i + +</PRE> +</DIV> +<P> This produces two files. The first file, <TT>example_wrap.c</TT> + contains all of the C code needed to build a Perl5 module. The second + file, <TT>example.pm</TT> contains supporting Perl code needed to + properly load the module.</P> +<P> To build the module, you will need to compile the file <TT> +example_wrap.c</TT> and link it with the rest of your program.</P> +<H3><A name="Perl5_nn4"></A>28.2.1 Getting the right header files</H3> +<P> In order to compile, SWIG extensions need the following Perl5 header + files :</P> +<DIV class="code"> +<PRE> +#include "Extern.h" +#include "perl.h" +#include "XSUB.h" +</PRE> +</DIV> +<P> These are typically located in a directory like this</P> +<DIV class="code"> +<PRE> +/usr/lib/perl5/5.00503/i386-linux/CORE +</PRE> +</DIV> +<P> The SWIG configuration script automatically tries to locate this + directory so that it can compile examples. However, if you need to find + out where the directory is loaded, an easy way to find out is to run + Perl itself.</P> +<DIV class="code"> +<PRE> +% perl -e 'use Config; print $Config{archlib};' +/usr/lib/perl5/5.00503/i386-linux +</PRE> +</DIV> +<H3><A name="Perl5_nn5"></A>28.2.2 Compiling a dynamic module</H3> +<P> The preferred approach to building an extension module is to compile + it into a shared object file or DLL. To do this, you will need to + compile your program using commands like this (shown for Linux):</P> +<DIV class="code"> +<PRE> +$ swig -perl example.i +% gcc example.c +% gcc -c example_wrap.c -I/usr/lib/perl5/5.00503/i386-linux/CORE -Dbool=char +% gcc -shared example.o example_wrap.o -o example.so +</PRE> +</DIV> +<P> The exact compiler options vary from platform to platform. SWIG + tries to guess the right options when it is installed. Therefore, you + may want to start with one of the examples in the <TT> +SWIG/Examples/perl5</TT> directory. If that doesn't work, you will need + to read the man-pages for your compiler and linker to get the right set + of options. You might also check the <A href="http://www.dabeaz.com/cgi-bin/wiki.pl"> +SWIG Wiki</A> for additional information.</P> +<P> When linking the module, the name of the shared object file must + match the module name used in the SWIG interface file. If you used `<TT> +%module example</TT>', then the target should be named `<TT>example.so</TT> +', `<TT>example.sl</TT>', or the appropriate dynamic module name on your + system.</P> +<H3><A name="Perl5_nn6"></A>28.2.3 Building a dynamic module with + MakeMaker</H3> +<P> It is also possible to use Perl to build dynamically loadable + modules for you using the MakeMaker utility. To do this, write a Perl + script such as the following :</P> +<DIV class="targetlang"> +<PRE> +# File : Makefile.PL +use ExtUtils::MakeMaker; +WriteMakefile( + `NAME' => `example', # Name of package + `LIBS' => [`-lm'], # Name of custom libraries + `OBJECT' => `example.o example_wrap.o' # Object files +); + +</PRE> +</DIV> +<P> Now, to build a module, simply follow these steps :</P> +<DIV class="code"> +<PRE> +% perl Makefile.PL +% make +% make install +</PRE> +</DIV> +<P> If you are planning to distribute a SWIG-generated module, this is + the preferred approach to compilation. More information about MakeMaker + can be found in "Programming Perl, 2nd ed." by Larry Wall, Tom + Christiansen, and Randal Schwartz.</P> +<H3><A name="Perl5_nn7"></A>28.2.4 Building a static version of Perl</H3> +<P> If you machine does not support dynamic loading or if you've tried + to use it without success, you can build a new version of the Perl + interpreter with your SWIG extensions added to it. To build a static + extension, you first need to invoke SWIG as follows :</P> +<DIV class="code"> +<PRE> +% swig -perl -static example.i +</PRE> +</DIV> +<P> By default SWIG includes code for dynamic loading, but the <TT> +-static</TT> option takes it out.</P> +<P> Next, you will need to supply a <TT>main()</TT> function that + initializes your extension and starts the Perl interpreter. While, this + may sound daunting, SWIG can do this for you automatically as follows :</P> +<DIV class="targetlang"> +<PRE> +%module example + +%inline %{ +extern double My_variable; +extern int fact(int); +%} + +// Include code for rebuilding Perl +%include <perlmain.i> +</PRE> +</DIV> +<P> The same thing can be accomplished by running SWIG as follows :</P> +<DIV class="code"> +<PRE> +% swig -perl -static -lperlmain.i example.i +</PRE> +</DIV> +<P> The <TT>perlmain.i</TT> file inserts Perl's <TT>main()</TT> function + into the wrapper code and automatically initializes the SWIG generated + module. If you just want to make a quick a dirty module, this may be + the easiest way. By default, the <TT>perlmain.i</TT> code does not + initialize any other Perl extensions. If you need to use other + packages, you will need to modify it appropriately. You can do this by + just copying <TT>perlmain.i</TT> out of the SWIG library, placing it in + your own directory, and modifying it to suit your purposes.</P> +<P> To build your new Perl executable, follow the exact same procedure + as for a dynamic module, but change the link line to something like + this:</P> +<DIV class="code"> +<PRE> +% gcc example.o example_wrap.o -L/usr/lib/perl5/5.00503/i386-linux/CORE \ + -lperl -lsocket -lnsl -lm -o myperl +</PRE> +</DIV> +<P> This will produce a new version of Perl called <TT>myperl</TT>. It + should be functionality identical to Perl with your C/C++ extension + added to it. Depending on your machine, you may need to link with + additional libraries such as <TT>-lsocket, -lnsl, -ldl</TT>, etc.</P> +<H3><A name="Perl5_nn8"></A>28.2.5 Using the module</H3> +<P> To use the module, simply use the Perl <TT>use</TT> statement. If + all goes well, you will be able to do this:</P> +<DIV class="targetlang"> +<PRE> +$ perl +use example; +print example::fact(4),"\n"; +24 +</PRE> +</DIV> +<P> A common error received by first-time users is the following:</P> +<DIV class="targetlang"> +<PRE> +use example; +Can't locate example.pm in @INC (@INC contains: /usr/lib/perl5/5.00503/i386-lin +ux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/pe +rl5/site_perl/5.005 .) at - line 1. +BEGIN failed--compilation aborted at - line 1. +</PRE> +</DIV> +<P> This error is almost caused when the name of the shared object file + you created doesn't match the module name you specified with the <TT> +%module</TT> directive.</P> +<P> A somewhat related, but slightly different error is this:</P> +<DIV class="targetlang"> +<PRE> +use example; +Can't find 'boot_example' symbol in ./example.so + at - line 1 +BEGIN failed--compilation aborted at - line 1. +</PRE> +</DIV> +<P> This error is generated because Perl can't locate the module + bootstrap function in the SWIG extension module. This could be caused + by a mismatch between the module name and the shared library name. + However, another possible cause is forgetting to link the + SWIG-generated wrapper code with the rest of your application when you + linked the extension module.</P> +<P> Another common error is the following:</P> +<DIV class="targetlang"> +<PRE> +use example; +Can't load './example.so' for module example: ./example.so: +undefined symbol: Foo at /usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169. + + at - line 1 +BEGIN failed--compilation aborted at - line 1. +</PRE> +</DIV> +<P> This error usually indicates that you forgot to include some object + files or libraries in the linking of the shared library file. Make sure + you compile both the SWIG wrapper file and your original program into a + shared library file. Make sure you pass all of the required libraries + to the linker.</P> +<P> Sometimes unresolved symbols occur because a wrapper has been + created for a function that doesn't actually exist in a library. This + usually occurs when a header file includes a declaration for a function + that was never actually implemented or it was removed from a library + without updating the header file. To fix this, you can either edit the + SWIG input file to remove the offending declaration or you can use the <TT> +%ignore</TT> directive to ignore the declaration. Better yet, update the + header file so that it doesn't have an undefined declaration.</P> +<P> Finally, suppose that your extension module is linked with another + library like this:</P> +<DIV class="code"> +<PRE> +$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \ + -o example.so +</PRE> +</DIV> +<P> If the <TT>foo</TT> library is compiled as a shared library, you + might get the following error when you try to use your module:</P> +<DIV class="targetlang"> +<PRE> +use example; +Can't load './example.so' for module example: libfoo.so: cannot open shared object file: +No such file or directory at /usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169. + + at - line 1 +BEGIN failed--compilation aborted at - line 1. +>>> +</PRE> +</DIV> +<P> This error is generated because the dynamic linker can't locate the <TT> +libfoo.so</TT> library. When shared libraries are loaded, the system + normally only checks a few standard locations such as <TT>/usr/lib</TT> + and <TT>/usr/local/lib</TT>. To get the loader to look in other + locations, there are several things you can do. First, you can + recompile your extension module with extra path information. For + example, on Linux you can do this:</P> +<DIV class="code"> +<PRE> +$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \ + <B>-Xlinker -rpath /home/beazley/projects/lib \</B> + -o example.so +</PRE> +</DIV> +<P> Alternatively, you can set the <TT>LD_LIBRARY_PATH</TT> environment + variable to include the directory with your shared libraries. If + setting <TT>LD_LIBRARY_PATH</TT>, be aware that setting this variable + can introduce a noticeable performance impact on all other applications + that you run. To set it only for Perl, you might want to do this + instead:</P> +<DIV class="code"> +<PRE> +$ env LD_LIBRARY_PATH=/home/beazley/projects/lib perl +</PRE> +</DIV> +<P> Finally, you can use a command such as <TT>ldconfig</TT> (Linux) or <TT> +crle</TT> (Solaris) to add additional search paths to the default system + configuration (this requires root access and you will need to read the + man pages).</P> +<H3><A name="Perl5_nn9"></A>28.2.6 Compilation problems and compiling + with C++</H3> +<P> Compilation of C++ extensions has traditionally been a tricky + problem. Since the Perl interpreter is written in C, you need to take + steps to make sure C++ is properly initialized and that modules are + compiled correctly.</P> +<P> On most machines, C++ extension modules should be linked using the + C++ compiler. For example:</P> +<DIV class="code"> +<PRE> +% swig -c++ -perl example.i +% g++ -c example.cxx +% g++ -c example_wrap.cxx -I/usr/lib/perl5/5.00503/i386-linux/CORE +% <B>g++ -shared example.o example_wrap.o -o example.so</B> +</PRE> +</DIV> +<P> In addition to this, you may need to include additional library + files to make it work. For example, if you are using the Sun C++ + compiler on Solaris, you often need to add an extra library <TT>-lCrun</TT> + like this:</P> +<DIV class="code"> +<PRE> +% swig -c++ -perl example.i +% g++ -c example.cxx +% g++ -c example_wrap.cxx -I/usr/lib/perl5/5.00503/i386-linux/CORE +% g++ -shared example.o example_wrap.o -o example.so <B>-lCrun</B> +</PRE> +</DIV> +<P> Of course, the names of the extra libraries are completely + non-portable---you will probably need to do some experimentation.</P> +<P> Another possible compile problem comes from recent versions of Perl + (5.8.0) and the GNU tools. If you see errors having to do with + _crypt_struct, that means _GNU_SOURCE is not defined and it needs to + be. So you should compile the wrapper like:</P> +<DIV class="code"> +<PRE> +% g++ -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE -D_GNU_SOURCE +</PRE> +</DIV> +<P> -D_GNU_SOURCE is also included in the Perl ccflags, which can be + found by running</P> +<DIV class="code"> +<PRE> +% perl -e 'use Config; print $Config{ccflags};' +</PRE> +</DIV> +<P> So you could also compile the wrapper like</P> +<DIV class="code"> +<PRE> +% g++ -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE \ +`perl -e 'use Config; print $Config{ccflags}'` +</PRE> +</DIV> +<P> Sometimes people have suggested that it is necessary to relink the + Perl interpreter using the C++ compiler to make C++ extension modules + work. In the experience of this author, this has never actually + appeared to be necessary on most platforms. Relinking the interpreter + with C++ really only includes the special run-time libraries described + above---as long as you link your extension modules with these + libraries, it should not be necessary to rebuild Perl.</P> +<P> If you aren't entirely sure about the linking of a C++ extension, + you might look at an existing C++ program. On many Unix machines, the <TT> +ldd</TT> command will list library dependencies. This should give you + some clues about what you might have to include when you link your + extension module. For example, notice the first line of output here:</P> +<DIV class="code"> +<PRE> +$ ldd swig + <B>libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000)</B> + libm.so.6 => /lib/libm.so.6 (0x4005b000) + libc.so.6 => /lib/libc.so.6 (0x40077000) + /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) +$ +</PRE> +</DIV> +<P> If linking wasn't enough of a problem, another major complication of + C++ is that it does not define any sort of standard for binary linking + of libraries. This means that C++ code compiled by different compilers + will not link together properly as libraries nor is the memory layout + of classes and data structures implemented in any kind of portable + manner. In a monolithic C++ program, this problem may be unnoticed. + However, in Perl, it is possible for different extension modules to be + compiled with different C++ compilers. As long as these modules are + self-contained, this probably won't matter. However, if these modules + start sharing data, you will need to take steps to avoid segmentation + faults and other erratic program behavior. Also, be aware that certain + C++ features, especially RTTI, can behave strangely when working with + multiple modules.</P> +<P> It should be noted that you may get a lot of error messages about + the `<TT>bool</TT>' datatype when compiling a C++ Perl module. If you + experience this problem, you can try the following :</P> +<UL> +<LI>Use <TT>-DHAS_BOOL</TT> when compiling the SWIG wrapper code</LI> +<LI>Or use <TT>-Dbool=char</TT> when compiling.</LI> +</UL> +<P> Finally, recent versions of Perl (5.8.0) have namespace conflict + problems. Perl defines a bunch of short macros to make the Perl API + function names shorter. For example, in + /usr/lib/perl/5.8.0/CORE/embed.h there is a line:</P> +<DIV class="code"> +<PRE> +#define do_open Perl_do_open +</PRE> +</DIV> +<P> The problem is, in the <iostream> header from GNU libstdc++v3 there + is a private function named do_open. If <iostream> is included after + the perl headers, then the Perl macro causes the iostream do_open to be + renamed, which causes compile errors. Hopefully in the future Perl will + support a PERL_NO_SHORT_NAMES flag, but for now the only solution is to + undef the macros that conflict. Lib/perl5/noembed.h in the SWIG source + has a list of macros that are known to conflict with either standard + headers or other headers. But if you get macro type conflicts from + other macros not included in Lib/perl5/noembed.h while compiling the + wrapper, you will have to find the macro that conflicts and add an + #undef into the .i file. Please report any conflicting macros you find + to <A href="http://www.swig.org/mail.html">swig-user mailing list</A>.</P> +<H3><A name="Perl5_nn10"></A>28.2.7 Compiling for 64-bit platforms</H3> +<P> On platforms that support 64-bit applications (Solaris, Irix, etc.), + special care is required when building extension modules. On these + machines, 64-bit applications are compiled and linked using a different + set of compiler/linker options. In addition, it is not generally + possible to mix 32-bit and 64-bit code together in the same + application.</P> +<P> To utilize 64-bits, the Perl executable will need to be recompiled + as a 64-bit application. In addition, all libraries, wrapper code, and + every other part of your application will need to be compiled for + 64-bits. If you plan to use other third-party extension modules, they + will also have to be recompiled as 64-bit extensions.</P> +<P> If you are wrapping commercial software for which you have no source + code, you will be forced to use the same linking standard as used by + that software. This may prevent the use of 64-bit extensions. It may + also introduce problems on platforms that support more than one linking + standard (e.g., -o32 and -n32 on Irix).</P> +<H2><A name="Perl5_nn11"></A>28.3 Building Perl Extensions under Windows</H2> +<P> Building a SWIG extension to Perl under Windows is roughly similar + to the process used with Unix. Normally, you will want to produce a DLL + that can be loaded into the Perl interpreter. This section assumes you + are using SWIG with Microsoft Visual C++ although the procedure may be + similar with other compilers.</P> +<H3><A name="Perl5_nn12"></A>28.3.1 Running SWIG from Developer Studio</H3> +<P> If you are developing your application within Microsoft developer + studio, SWIG can be invoked as a custom build option. The process + roughly requires these steps :</P> +<UL> +<LI>Open up a new workspace and use the AppWizard to select a DLL + project.</LI> +<LI>Add both the SWIG interface file (the .i file), any supporting C + files, and the name of the wrapper file that will be created by SWIG + (ie. <TT>example_wrap.c</TT>). Note : If using C++, choose a different + suffix for the wrapper file such as <TT>example_wrap.cxx</TT>. Don't + worry if the wrapper file doesn't exist yet--Developer studio will keep + a reference to it around.</LI> +<LI>Select the SWIG interface file and go to the settings menu. Under + settings, select the "Custom Build" option.</LI> +<LI>Enter "SWIG" in the description field.</LI> +<LI>Enter "<TT>swig -perl5 -o $(ProjDir)\$(InputName)_wrap.cxx + $(InputPath)</TT>" in the "Build command(s) field"</LI> +<LI>Enter "<TT>$(ProjDir)\$(InputName)_wrap.c</TT>xx" in the "Output + files(s) field".</LI> +<LI>Next, select the settings for the entire project and go to + "C++:Preprocessor". Add the include directories for your Perl 5 + installation under "Additional include directories".</LI> +<LI>Define the symbols WIN32 and MSWIN32 under preprocessor options. If + using the ActiveWare port, also define the symbol PERL_OBJECT. Note + that all extensions to the ActiveWare port must be compiled with the + C++ compiler since Perl has been encapsulated in a C++ class.</LI> +<LI>Finally, select the settings for the entire project and go to "Link + Options". Add the Perl library file to your link libraries. For example + "perl.lib". Also, set the name of the output file to match the name of + your Perl module (ie. example.dll).</LI> +<LI>Build your project.</LI> +</UL> +<P> Now, assuming you made it this far, SWIG will be automatically + invoked when you build your project. Any changes made to the interface + file will result in SWIG being automatically invoked to produce a new + version of the wrapper file. To run your new Perl extension, simply run + Perl and use the use command as normal. For example :</P> +<DIV class="targetlang"> +<PRE> +DOS > perl +use example; +$a = example::fact(4); +print "$a\n"; + +</PRE> +</DIV> +<H3><A name="Perl5_nn13"></A>28.3.2 Using other compilers</H3> +<P> SWIG is known to work with Cygwin and may work with other compilers + on Windows. For general hints and suggestions refer to the <A href="#Windows"> +Windows</A> chapter.</P> +<H2><A name="Perl5_nn14"></A>28.4 The low-level interface</H2> +<P> At its core, the Perl module uses a simple low-level interface to C + function, variables, constants, and classes. This low-level interface + can be used to control your application. However, it is also used to + construct more user-friendly proxy classes as described in the next + section.</P> +<H3><A name="Perl5_nn15"></A>28.4.1 Functions</H3> +<P> C functions are converted into new Perl built-in commands (or + subroutines). For example:</P> +<DIV class="targetlang"> +<PRE> +%module example +int fact(int a); +... +</PRE> +</DIV> +<P> Now, in Perl:</P> +<DIV class="targetlang"> +<PRE> +use example; +$a = &example::fact(2); +</PRE> +</DIV> +<H3><A name="Perl5_nn16"></A>28.4.2 Global variables</H3> +<P> Global variables are handled using Perl's magic variable mechanism. + SWIG generates a pair of functions that intercept read/write operations + and attaches them to a Perl variable with the same name as the C global + variable. Thus, an interface like this</P> +<DIV class="targetlang"> +<PRE> +%module example; +... +double Spam; +... +</PRE> +</DIV> +<P> is accessed as follows :</P> +<DIV class="targetlang"> +<PRE> +use example; +print $example::Spam,"\n"; +$example::Spam = $example::Spam + 4 +# ... etc ... + +</PRE> +</DIV> +<P> If a variable is declared as <TT>const</TT>, it is wrapped as a + read-only variable. Attempts to modify its value will result in an + error.</P> +<P> To make ordinary variables read-only, you can also use the <TT> +%immutable</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%{ +extern char *path; +%} +%immutable; +extern char *path; +%mutable; +</PRE> +</DIV> +<P> The <TT>%immutable</TT> directive stays in effect until it is + explicitly disabled or cleared using <TT>%mutable</TT>. See the <A href="#SWIG_readonly_variables"> +Creating read-only variables</A> section for further details.</P> +<P> It is also possible to tag a specific variable as read-only like + this:</P> +<DIV class="code"> +<PRE> +%{ +extern char *path; +%} +%immutable path; +... +... +extern char *path; // Declared later in the input +</PRE> +</DIV> +<H3><A name="Perl5_nn17"></A>28.4.3 Constants</H3> +<P> By default, constants are wrapped as read-only Perl variables. For + example:</P> +<DIV class="code"> +<PRE> +%module example + +#define FOO 42 +</PRE> +</DIV> +<P> In Perl:</P> +<DIV class="targetlang"> +<PRE> +use example; +print $example::FOO,"\n"; # OK +$example::FOO = 2; # Error +</PRE> +</DIV> +<P> Alternatively, if you use swig's <TT>-const</TT> option, constants + are wrapped such that the leading $ isn't required (by using a constant + subroutine), which usually gives a more natural Perl interface, for + example:</P> +<DIV class="targetlang"> +<PRE> +use example; +print example::FOO,"\n"; +</PRE> +</DIV> +<H3><A name="Perl5_nn18"></A>28.4.4 Pointers</H3> +<P> SWIG represents pointers as blessed references. A blessed reference + is the same as a Perl reference except that it has additional + information attached to it indicating what kind of reference it is. + That is, if you have a C declaration like this :</P> +<DIV class="code"> +<PRE> +Matrix *new_Matrix(int n, int m); +</PRE> +</DIV> +<P> The module returns a value generated as follows:</P> +<DIV class="targetlang"> +<PRE> +$ptr = new_Matrix(int n, int m); # Save pointer return result +bless $ptr, "p_Matrix"; # Bless it as a pointer to Matrix +</PRE> +</DIV> +<P> SWIG uses the "blessing" to check the datatype of various pointers. + In the event of a mismatch, an error or warning message is generated.</P> +<P> To check to see if a value is the NULL pointer, use the <TT> +defined()</TT> command :</P> +<DIV class="targetlang"> +<PRE> +if (defined($ptr)) { + print "Not a NULL pointer."; +} else { + print "Is a NULL pointer."; +} + +</PRE> +</DIV> +<P> To create a NULL pointer, you should pass the <TT>undef</TT> value + to a function.</P> +<P> The "value" of a Perl reference is not the same as the underlying C + pointer that SWIG wrapper functions return. Suppose that <TT>$a</TT> + and <TT>$b</TT> are two references that point to the same C object. In + general, <TT>$a</TT> and <TT>$b</TT> will be different--since they are + different references. Thus, it is a mistake to check the equality of <TT> +$a</TT> and <TT>$b</TT> to check the equality of two C pointers. The + correct method to check equality of C pointers is to dereference them + as follows :</P> +<DIV class="targetlang"> +<PRE> +if ($$a == $$b) { + print "a and b point to the same thing in C"; +} else { + print "a and b point to different objects."; +} + +</PRE> +</DIV> +<P> As much as you might be inclined to modify a pointer value directly + from Perl, don't. Manipulating pointer values is architecture dependent + and could cause your program to crash. Similarly, don't try to manually + cast a pointer to a new type by reblessing a pointer. This may not work + like you expect and it is particularly dangerous when casting C++ + objects. If you need to cast a pointer or change its value, consider + writing some helper functions instead. For example:</P> +<DIV class="code"> +<PRE> +%inline %{ +/* C-style cast */ +Bar *FooToBar(Foo *f) { + return (Bar *) f; +} + +/* C++-style cast */ +Foo *BarToFoo(Bar *b) { + return dynamic_cast<Foo*>(b); +} + +Foo *IncrFoo(Foo *f, int i) { + return f+i; +} +%} +</PRE> +</DIV> +<P> Also, if working with C++, you should always try to use the new C++ + style casts. For example, in the above code, the C-style cast may + return a bogus result whereas as the C++-style cast will return <TT> +NULL</TT> if the conversion can't be performed.</P> +<P><B> Compatibility Note:</B> In earlier versions, SWIG tried to + preserve the same pointer naming conventions as XS and <TT>xsubpp</TT>. + Given the advancement of the SWIG typesystem and the growing + differences between SWIG and XS, this is no longer supported.</P> +<H3><A name="Perl5_nn19"></A>28.4.5 Structures</H3> +<P> Access to the contents of a structure are provided through a set of + low-level accessor functions as described in the "SWIG Basics" chapter. + For example,</P> +<DIV class="code"> +<PRE> +struct Vector { + double x,y,z; +}; +</PRE> +</DIV> +<P> gets mapped into the following collection of accessor functions:</P> +<DIV class="code"> +<PRE> +struct Vector *new_Vector(); +void delete_Vector(Vector *v); +double Vector_x_get(Vector *obj) +void Vector_x_set(Vector *obj, double x) +double Vector_y_get(Vector *obj) +void Vector_y_set(Vector *obj, double y) +double Vector_z_get(Vector *obj) +void Vector_z_set(Vector *obj, double z) + +</PRE> +</DIV> +<P> These functions are then used to access structure data from Perl as + follows:</P> +<DIV class="targetlang"> +<PRE> +$v = example::new_Vector(); +print example::Vector_x_get($v),"\n"; # Get x component +example::Vector_x_set($v,7.8); # Change x component +</PRE> +</DIV> +<P> Similar access is provided for unions and the data members of C++ + classes.</P> +<P> <TT>const</TT> members of a structure are read-only. Data members + can also be forced to be read-only using the <TT>%immutable</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +struct Foo { + ... + %immutable; + int x; /* Read-only members */ + char *name; + %mutable; + ... +}; +</PRE> +</DIV> +<P> When <TT>char *</TT> members of a structure are wrapped, the + contents are assumed to be dynamically allocated using <TT>malloc</TT> + or <TT>new</TT> (depending on whether or not SWIG is run with the -c++ + option). When the structure member is set, the old contents will be + released and a new value created. If this is not the behavior you want, + you will have to use a typemap (described later).</P> +<P> Array members are normally wrapped as read-only. For example,</P> +<DIV class="code"> +<PRE> +struct Foo { + int x[50]; +}; +</PRE> +</DIV> +<P> produces a single accessor function like this:</P> +<DIV class="code"> +<PRE> +int *Foo_x_get(Foo *self) { + return self->x; +}; +</PRE> +</DIV> +<P> If you want to set an array member, you will need to supply a + "memberin" typemap described later in this chapter. As a special case, + SWIG does generate code to set array members of type <TT>char</TT> + (allowing you to store a Python string in the structure).</P> +<P> When structure members are wrapped, they are handled as pointers. + For example,</P> +<DIV class="code"> +<PRE> +struct Foo { + ... +}; + +struct Bar { + Foo f; +}; +</PRE> +</DIV> +<P> generates accessor functions such as this:</P> +<DIV class="code"> +<PRE> +Foo *Bar_f_get(Bar *b) { + return &b->f; +} + +void Bar_f_set(Bar *b, Foo *val) { + b->f = *val; +} +</PRE> +</DIV> +<H3><A name="Perl5_nn20"></A>28.4.6 C++ classes</H3> +<P> C++ classes are wrapped by building a set of low level accessor + functions. Consider the following class :</P> +<DIV class="code"> +<PRE> +class List { +public: + List(); + ~List(); + int search(char *item); + void insert(char *item); + void remove(char *item); + char *get(int n); + int length; +static void print(List *l); +}; +</PRE> +</DIV> +<P> When wrapped by SWIG, the following functions are created :</P> +<DIV class="code"> +<PRE> +List *new_List(); +void delete_List(List *l); +int List_search(List *l, char *item); +void List_insert(List *l, char *item); +void List_remove(List *l, char *item); +char *List_get(List *l, int n); +int List_length_get(List *l); +void List_length_set(List *l, int n); +void List_print(List *l); + +</PRE> +</DIV> +<P> In Perl, these functions are used in a straightforward manner:</P> +<DIV class="targetlang"> +<PRE> +use example; +$l = example::new_List(); +example::List_insert($l,"Ale"); +example::List_insert($l,"Stout"); +example::List_insert($l,"Lager") +example::List_print($l) +Lager +Stout +Ale +print example::List_length_get($l),"\n"; +3 +</PRE> +</DIV> +<P> At this low level, C++ objects are really just typed pointers. + Member functions are accessed by calling a C-like wrapper with an + instance pointer as the first argument. Although this interface is + fairly primitive, it provides direct access to C++ objects. A higher + level interface using Perl proxy classes can be built using these + low-level accessors. This is described shortly.</P> +<H3><A name="Perl5_nn21"></A>28.4.7 C++ classes and type-checking</H3> +<P> The SWIG type-checker is fully aware of C++ inheritance. Therefore, + if you have classes like this</P> +<DIV class="code"> +<PRE> +class Foo { +... +}; + +class Bar : public Foo { +... +}; +</PRE> +</DIV> +<P> and a function</P> +<DIV class="code"> +<PRE> +void spam(Foo *f); +</PRE> +</DIV> +<P> then the function <TT>spam()</TT> accepts <TT>Foo *</TT> or a + pointer to any class derived from <TT>Foo</TT>. If necessary, the + type-checker also adjusts the value of the pointer (as is necessary + when multiple inheritance is used).</P> +<H3><A name="Perl5_nn22"></A>28.4.8 C++ overloaded functions</H3> +<P> If you have a C++ program with overloaded functions or methods, you + will need to disambiguate those methods using <TT>%rename</TT>. For + example:</P> +<DIV class="code"> +<PRE> +/* Forward renaming declarations */ +%rename(foo_i) foo(int); +%rename(foo_d) foo(double); +... +void foo(int); // Becomes 'foo_i' +void foo(char *c); // Stays 'foo' (not renamed) + +class Spam { +public: + void foo(int); // Becomes 'foo_i' + void foo(double); // Becomes 'foo_d' + ... +}; +</PRE> +</DIV> +<P> Now, in Perl, the methods are accessed as follows:</P> +<DIV class="targetlang"> +<PRE> +use example; +example::foo_i(3); +$s = example::new_Spam(); +example::Spam_foo_i($s,3); +example::Spam_foo_d($s,3.14); +</PRE> +</DIV> +<P> Please refer to the "SWIG Basics" chapter for more information.</P> +<H3><A name="Perl5_nn23"></A>28.4.9 Operators</H3> +<P> As of version 1.3.27 SWIG automatically renames the most common C++ + operators, and maps them into the perl module with the proper 'use + overload ...' so you don't need to do any work.</P> +<P> The following C++ operators are currently supported by the Perl + module:</P> +<UL> +<LI>operator++</LI> +<LI>operator--</LI> +<LI>operator+</LI> +<LI>operator-</LI> +<LI>operator*</LI> +<LI>operator/</LI> +<LI>operator==</LI> +<LI>operator!=</LI> +<LI>operator%</LI> +<LI>operator></LI> +<LI>operator<</LI> +<LI>operator and</LI> +<LI>operator or</LI> +</UL> +<H3><A name="Perl5_nn24"></A>28.4.10 Modules and packages</H3> +<P> When you create a SWIG extension, everything gets placed into a + single Perl module. The name of the module is determined by the <TT> +%module</TT> directive. To use the module, do the following :</P> +<DIV class="targetlang"> +<PRE> +% perl5 +use example; # load the example module +print example::fact(4),"\n" # Call a function in it +24 +</PRE> +</DIV> +<P> Usually, a module consists of a collection of code that is contained + within a single file. A package, on the other hand, is the Perl + equivalent of a namespace. A package is a lot like a module, except + that it is independent of files. Any number of files may be part of the + same package--or a package may be broken up into a collection of + modules if you prefer to think about it in this way.</P> +<P> SWIG installs its functions into a package with the same name as the + module.</P> +<P><B> Incompatible Change:</B> previous versions of SWIG enabled you to + change the name of the package by using the -package option, this + feature has been removed in order to properly support modules that used + nested namespaces, e.g. Foo::Bar::Baz. To give your module a nested + namespace simply provide the fully qualified name in your %module + directive:</P> +<DIV class="code"> +<PRE> +%module "Foo::Bar::Baz" +</PRE> +</DIV> +<P><B> NOTE:</B> the double quotes are necessary.</P> +<P> Using the <TT>package</TT> option of the <TT>%module</TT> directive + allows you to specify what Perl namespace that the module will be + living in when installed. This is useful in the situation where a + module maintainer wants to split a large module into smaller pieces to + make maintenance easier, but doesn't want to have that affect the + module name used by applications. So for example, if I wanted to split <TT> +XML::Xerces</TT> into <TT>XML::Xerces::SAX</TT>, etc. , but I wanted all + the applications to be able to access the classes using the <TT> +XML::Xerces</TT> namespace I could use:</P> +<DIV class="code"> +<PRE> +%module(package="XML::Xerces") "XML::Xerces::SAX +</PRE> +</DIV> +<P> And now all the applications could use the class <TT> +XML::Xerces::SAXParser</TT>. Without the <TT>package</TT> directive + splitting the module would force applications to use the class <TT> +XML::Xerces::SAX::SAXParser</TT>. This could break compatibility for + existing applications that are already using the class under the name <TT> +XML::Xerces::SAXParser</TT>.</P> + +<!-- +<p> +This can be changed by giving SWIG the -package +option : +</p> + +<div class="code"><pre> +% swig -perl -package Foo example.i +</pre></div> + +<p> +In this case, you still create a module called `<tt>example</tt>' exactly as before, but +all of the functions in that module will be installed into the package +`<tt>Foo</tt>.' For example : +</p> + +<div class="targetlang"><pre> +use example; # Load the module like before +print Foo::fact(4),"\n"; # Call a function in package FooBar +</pre></div> +--> +<H2><A name="Perl5_nn25"></A>28.5 Input and output parameters</H2> +<P> A common problem in some C programs is handling parameters passed as + simple pointers. For example:</P> +<DIV class="code"> +<PRE> +void add(int x, int y, int *result) { + *result = x + y; +} +</PRE> +</DIV> +<P> or perhaps</P> +<DIV class="code"> +<PRE> +int sub(int *x, int *y) { + return *x+*y; +} +</PRE> +</DIV> +<P> The easiest way to handle these situations is to use the <TT> +typemaps.i</TT> file. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +void add(int, int, int *OUTPUT); +int sub(int *INPUT, int *INPUT); +</PRE> +</DIV> +<P> In Perl, this allows you to pass simple values. For example:</P> +<DIV class="targetlang"> +<PRE> +$a = example::add(3,4); +print "$a\n"; +7 +$b = example::sub(7,4); +print "$b\n"; +3 +</PRE> +</DIV> +<P> Notice how the <TT>INPUT</TT> parameters allow integer values to be + passed instead of pointers and how the <TT>OUTPUT</TT> parameter + creates a return result.</P> +<P> If you don't want to use the names <TT>INPUT</TT> or <TT>OUTPUT</TT> +, use the <TT>%apply</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +%apply int *OUTPUT { int *result }; +%apply int *INPUT { int *x, int *y}; + +void add(int x, int y, int *result); +int sub(int *x, int *y); +</PRE> +</DIV> +<P> If a function mutates one of its parameters like this,</P> +<DIV class="code"> +<PRE> +void negate(int *x) { + *x = -(*x); +} +</PRE> +</DIV> +<P> you can use <TT>INOUT</TT> like this:</P> +<DIV class="code"> +<PRE> +%include "typemaps.i" +... +void negate(int *INOUT); +</PRE> +</DIV> +<P> In Perl, a mutated parameter shows up as a return value. For + example:</P> +<DIV class="targetlang"> +<PRE> +$a = example::negate(3); +print "$a\n"; +-3 +</PRE> +</DIV> +<P> The most common use of these special typemap rules is to handle + functions that return more than one value. For example, sometimes a + function returns a result as well as a special error code:</P> +<DIV class="code"> +<PRE> +/* send message, return number of bytes sent, along with success code */ +int send_message(char *text, int len, int *success); +</PRE> +</DIV> +<P> To wrap such a function, simply use the <TT>OUTPUT</TT> rule above. + For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +%apply int *OUTPUT { int *success }; +... +int send_message(char *text, int *success); +</PRE> +</DIV> +<P> When used in Perl, the function will return multiple values.</P> +<DIV class="targetlang"> +<PRE> +($bytes, $success) = example::send_message("Hello World"); +</PRE> +</DIV> +<P> Another common use of multiple return values are in query functions. + For example:</P> +<DIV class="code"> +<PRE> +void get_dimensions(Matrix *m, int *rows, int *columns); +</PRE> +</DIV> +<P> To wrap this, you might use the following:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +%apply int *OUTPUT { int *rows, int *columns }; +... +void get_dimensions(Matrix *m, int *rows, *columns); +</PRE> +</DIV> +<P> Now, in Perl:</P> +<DIV class="targetlang"> +<PRE> +($r,$c) = example::get_dimensions($m); +</PRE> +</DIV> +<P> In certain cases, it is possible to treat Perl references as C + pointers. To do this, use the <TT>REFERENCE</TT> typemap. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +void add(int x, int y, int *REFERENCE); +</PRE> +</DIV> +<P> In Perl:</P> +<DIV class="targetlang"> +<PRE> +use example; +$c = 0.0; +example::add(3,4,\$c); +print "$c\n"; +7 +</PRE> +</DIV> +<P><B> Note:</B> The <TT>REFERENCE</TT> feature is only currently + supported for numeric types (integers and floating point).</P> +<H2><A name="Perl5_nn26"></A>28.6 Exception handling</H2> +<P> The SWIG <TT>%exception</TT> directive can be used to create a + user-definable exception handler for converting exceptions in your + C/C++ program into Perl exceptions. The chapter on customization + features contains more details, but suppose you have a C++ class like + the following :</P> +<DIV class="code"> +<PRE> +class RangeError {}; // Used for an exception + +class DoubleArray { + private: + int n; + double *ptr; + public: + // Create a new array of fixed size + DoubleArray(int size) { + ptr = new double[size]; + n = size; + } + // Destroy an array + ~DoubleArray() { + delete ptr; + } + // Return the length of the array + int length() { + return n; + } + + // Get an item from the array and perform bounds checking. + double getitem(int i) { + if ((i >= 0) && (i < n)) + return ptr[i]; + else + throw RangeError(); + } + + // Set an item in the array and perform bounds checking. + void setitem(int i, double val) { + if ((i >= 0) && (i < n)) + ptr[i] = val; + else { + throw RangeError(); + } + } + }; +</PRE> +</DIV> +<P> Since several methods in this class can throw an exception for an + out-of-bounds access, you might want to catch this in the Perl + extension by writing the following in an interface file:</P> +<DIV class="code"> +<PRE> +%exception { + try { + $action + } + catch (RangeError) { + croak("Array index out-of-bounds"); + } +} + +class DoubleArray { +... +}; +</PRE> +</DIV> +<P> The exception handling code is inserted directly into generated + wrapper functions. The <TT>$action</TT> variable is replaced with the + C/C++ code being executed by the wrapper. When an exception handler is + defined, errors can be caught and used to gracefully generate a Perl + error instead of forcing the entire program to terminate with an + uncaught error.</P> +<P> As shown, the exception handling code will be added to every wrapper + function. Since this is somewhat inefficient. You might consider + refining the exception handler to only apply to specific methods like + this:</P> +<DIV class="code"> +<PRE> +%exception getitem { + try { + $action + } + catch (RangeError) { + croak("Array index out-of-bounds"); + } +} + +%exception setitem { + try { + $action + } + catch (RangeError) { + croak("Array index out-of-bounds"); + } +} +</PRE> +</DIV> +<P> In this case, the exception handler is only attached to methods and + functions named <TT>getitem</TT> and <TT>setitem</TT>.</P> +<P> If you had a lot of different methods, you can avoid extra typing by + using a macro. For example:</P> +<DIV class="code"> +<PRE> +%define RANGE_ERROR +{ + try { + $action + } + catch (RangeError) { + croak("Array index out-of-bounds"); + } +} +%enddef + +%exception getitem RANGE_ERROR; +%exception setitem RANGE_ERROR; +</PRE> +</DIV> +<P> Since SWIG's exception handling is user-definable, you are not + limited to C++ exception handling. See the chapter on "<A href="#Customization"> +Customization features</A>" for more examples.</P> +<P><B> Compatibility note:</B> In SWIG1.1, exceptions were defined using + the older <TT>%except</TT> directive:</P> +<DIV class="code"> +<PRE> +%except(python) { + try { + $function + } + catch (RangeError) { + croak("Array index out-of-bounds"); + } +} +</PRE> +</DIV> +<P> This is still supported, but it is deprecated. The newer <TT> +%exception</TT> directive provides the same functionality, but it has + additional capabilities that make it more powerful.</P> +<H2><A name="Perl5_nn27"></A>28.7 Remapping datatypes with typemaps</H2> +<P> This section describes how you can modify SWIG's default wrapping + behavior for various C/C++ datatypes using the <TT>%typemap</TT> + directive. This is an advanced topic that assumes familiarity with the + Perl C API as well as the material in the "<A href="#Typemaps">Typemaps</A> +" chapter.</P> +<P> Before proceeding, it should be stressed that typemaps are<EM> not</EM> + a required part of using SWIG---the default wrapping behavior is enough + in most cases. Typemaps are only used if you want to change some aspect + of the primitive C-Perl interface.</P> +<H3><A name="Perl5_nn28"></A>28.7.1 A simple typemap example</H3> +<P> A typemap is nothing more than a code generation rule that is + attached to a specific C datatype. For example, to convert integers + from Perl to C, you might define a typemap like this:</P> +<DIV class="code"> +<PRE> +%module example + +%typemap(in) int { + $1 = (int) SvIV($input); + printf("Received an integer : %d\n", $1); +} +... +%inline %{ +extern int fact(int n); +%} + +</PRE> +</DIV> +<P> Typemaps are always associated with some specific aspect of code + generation. In this case, the "in" method refers to the conversion of + input arguments to C/C++. The datatype <TT>int</TT> is the datatype to + which the typemap will be applied. The supplied C code is used to + convert values. In this code a number of special variable prefaced by a + <TT>$</TT> are used. The <TT>$1</TT> variable is placeholder for a + local variable of type <TT>int</TT>. The <TT>$input</TT> variable is + the input object (usually a <TT>SV *</TT>).</P> +<P> When this example is used in Perl5, it will operate as follows :</P> +<DIV class="targetlang"> +<PRE> +use example; +$n = example::fact(6); +print "$n\n"; +... + +Output : +Received an integer : 6 +720 +</PRE> +</DIV> +<P> The application of a typemap to specific datatypes and argument + names involves more than simple text-matching--typemaps are fully + integrated into the SWIG type-system. When you define a typemap for <TT> +int</TT>, that typemap applies to <TT>int</TT> and qualified variations + such as <TT>const int</TT>. In addition, the typemap system follows <TT> +typedef</TT> declarations. For example:</P> +<DIV class="targetlang"> +<PRE> +%typemap(in) int n { + $1 = (int) SvIV($input); + printf("n = %d\n",$1); +} +%inline %{ +typedef int Integer; +extern int fact(Integer n); // Above typemap is applied +%} +</PRE> +</DIV> +<P> It should be noted that the matching of <TT>typedef</TT> only occurs + in one direction. If you defined a typemap for <TT>Integer</TT>, it is + not applied to arguments of type <TT>int</TT>.</P> +<P> Typemaps can also be defined for groups of consecutive arguments. + For example:</P> +<DIV class="targetlang"> +<PRE> +%typemap(in) (char *str, unsigned len) { + $1 = SvPV($input,$2); +}; + +int count(char c, char *str, unsigned len); +</PRE> +</DIV> +<P> When a multi-argument typemap is defined, the arguments are always + handled as a single Perl object. This allows the function to be used + like this (notice how the length parameter is omitted):</P> +<DIV class="targetlang"> +<PRE> +example::count("e","Hello World"); +1 +>>> +</PRE> +</DIV> +<H3><A name="Perl5_nn29"></A>28.7.2 Perl5 typemaps</H3> +<P> The previous section illustrated an "in" typemap for converting Perl + objects to C. A variety of different typemap methods are defined by the + Perl module. For example, to convert a C integer back into a Perl + object, you might define an "out" typemap like this:</P> +<DIV class="targetlang"> +<PRE> +%typemap(out) int { + $result = sv_newmortal(); + set_setiv($result, (IV) $1); + argvi++; +} +</PRE> +</DIV> +<P> The following typemap methods are available:</P> +<P> <TT>%typemap(in)</TT></P> +<DIV class="indent"> Converts Perl5 object to input function arguments.</DIV> +<P> <TT>%typemap(out)</TT></P> +<DIV class="indent"> Converts function return value to a Perl5 value.</DIV> +<P> <TT>%typemap(varin)</TT></P> +<DIV class="indent"> Converts a Perl5 object to a global variable.</DIV> +<P> <TT>%typemap(varout)</TT></P> +<DIV class="indent"> Converts a global variable to a Perl5 object.</DIV> +<P> <TT>%typemap(freearg)</TT></P> +<DIV class="indent"> Cleans up a function argument after a function call</DIV> +<P> <TT>%typemap(argout)</TT></P> +<DIV class="indent"> Output argument handling</DIV> +<P> <TT>%typemap(ret)</TT></P> +<DIV class="indent"> Clean up return value from a function.</DIV> +<P> <TT>%typemap(memberin)</TT></P> +<DIV class="indent"> Setting of C++ member data (all languages).</DIV> +<P> <TT>%typemap(memberout)</TT></P> +<DIV class="indent"> Return of C++ member data (all languages).</DIV> +<P> <TT>%typemap(check)</TT></P> +<DIV class="indent"> Check value of input parameter.</DIV> +<H3><A name="Perl5_nn30"></A>28.7.3 Typemap variables</H3> +<P> Within typemap code, a number of special variables prefaced with a <TT> +$</TT> may appear. A full list of variables can be found in the "<A href="#Typemaps"> +Typemaps</A>" chapter. This is a list of the most common variables:</P> +<P> <TT>$1</TT></P> +<DIV class="indent"> A C local variable corresponding to the actual type + specified in the <TT>%typemap</TT> directive. For input values, this is + a C local variable that's supposed to hold an argument value. For + output values, this is the raw result that's supposed to be returned to + Perl.</DIV> +<P> <TT>$input</TT></P> +<DIV class="indent"> A Perl object holding the value of an argument of + variable value.</DIV> +<P> <TT>$result</TT></P> +<DIV class="indent"> A Perl object that holds the result to be returned + to Perl.</DIV> +<P> <TT>$1_name</TT></P> +<DIV class="indent"> The parameter name that was matched.</DIV> +<P> <TT>$1_type</TT></P> +<DIV class="indent"> The actual C datatype matched by the typemap.</DIV> +<P> <TT>$1_ltype</TT></P> +<DIV class="indent"> An assignable version of the datatype matched by + the typemap (a type that can appear on the left-hand-side of a C + assignment operation). This type is stripped of qualifiers and may be + an altered version of <TT>$1_type</TT>. All arguments and local + variables in wrapper functions are declared using this type so that + their values can be properly assigned.</DIV> +<P> <TT>$symname</TT></P> +<DIV class="indent"> The Perl name of the wrapper function being + created.</DIV> +<H3><A name="Perl5_nn31"></A>28.7.4 Useful functions</H3> +<P> When writing typemaps, it is necessary to work directly with Perl5 + objects. This, unfortunately, can be a daunting task. Consult the + "perlguts" man-page for all of the really ugly details. A short summary + of commonly used functions is provided here for reference. It should be + stressed that SWIG can be used quite effectively without knowing any of + these details--especially now that there are typemap libraries that can + already been written.</P> +<P><B> Perl Integer Functions</B></P> +<DIV class="code"> +<PRE> +int SvIV(SV *); +void sv_setiv(SV *sv, IV value); +SV *newSViv(IV value); +int SvIOK(SV *); +</PRE> +</DIV> +<P><B> Perl Floating Point Functions</B></P> +<DIV class="code"> +<PRE> +double SvNV(SV *); +void sv_setnv(SV *, double value); +SV *newSVnv(double value); +int SvNOK(SV *); +</PRE> +</DIV> +<P><B> Perl String Functions</B></P> +<DIV class="code"> +<PRE> +char *SvPV(SV *, STRLEN len); +void sv_setpv(SV *, char *val); +void sv_setpvn(SV *, char *val, STRLEN len); +SV *newSVpv(char *value, STRLEN len); +int SvPOK(SV *); +void sv_catpv(SV *, char *); +void sv_catpvn(SV *, char *, STRLEN); +</PRE> +</DIV> +<P><B> Perl References</B></P> +<DIV class="code"> +<PRE> +void sv_setref_pv(SV *, char *, void *ptr); +int sv_isobject(SV *); +SV *SvRV(SV *); +int sv_isa(SV *, char *0; +</PRE> +</DIV> +<H2><A name="Perl5_nn32"></A>28.8 Typemap Examples</H2> +<P> This section includes a few examples of typemaps. For more examples, + you might look at the files "<TT>perl5.swg</TT>" and "<TT>typemaps.i</TT> +" in the SWIG library.</P> +<H3><A name="Perl5_nn33"></A>28.8.1 Converting a Perl5 array to a char + **</H3> +<P> A common problem in many C programs is the processing of command + line arguments, which are usually passed in an array of NULL terminated + strings. The following SWIG interface file allows a Perl5 array + reference to be used as a char ** datatype.</P> +<DIV class="code"> +<PRE> +%module argv + +// This tells SWIG to treat char ** as a special case +%typemap(in) char ** { + AV *tempav; + I32 len; + int i; + SV **tv; + if (!SvROK($input)) + croak("Argument $argnum is not a reference."); + if (SvTYPE(SvRV($input)) != SVt_PVAV) + croak("Argument $argnum is not an array."); + tempav = (AV*)SvRV($input); + len = av_len(tempav); + $1 = (char **) malloc((len+2)*sizeof(char *)); + for (i = 0; i <= len; i++) { + tv = av_fetch(tempav, i, 0); + $1[i] = (char *) SvPV(*tv,PL_na); + } + $1[i] = NULL; +}; + +// This cleans up the char ** array after the function call +%typemap(freearg) char ** { + free($1); +} + +// Creates a new Perl array and places a NULL-terminated char ** into it +%typemap(out) char ** { + AV *myav; + SV **svs; + int i = 0,len = 0; + /* Figure out how many elements we have */ + while ($1[len]) + len++; + svs = (SV **) malloc(len*sizeof(SV *)); + for (i = 0; i < len ; i++) { + svs[i] = sv_newmortal(); + sv_setpv((SV*)svs[i],$1[i]); + }; + myav = av_make(len,svs); + free(svs); + $result = newRV_noinc((SV*)myav); + sv_2mortal($result); + argvi++; +} + +// Now a few test functions +%inline %{ +int print_args(char **argv) { + int i = 0; + while (argv[i]) { + printf("argv[%d] = %s\n", i,argv[i]); + i++; + } + return i; +} + +// Returns a char ** list +char **get_args() { + static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0}; + return &values[0]; +} +%} + +</PRE> +</DIV> +<P> When this module is compiled, the wrapped C functions can be used in + a Perl script as follows :</P> +<DIV class="targetlang"> +<PRE> +use argv; +@a = ("Dave", "Mike", "John", "Mary"); # Create an array of strings +argv::print_args(\@a); # Pass it to our C function +$b = argv::get_args(); # Get array of strings from C +print @$b,"\n"; # Print it out +</PRE> +</DIV> +<H3><A name="Perl5_nn34"></A>28.8.2 Return values</H3> +<P> Return values are placed on the argument stack of each wrapper + function. The current value of the argument stack pointer is contained + in a variable <TT>argvi</TT>. Whenever a new output value is added, it + is critical that this value be incremented. For multiple output values, + the final value of <TT>argvi</TT> should be the total number of output + values.</P> +<P> The total number of return values should not exceed the number of + input values unless you explicitly extend the argument stack. This can + be done using the <TT>EXTEND()</TT> macro as in :</P> +<DIV class="code"> +<PRE> +%typemap(argout) int *OUTPUT { + if (argvi >= items) { + EXTEND(sp,1); /* Extend the stack by 1 object */ + } + $result = sv_newmortal(); + sv_setiv($target,(IV) *($1)); + argvi++; +} +</PRE> +</DIV> +<H3><A name="Perl5_nn35"></A>28.8.3 Returning values from arguments</H3> +<P> Sometimes it is desirable for a function to return a value in one of + its arguments. This example describes the implementation of the <TT> +OUTPUT</TT> typemap.</P> +<DIV class="code"> +<PRE> +%module return + +// This tells SWIG to treat an double * argument with name 'OutDouble' as +// an output value. + +%typemap(argout) double *OUTPUT { + $result = sv_newmortal(); + sv_setnv($result, *$input); + argvi++; /* Increment return count -- important! */ +} + +// We don't care what the input value is. Ignore, but set to a temporary variable + +%typemap(in,numinputs=0) double *OUTPUT(double junk) { + $1 = &junk; +} + +// Now a function to test it +%{ +/* Returns the first two input arguments */ +int multout(double a, double b, double *out1, double *out2) { + *out1 = a; + *out2 = b; + return 0; +}; +%} + +// If we name both parameters OutDouble both will be output + +int multout(double a, double b, double *OUTPUT, double *OUTPUT); +... +</PRE> +</DIV> +<P> When this function is called, the output arguments are appended to + the stack used to return results. This shows up an array in Perl. For + example :</P> +<DIV class="targetlang"> +<PRE> +@r = multout(7,13); +print "multout(7,13) = @r\n"; +($x,$y) = multout(7,13); +</PRE> +</DIV> +<H3><A name="Perl5_nn36"></A>28.8.4 Accessing array structure members</H3> +<P> Consider the following data structure :</P> +<DIV class="code"> +<PRE> +#define SIZE 8 +typedef struct { + int values[SIZE]; + ... +} Foo; + +</PRE> +</DIV> +<P> By default, SWIG doesn't know how to the handle the values structure + member it's an array, not a pointer. In this case, SWIG makes the array + member read-only. Reading will simply return a pointer to the first + item in the array. To make the member writable, a "memberin" typemap + can be used.</P> +<DIV class="code"> +<PRE> +%typemap(memberin) int [SIZE] { + int i; + for (i = 0; i < SIZE; i++) { + $1[i] = $input[i]; + } +} + +</PRE> +</DIV> +<P> Whenever a <TT>int [SIZE]</TT> member is encountered in a structure + or class, this typemap provides a safe mechanism for setting its value.</P> +<P> As in the previous example, the typemap can be generalized for any + dimension. For example:</P> +<DIV class="code"> +<PRE> +%typemap(memberin) int [ANY] { + int i; + for (i = 0; i < $1_dim0; i++) { + $1[i] = $input[i]; + } +} +</PRE> +</DIV> +<P> When setting structure members, the input object is always assumed + to be a C array of values that have already been converted from the + target language. Because of this, the <TT>memberin</TT> typemap is + almost always combined with the use of an "in" typemap. For example, + the "in" typemap in the previous section would be used to convert an <TT> +int[]</TT> array to C whereas the "memberin" typemap would be used to + copy the converted array into a C data structure.</P> +<H3><A name="Perl5_nn37"></A>28.8.5 Turning Perl references into C + pointers</H3> +<P> A frequent confusion on the SWIG mailing list is errors caused by + the mixing of Perl references and C pointers. For example, suppose you + have a C function that modifies its arguments like this :</P> +<DIV class="code"> +<PRE> +void add(double a, double b, double *c) { + *c = a + b; +} +</PRE> +</DIV> +<P> A common misinterpretation of this function is the following Perl + script :</P> +<DIV class="targetlang"> +<PRE> +# Perl script +$a = 3.5; +$b = 7.5; +$c = 0.0; # Output value +add($a,$b,\$c); # Place result in c (Except that it doesn't work) +</PRE> +</DIV> +<P> To make this work with a reference, you can use a typemap such as + this:</P> +<DIV class="code"> +<PRE> +%typemap(in) double * (double dvalue) { + SV* tempsv; + if (!SvROK($input)) { + croak("expected a reference\n"); + } + tempsv = SvRV($input); + if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { + croak("expected a double reference\n"); + } + dvalue = SvNV(tempsv); + $1 = &dvalue; +} + +%typemap(argout) double * { + SV *tempsv; + tempsv = SvRV($input); + sv_setnv(tempsv, *$1); +} +</PRE> +</DIV> +<P> Now, if you place this before the add function, you can do this :</P> +<DIV class="targetlang"> +<PRE> +$a = 3.5; +$b = 7.5; +$c = 0.0; +add($a,$b,\$c); # Now it works! +print "$c\n"; + +</PRE> +</DIV> +<H3><A name="Perl5_nn38"></A>28.8.6 Pointer handling</H3> +<P> Occasionally, it might be necessary to convert pointer values that + have been stored using the SWIG typed-pointer representation. To + convert a pointer from Perl to C, the following function is used:</P> +<P> <TT>int SWIG_ConvertPtr(SV *obj, void **ptr, swig_type_info *ty, int + flags)</TT></P> +<DIV class="indent"> Converts a Perl object <TT>obj</TT> to a C pointer. + The result of the conversion is placed into the pointer located at <TT> +ptr</TT>. <TT>ty</TT> is a SWIG type descriptor structure. <TT>flags</TT> + is used to handle error checking and other aspects of conversion. <TT> +flags</TT> is currently undefined and reserved for future expansion. + Returns 0 on success and -1 on error.</DIV> +<P> <TT>void *SWIG_MakePtr(SV *obj, void *ptr, swig_type_info *ty, int + flags)</TT></P> +<DIV class="indent"> Creates a new Perl pointer object. <TT>obj</TT> is + a Perl SV that has been initialized to hold the result, <TT>ptr</TT> is + the pointer to convert, <TT>ty</TT> is the SWIG type descriptor + structure that describes the type, and <TT>flags</TT> is a flag that + controls properties of the conversion. <TT>flags</TT> is currently + undefined and reserved.</DIV> +<P> Both of these functions require the use of a special SWIG + type-descriptor structure. This structure contains information about + the mangled name of the datatype, type-equivalence information, as well + as information about converting pointer values under C++ inheritance. + For a type of <TT>Foo *</TT>, the type descriptor structure is usually + accessed as follows:</P> +<DIV class="code"> +<PRE> +Foo *f; +if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL; + +SV *sv = sv_newmortal(); +SWIG_MakePtr(sv, f, SWIGTYPE_p_Foo, 0); +</PRE> +</DIV> +<P> In a typemap, the type descriptor should always be accessed using + the special typemap variable <TT>$1_descriptor</TT>. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) Foo * { + if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL; +} +</PRE> +</DIV> +<P> If necessary, the descriptor for any type can be obtained using the <TT> +$descriptor()</TT> macro in a typemap. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) Foo * { + if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL; +} +</PRE> +</DIV> +<H2><A name="Perl5_nn39"></A>28.9 Proxy classes</H2> +<P><B> Out of date. Needs update.</B></P> +<P> Using the low-level procedural interface, SWIG can also construct a + high-level object oriented interface to C structures and C++ classes. + This is done by constructing a Perl proxy class (also known as a shadow + class) that provides an OO wrapper to the underlying code. This section + describes the implementation details of the proxy interface.</P> +<H3><A name="Perl5_nn40"></A>28.9.1 Preliminaries</H3> +<P> Proxy classes, are generated by default. If you want to turn them + off, use the <TT>-noproxy</TT> command line option. For example:</P> +<DIV class="code"> +<PRE> +$ swig -c++ -perl -noproxy example.i +</PRE> +</DIV> +<P> When proxy classes are used, SWIG moves all of the low-level + procedural wrappers to another package name. By default, this package + is named 'modulec' where 'module' is the name of the module you + provided with the <TT>%module</TT> directive. Then, in place of the + original module, SWIG creates a collection of high-level Perl wrappers. + In your scripts, you will use these high level wrappers. The wrappers, + in turn, interact with the low-level procedural module.</P> +<H3><A name="Perl5_nn41"></A>28.9.2 Structure and class wrappers</H3> +<P> Suppose you have the following SWIG interface file :</P> +<DIV class="code"> +<PRE> +%module example +struct Vector { + Vector(double x, double y, double z); + ~Vector(); + double x,y,z; +}; + +</PRE> +</DIV> +<P> When wrapped, SWIG creates the following set of low-level accessor + functions as described in previous sections.</P> +<DIV class="code"> +<PRE> +Vector *new_Vector(double x, double y, double z); +void delete_Vector(Vector *v); +double Vector_x_get(Vector *v); +double Vector_x_set(Vector *v, double value); +double Vector_y_get(Vector *v); +double Vector_y_set(Vector *v, double value); +double Vector_z_get(Vector *v); +double Vector_z_set(Vector *v, double value); + +</PRE> +</DIV> +<P> However, when proxy classes are enabled, these accessor functions + are wrapped inside a Perl class like this:</P> +<DIV class="targetlang"> +<PRE> +package example::Vector; +@ISA = qw( example ); +%OWNER = (); +%BLESSEDMEMBERS = (); + +sub new () { + my $self = shift; + my @args = @_; + $self = vectorc::new_Vector(@args); + return undef if (!defined($self)); + bless $self, "example::Vector"; + $OWNER{$self} = 1; + my %retval; + tie %retval, "example::Vector", $self; + return bless \%retval,"Vector"; +} + +sub DESTROY { + return unless $_[0]->isa('HASH'); + my $self = tied(%{$_[0]}); + delete $ITERATORS{$self}; + if (exists $OWNER{$self}) { + examplec::delete_Vector($self)); + delete $OWNER{$self}; +} + +sub FETCH { + my ($self,$field) = @_; + my $member_func = "vectorc::Vector_${field}_get"; + my $val = &$member_func($self); + if (exists $BLESSEDMEMBERS{$field}) { + return undef if (!defined($val)); + my %retval; + tie %retval,$BLESSEDMEMBERS{$field},$val; + return bless \%retval, $BLESSEDMEMBERS{$field}; + } + return $val; +} + +sub STORE { + my ($self,$field,$newval) = @_; + my $member_func = "vectorc::Vector_${field}_set"; + if (exists $BLESSEDMEMBERS{$field}) { + &$member_func($self,tied(%{$newval})); + } else { + &$member_func($self,$newval); + } +} +</PRE> +</DIV> +<P> Each structure or class is mapped into a Perl package of the same + name. The C++ constructors and destructors are mapped into constructors + and destructors for the package and are always named "new" and + "DESTROY". The constructor always returns a tied hash table. This hash + table is used to access the member variables of a structure in addition + to being able to invoke member functions. The <TT>%OWNER</TT> and <TT> +%BLESSEDMEMBERS</TT> hash tables are used internally and described + shortly.</P> +<P> To use our new proxy class we can simply do the following:</P> +<DIV class="targetlang"> +<PRE> +# Perl code using Vector class +$v = new Vector(2,3,4); +$w = Vector->new(-1,-2,-3); + +# Assignment of a single member +$v->{x} = 7.5; + +# Assignment of all members +%$v = ( x=>3, + y=>9, + z=>-2); + +# Reading members +$x = $v->{x}; + +# Destruction +$v->DESTROY(); + +</PRE> +</DIV> +<H3><A name="Perl5_nn42"></A>28.9.3 Object Ownership</H3> +<P> In order for proxy classes to work properly, it is necessary for + Perl to manage some mechanism of object ownership. Here's the crux of + the problem---suppose you had a function like this :</P> +<DIV class="code"> +<PRE> +Vector *Vector_get(Vector *v, int index) { + return &v[i]; +} +</PRE> +</DIV> +<P> This function takes a Vector pointer and returns a pointer to + another Vector. Such a function might be used to manage arrays or lists + of vectors (in C). Now contrast this function with the constructor for + a Vector object :</P> +<DIV class="code"> +<PRE> +Vector *new_Vector(double x, double y, double z) { + Vector *v; + v = new Vector(x,y,z); // Call C++ constructor + return v; +} +</PRE> +</DIV> +<P> Both functions return a Vector, but the constructor is returning a + brand-new Vector while the other function is returning a Vector that + was already created (hopefully). In Perl, both vectors will be + indistinguishable---clearly a problem considering that we would + probably like the newly created Vector to be destroyed when we are done + with it.</P> +<P> To manage these problems, each class contains two methods that + access an internal hash table called <TT>%OWNER</TT>. This hash keeps a + list of all of the objects that Perl knows that it has created. This + happens in two cases: (1) when the constructor has been called, and (2) + when a function implicitly creates a new object (as is done when SWIG + needs to return a complex datatype by value). When the destructor is + invoked, the Perl proxy class module checks the <TT>%OWNER</TT> hash to + see if Perl created the object. If so, the C/C++ destructor is invoked. + If not, we simply destroy the Perl object and leave the underlying C + object alone (under the assumption that someone else must have created + it).</P> +<P> This scheme works remarkably well in practice but it isn't + foolproof. In fact, it will fail if you create a new C object in Perl, + pass it on to a C function that remembers the object, and then destroy + the corresponding Perl object (this situation turns out to come up + frequently when constructing objects like linked lists and trees). When + C takes possession of an object, you can change Perl's ownership by + simply deleting the object from the <TT>%OWNER</TT> hash. This is done + using the <TT>DISOWN</TT> method.</P> +<DIV class="targetlang"> +<PRE> +# Perl code to change ownership of an object +$v = new Vector(x,y,z); +$v->DISOWN(); +</PRE> +</DIV> +<P> To acquire ownership of an object, the <TT>ACQUIRE</TT> method can + be used.</P> +<DIV class="targetlang"> +<PRE> +# Given Perl ownership of a file +$u = Vector_get($v); +$u->ACQUIRE(); + +</PRE> +</DIV> +<P> As always, a little care is in order. SWIG does not provide + reference counting, garbage collection, or advanced features one might + find in sophisticated languages.</P> +<H3><A name="Perl5_nn43"></A>28.9.4 Nested Objects</H3> +<P> Suppose that we have a new object that looks like this :</P> +<DIV class="code"> +<PRE> +struct Particle { + Vector r; + Vector v; + Vector f; + int type; +} + +</PRE> +</DIV> +<P> In this case, the members of the structure are complex objects that + have already been encapsulated in a Perl proxy class. To handle these + correctly, we use the <TT>%BLESSEDMEMBERS</TT> hash which would look + like this (along with some supporting code) :</P> +<DIV class="targetlang"> +<PRE> +package Particle; +... +%BLESSEDMEMBERS = ( + r => `Vector', + v => `Vector', + f => `Vector', +); + +</PRE> +</DIV> +<P> When fetching members from the structure, <TT>%BLESSEDMEMBERS</TT> + is checked. If the requested field is present, we create a tied-hash + table and return it. If not, we just return the corresponding member + unmodified.</P> +<P> This implementation allows us to operate on nested structures as + follows :</P> +<DIV class="targetlang"> +<PRE> +# Perl access of nested structure +$p = new Particle(); +$p->{f}->{x} = 0.0; +%${$p->{v}} = ( x=>0, y=>0, z=>0); +</PRE> +</DIV> +<H3><A name="Perl5_nn44"></A>28.9.5 Proxy Functions</H3> +<P> When functions take arguments involving a complex object, it is + sometimes necessary to write a proxy function. For example :</P> +<DIV class="code"> +<PRE> +double dot_product(Vector *v1, Vector *v2); +</PRE> +</DIV> +<P> Since Vector is an object already wrapped into a proxy class, we + need to modify this function to accept arguments that are given in the + form of tied hash tables. This is done by creating a Perl function like + this :</P> +<DIV class="targetlang"> +<PRE> +sub dot_product { + my @args = @_; + $args[0] = tied(%{$args[0]}); # Get the real pointer values + $args[1] = tied(%{$args[1]}); + my $result = vectorc::dot_product(@args); + return $result; +} +</PRE> +</DIV> +<P> This function replaces the original function, but operates in an + identical manner.</P> +<H3><A name="Perl5_nn45"></A>28.9.6 Inheritance</H3> +<P> Simple C++ inheritance is handled using the Perl <TT>@ISA</TT> array + in each class package. For example, if you have the following interface + file :</P> +<DIV class="code"> +<PRE> +// shapes.i +// SWIG interface file for shapes class +%module shapes +%{ +#include "shapes.h" +%} + +class Shape { +public: + virtual double area() = 0; + virtual double perimeter() = 0; + void set_location(double x, double y); +}; +class Circle : public Shape { +public: + Circle(double radius); + ~Circle(); + double area(); + double perimeter(); +}; +class Square : public Shape { +public: + Square(double size); + ~Square(); + double area(); + double perimeter(); +} + +</PRE> +</DIV> +<P> The resulting, Perl wrapper class will create the following code :</P> +<DIV class="targetlang"> +<PRE> +Package Shape; +@ISA = (shapes); +... +Package Circle; +@ISA = (shapes Shape); +... +Package Square; +@ISA = (shapes Shape); + +</PRE> +</DIV> +<P> The <TT>@ISA</TT> array determines where to look for methods of a + particular class. In this case, both the <TT>Circle</TT> and <TT>Square</TT> + classes inherit functions from <TT>Shape</TT> so we'll want to look in + the <TT>Shape</TT> base class for them. All classes also inherit from + the top-level module <TT>shapes</TT>. This is because certain common + operations needed to implement proxy classes are implemented only once + and reused in the wrapper code for various classes and structures.</P> +<P> Since SWIG proxy classes are implemented in Perl, it is easy to + subclass from any SWIG generated class. To do this, simply put the name + of a SWIG class in the <TT>@ISA</TT> array for your new class. However, + be forewarned that this is not a trivial problem. In particular, + inheritance of data members is extremely tricky (and I'm not even sure + if it really works).</P> +<H3><A name="Perl5_nn46"></A>28.9.7 Modifying the proxy methods</H3> +<P> It is possible to override the SWIG generated proxy/shadow methods, + using <TT>%feature("shadow")</TT>. It works like all the other <A href="#features"> +%feature directives</A>. Here is a simple example showing how to add + some Perl debug code to the constructor:</P> +<DIV class="targetlang"> +<PRE> +/* Let's make the constructor of the class Square more verbose */ +%feature("shadow") Square(double w) +%{ + sub new { + my $pkg = shift; + my $self = examplec::new_Square(@_); + print STDERR "Constructed an @{[ref($self)]}\n"; + bless $self, $pkg if defined($self); + } +%} + +class Square { +public: + Square(double w); + ... +}; +</PRE> +</DIV> +<H2><A name="Perl5_nn47"></A>28.10 Adding additional Perl code</H2> +<P> If writing support code in C isn't enough, it is also possible to + write code in Perl. This code gets inserted in to the <TT>.pm</TT> file + created by SWIG. One use of Perl code might be to supply a high-level + interface to certain functions. For example:</P> +<DIV class="code"> +<PRE> +void set_transform(Image *im, double x[4][4]); + +... +/* Rewrite the high level interface to set_transform */ +%perlcode %{ +sub set_transform +{ + my ($im, $x) = @_; + my $a = new_mat44(); + for (my $i = 0; $i < 4, $i++) + { + for (my $j = 0; $j < 4, $j++) + { + mat44_set($a, $i, $j, $x->[i][j]) + } + } + example.set_transform($im, $a); + free_mat44($a); +} +%} +</PRE> +</DIV> +<P> In this example, <TT>set_transform()</TT> provides a high-level Perl + interface built on top of low-level helper functions. For example, this + code now seems to work:</P> +<DIV class="targetlang"> +<PRE> +my $a = + [[1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1]]; +set_transform($im, $a); +</PRE> +</DIV><HR NOSHADE> + +<!-- Hand crafted HTML --> +<H1><A name="Php"></A>29 SWIG and PHP</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Php_nn1">Generating PHP Extensions</A> +<UL> +<LI><A href="#Php_nn1_1">Building a loadable extension</A></LI> +<LI><A href="#Php_nn1_3">Using PHP Extensions</A></LI> +</UL> +</LI> +<LI><A href="#Php_nn2">Basic PHP interface</A> +<UL> +<LI><A href="#Php_nn2_1">Constants</A></LI> +<LI><A href="#Php_nn2_2">Global Variables</A></LI> +<LI><A href="#Php_nn2_3">Functions</A></LI> +<LI><A href="#Php_nn2_4">Overloading</A></LI> +<LI><A href="#Php_nn2_5">Pointers and References</A></LI> +<LI><A href="#Php_nn2_6">Structures and C++ classes</A> +<UL> +<LI><A href="#Php_nn2_6_1">Using <TT>-noproxy</TT></A></LI> +<LI><A href="#Php_nn2_6_2">Constructors and Destructors</A></LI> +<LI><A href="#Php_nn2_6_3">Static Member Variables</A></LI> +<LI><A href="#Php_nn2_6_4">Static Member Functions</A></LI> +</UL> +</LI> +<LI><A href="#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</A></LI> +</UL> +</LI> +<LI><A href="#Php_nn3">Cross language polymorphism</A> +<UL> +<LI><A href="#Php_nn3_1">Enabling directors</A></LI> +<LI><A href="#Php_nn3_2">Director classes</A></LI> +<LI><A href="#Php_nn3_3">Ownership and object destruction</A></LI> +<LI><A href="#Php_nn3_4">Exception unrolling</A></LI> +<LI><A href="#Php_nn3_5">Overhead and code bloat</A></LI> +<LI><A href="#Php_nn3_6">Typemaps</A></LI> +<LI><A href="#Php_nn3_7">Miscellaneous</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> SWIG supports generating wrappers for PHP5. Support for PHP4 has + been removed as of SWIG 1.3.37. The PHP developers are no longer making + new PHP4 releases, and won't even be patching critical security issues + after 2008-08-08, so it doesn't make much sense for SWIG to continue to + support PHP4 at this point. If you need to continue to use PHP4, stick + with SWIG 1.3.36.</P> +<P> In this chapter, we discuss SWIG's support of PHP. The PHP module + was extensively rewritten in release 1.3.26, and support for generating + OO wrappers for PHP5 was added in 1.3.30. The PHP module works fairly + well, but currently does not implement all the features available in + some of the other languages.</P> +<P> In order to use this module, you will need to have a copy of the + PHP5 include files to compile the SWIG generated files. If you + installed PHP from a binary package, you may need to install a + "php-dev" or "php-devel" package for these to be installed. You can + find out where these files are by running <TT>php-config --includes</TT> +. To use the built PHP module you will need either the php binary or the + Apache php module. If you want to build your extension into php + directly, you will need the complete PHP source tree available.</P> +<H2><A name="Php_nn1"></A>29.1 Generating PHP Extensions</H2> +<P> To build a PHP extension, run swig using the <TT>-php</TT> option as + follows:</P> +<DIV class="code"> +<PRE> +swig -php example.i +</PRE> +</DIV> +<P> This will produce 3 files example_wrap.c, php_example.h and + example.php. The first file, <TT>example_wrap.c</TT> contains all of + the C code needed to build a PHP extension. The second file, <TT> +php_example.h</TT> contains the header information needed if you wish to + statically link the extension into the php interpreter. The third file, + <TT>example.php</TT> can be included by PHP scripts. It attempts to + dynamically load the extension and contains extra php code specified in + the interface file. If wrapping C++ code with PHP classes, it will also + contain PHP5 class wrappers.</P> +<P> Swig can generate PHP extensions from C++ libraries as well when + given the <TT>-c++</TT> option. The support for C++ is discussed in + more detail in <A href="#Php_nn2_6">section 27.2.6</A>.</P> +<P> The usual (and recommended) way is to build the extension as a + separate dynamically loaded module (which is supported by all modern + operating systems). You can then specify that this be loaded + automatically in <TT>php.ini</TT> or load it explicitly for any script + which needs it.</P> +<P> It is also possible to rebuild PHP from source so that your module + is statically linked into the php executable/library. This is a lot + more work, and also requires a full rebuild of PHP to update your + module, and it doesn't play nicely with package system. We don't + recommend this approach, or provide explicit support for it.</P> +<H3><A name="Php_nn1_1"></A>29.1.1 Building a loadable extension</H3> +<P> To build your module as a dynamically loadable extension, use + compilation commands like these (if you aren't using GCC, the commands + will be different, and there may be some variation between platforms - + these commands should at least work for Linux though):</P> +<DIV class="code"> +<PRE> + gcc `php-config --includes` -fpic -c example_wrap.c + gcc -shared example_wrap.o -o example.so +</PRE> +</DIV> +<H3><A name="Php_nn1_3"></A>29.1.2 Using PHP Extensions</H3> +<P> To test the extension from a PHP script, you need to load it first. + You can load it for every script by adding this line the <TT>[PHP]</TT> + section of <TT>php.ini</TT>:</P> +<DIV class="code"> +<PRE> + extension=/path/to/modulename.so +</PRE> +</DIV> +<P> Alternatively, you can load it explicitly only for scripts which + need it by adding this line:</P> +<DIV class="code"> +<PRE> + dl("/path/to/modulename.so"); // Load the module +</PRE> +</DIV> +<P> to the start of each PHP file. SWIG also generates a php module, + which attempts to do the <TT>dl()</TT> call for you:</P> +<DIV class="code"> +<PRE> + include("example.php"); +</PRE> +</DIV> +<H2><A name="Php_nn2"></A>29.2 Basic PHP interface</H2> +<P> It is important to understand that PHP uses a single global + namespace into which all symbols from extension modules are loaded. It + is quite possible for names of symbols in one extension module to clash + with other symbols unless care is taken to <TT>%rename</TT> them.</P> +<H3><A name="Php_nn2_1"></A>29.2.1 Constants</H3> +<P> These work in much the same way as in C/C++, constants can be + defined by using either the normal C pre-processor declarations, or the + <TT>%constant</TT> SWIG directive. These will then be available from + your PHP script as a PHP constant, (i.e. no dollar sign is needed to + access them.) For example, with a swig interface file like this,</P> +<DIV class="code"> +<PRE> +%module example + +#define PI 3.14159 + +%constant int E = 2.71828 +</PRE> +</DIV> +<P> you can access the constants in your php script like this,</P> +<DIV class="code"> +<PRE> +include("example.php"); + +echo "PI = " . PI . "\n"; + +echo "E = " . E . "\n"; + +</PRE> +</DIV> +<P> There are two peculiarities with using constants in PHP. The first + is that if you try to use an undeclared constant, it will evaluate to a + string set to the constant's name. For example,</P> +<DIV class="code"> +<PRE> +%module example + +#define EASY_TO_MISPELL 0 +</PRE> +</DIV> +<P> accessed incorrectly in PHP,</P> +<DIV class="code"> +<PRE> +include("example.php"); + +if(EASY_TO_MISPEL) { + .... +} else { + .... +} + +</PRE> +</DIV> +<P> will issue a warning about the undeclared constant, but will then + evaluate it and turn it into a string ('EASY_TO_MISPEL'), which + evaluates to true, rather than the value of the constant which would be + false. This is a feature!</P> +<P> The second 'feature' is that although constants are case sensitive + (by default), you cannot declare a constant twice with alternative + cases. E.g.,</P> +<DIV class="code"> +<PRE> +%module example + +#define TEST Hello +#define Test World +</PRE> +</DIV> +<P> accessed from PHP,</P> +<DIV class="code"> +<PRE> +include("example.php"); + +echo TEST, Test; +</PRE> +</DIV> +<P> will output "Hello Test" rather than "Hello World". This is because + internally, all constants are stored in a hash table by their lower + case name, so 'TEST' and 'Test' will map to the same hash element + ('Test'). But, because we declared them case sensitive, the Zend engine + will test if the case matches with the case the constant was declared + with first.</P> +<P> So, in the example above, the TEST constant was declared first, and + will be stored under the hash element 'test'. The 'Test' constant will + also map to the same hash element 'test', but will not overwrite it. + When called from the script, the TEST constant will again be mapped to + the hash element 'test' so the constant will be retrieved. The case + will then be checked, and will match up, so the value ('Hello') will be + returned. When 'Test' is evaluated, it will also map to the same hash + element 'test'. The same constant will be retrieved, this time though + the case check will fail as 'Test' != 'TEST'. So PHP will assume that + Test is a undeclared constant, and as explained above, will return it + as a string set to the constant name ('Test'). Hence the script above + will print 'Hello Test'. If they were declared non-case sensitive, the + output would be 'Hello Hello', as both point to the same value, without + the case test taking place. ( Apologies, this paragraph needs rewriting + to make some sense. )</P> +<H3><A name="Php_nn2_2"></A>29.2.2 Global Variables</H3> +<P> Because PHP does not provide a mechanism to intercept access and + assignment of global variables, global variables are supported through + the use of automatically generated accessor functions.</P> +<DIV class="code"> +<PRE> +%module example; + +%inline %{ + double seki = 2; + void print_seki() { + zend_printf("seki is now %f\n",seki); + } +%} +</PRE> +</DIV> +<P> is accessed as follows:</P> +<DIV class="code"> +<PRE> +include("example.php"); +print seki_get(); +seki_set( seki_get() * 2); # The C variable is now 4. +print seki_get(); +</PRE> +</DIV> +<P> SWIG supports global variables of all C datatypes including pointers + and complex objects. Additional types can be supported by using the <TT> +varinit</TT> typemap.</P> +<P> SWIG honors the <TT>%immutable</TT> modifier by not generating code + for the <TT>_set</TT> method. This provides read-only access to the + variable from the php script. Attempting to access the <TT>_set</TT> + method will result in a php fatal error because the function is + undefined.</P> +<P> At this time SWIG does not support custom accessor methods.</P> +<H3><A name="Php_nn2_3"></A>29.2.3 Functions</H3> +<P> C functions are converted into PHP functions. Default/optional + arguments are also allowed. An interface file like this :</P> +<DIV class="code"> +<PRE> +%module example +int foo(int a); +double bar(double, double b = 3.0); +... +</PRE> +</DIV> +<P> Will be accessed in PHP like this :</P> +<DIV class="code"> +<PRE> +include("example.php"); +$a = foo(2); +$b = bar(3.5, -1.5); +$c = bar(3.5); # Use default argument for 2nd parameter + +</PRE> +</DIV> +<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality +<p> +Because PHP is a dynamically typed language, the default typemaps +used for simple types will attempt to coerce the arguments into the appropriate type. That is the following invocations are equivalent: +</p> + +<div class="code"><pre> +$a = foo(2); +$a = foo("2"); +$a = foo(2.0); +</pre></div> + +<p> +Functions are invoked using pass by value semantics like all of PHP. +This means the conversion which automatically takes place when +invoking a swig wrapped method does not change the native type of the +argument variable. +</p> +<div class="code"><pre> +$s = "2 A string representing two"; +$a = foo($s); # invokes 'foo(2)'; +print $s; # The value of $s was not changed. +</pre></div> +--> +<H3><A name="Php_nn2_4"></A>29.2.4 Overloading</H3> +<P> Although PHP does not support overloading functions natively, swig + will generate dispatch functions which will use <TT>%typecheck</TT> + typemaps to allow overloading. This dispatch function's operation and + precedence is described in <A href="#SWIGPlus_overloaded_methods"> +Wrapping Overloaded Functions and Methods</A>.</P> + +<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality +<p> +Because PHP is a dynamically typed language, simple values can be +silently converted from one type to another. For example, integers, +doubles and strings silently convert to each other depending on +context. This situation make overloading slightly problematic because +given the following function: +</p> + +<div class="code"><pre> +void doit( int i ); +void doit( double i ); +</pre></div> + +<p> +it is questionable which to invoke when <tt>doit("2");</tt> is used in +PHP. The string <tt>"2"</tt> simultaneously represents the integer +<tt>2</tt> and the double <tt>2.0</tt>. +</p> + +<p> +In order to provide the most natural experience to PHP programmers, +the default <tt>%typecheck</tt> implemented in <tt>php.swg</tt> +allows any simple type (integer, double, string) in PHP to be used for +any simple C type (int, double, char *). The function selected then +depends only on the argument type precedence defined by SWIG. +</p> + +<p> +It should be noted that <tt>SWIGTYPE</tt> references and pointers will +not be silently converted. So these two functions: +</p> + +<div class="code"><pre> +void doit( const Vector & ); +void doit( int i ); +</pre></div> + +<p> +Cause less confusion and <tt>doit("2");</tt> will invoke the function +taking the integer argument. +</p> +--> +<H3><A name="Php_nn2_5"></A>29.2.5 Pointers and References</H3> +<P> Pointers to C/C++ objects are represented as PHP resources, rather + like MySQL connection handles.</P> +<P> There are multiple ways to wrap pointers to simple types. Given the + following C method:</P> +<DIV class="code"> +<PRE> + void add( int *in1, int *in2, int *result); +</PRE> +</DIV> +<P> One can include<B> cpointer.i</B> to generate PHP wrappers to <TT> +int *</TT>.</P> +<DIV class="code"> +<PRE> +%module example +%include "cpointer.i" +%pointer_functions(int,intp) + +void add( int *in1, int *in2, int *result); +</PRE> +</DIV> +<P> This will result in the following usage in PHP:</P> +<DIV class="code"> +<PRE> +<?php + +include("example.php"); + +$in1=copy_intp(3); +$in2=copy_intp(5); +$result=new_intp(); + +add( $in1, $in2, $result ); + +echo "The sum " . intp_value($in1) . " + " . intp_value($in2) . " = " . intp_value( $result) . "\n"; +?> +</PRE> +</DIV> +<P> An alternative would be to use the include<B> typemaps.i</B> which + defines named typemaps for INPUT, OUTPUT and INOUT variables. One needs + to either <TT>%apply</TT> the appropriate typemap or adjust the + parameter names as appropriate.</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +void add( int *INPUT, int *INPUT, int *OUTPUT); + +</PRE> +</DIV> +<P> This will result in the following usage in PHP:</P> +<DIV class="code"> +<PRE> +<?php + +include("example.php"); + +$in1 = 3; +$in2 = 5; +$result= add($in1,$in2); # Note using variables for the input is unnecessary. + +echo "The sum $in1 + $in2 = $result\n"; +?> +</PRE> +</DIV> +<P> Because PHP has a native concept of reference, it may seem more + natural to the PHP developer to use references to pass pointers. To + enable this, one needs to include<B> phppointers.i</B> which defines + the named typemap REFERENCE.</P> +<DIV class="code"> +<PRE> +%module example +%include "phppointers.i" + +void add( int *REF, int *REF, int *REF); + +</PRE> +</DIV> +<P> This will result in the following usage in PHP:</P> +<DIV class="code"> +<PRE> +<?php + +include("example.php"); + +$in1 = 3; +$in2 = 5; +$result = 0; +add(&$in1,&$in2,&$result); + +echo "The sum $in1 + $in2 = $result\n"; +?> +</PRE> +</DIV> +<P> It is important to note that a php variable which is NULL when + passed by reference would end up passing a NULL pointer into the + function. In PHP, an unassigned variable (i.e. where the first + reference to the variable is not an assignment) is NULL. In the above + example, if any of the three variables had not been assigned, a NULL + pointer would have been passed into <TT>add</TT>. Depending on the + implementation of the function, this may or may not be a good thing.</P> +<P> We chose to allow passing NULL pointers into functions because that + is sometimes required in C libraries. A NULL pointer can be created in + PHP in a number of ways: by using <TT>unset</TT> on an existing + variable, or assigning <TT>NULL</TT> to a variable.</P> +<H3><A name="Php_nn2_6"></A>29.2.6 Structures and C++ classes</H3> +<P> SWIG defaults to wrapping C++ structs and classes with PHP classes + unless "-noproxy" is specified. For PHP5, a PHP wrapper class is + generated which calls a set of flat functions wrapping the C++ class.</P> +<P> This interface file</P> +<DIV class="code"> +<PRE> +%module vector + +class Vector { +public: + double x,y,z; + Vector(); + ~Vector(); + double magnitude(); +}; + +struct Complex { + double re, im; +}; +</PRE> +</DIV> +<P> Would be used in the following way from PHP5:</P> +<DIV class="code"> +<PRE> +<?php + require "vector.php"; + + $v = new Vector(); + $v->x = 3; + $v->y = 4; + $v->z = 5; + + echo "Magnitude of ($v->x,$v->y,$v->z) = " . $v->magnitude() . "\n"; + + $v = NULL; # destructor called. + + $c = new Complex(); + + $c->re = 0; + $c->im = 0; + + # $c destructor called when $c goes out of scope. +?> +</PRE> +</DIV> +<P> Member variables and methods are accessed using the <TT>-></TT> + operator.</P> +<H4><A name="Php_nn2_6_1"></A>29.2.6.1 Using <TT>-noproxy</TT></H4> +<P> The <TT>-noproxy</TT> option flattens the object structure and + generates collections of named functions (these are the functions which + the PHP5 class wrappers call). The above example results in the + following PHP functions:</P> +<DIV class="code"> +<PRE> +new_Vector(); +Vector_x_set($obj,$d); +Vector_x_get($obj); +Vector_y_set($obj,$d); +Vector_y_get($obj); +Vector_z_set($obj,$d); +Vector_z_get($obj); +Vector_magnitude($obj); +new_Complex(); +Complex_re_set($obj,$d); +Complex_re_get($obj); +Complex_im_set($obj,$d); +Complex_im_get($obj); +</PRE> +</DIV> +<H4><A name="Php_nn2_6_2"></A>29.2.6.2 Constructors and Destructors</H4> +<P> The constructor is called when <TT>new Object()</TT> (or <TT> +new_Object()</TT> if using <TT>-noproxy</TT>) is used to create an + instance of the object. If multiple constructors are defined for an + object, function overloading will be used to determine which + constructor to execute.</P> +<P> Because PHP uses reference counting to manage resources, simple + assignment of one variable to another such as:</P> +<DIV class="code"> +<PRE> +$ref = $v; +</PRE> +</DIV> +<P> causes the symbol <TT>$ref</TT> to refer to the same underlying + object as <TT>$v</TT>. This does not result in a call to the C++ copy + constructor or copy assignment operator.</P> +<P> One can force execution of the copy constructor by using:</P> +<DIV class="code"> +<PRE> +$o_copy = new Object($o); +</PRE> +</DIV> +<P> Destructors are automatically called when all variables referencing + the instance are reassigned or go out of scope. The destructor is not + available to be called manually. To force a destructor to be called the + programmer can either reassign the variable or call <TT>unset($v)</TT></P> +<H4><A name="Php_nn2_6_3"></A>29.2.6.3 Static Member Variables</H4> +<P> Static member variables in C++ are not wrapped as such in PHP as it + does not appear to be possible to intercept accesses to such variables. + Therefore, static member variables are wrapped using a class function + with the same name, which returns the current value of the class + variable. For example</P> +<DIV class="code"> +<PRE> +%module example + +class Ko { + static int threats; +}; + +</PRE> +</DIV> +<P> would be accessed in PHP as,</P> +<DIV class="code"> +<PRE> +include("example.php"); + +echo "There has now been " . Ko::threats() . " threats\n"; + +</PRE> +</DIV> +<P> To set the static member variable, pass the value as the argument to + the class function, e.g.</P> +<DIV class="code"> +<PRE> + +Ko::threats(10); + +echo "There has now been " . Ko::threats() . " threats\n"; + +</PRE> +</DIV> +<H4><A name="Php_nn2_6_4"></A>29.2.6.4 Static Member Functions</H4> +<P> Static member functions are supported in PHP using the <TT> +class::function()</TT> syntax. For example</P> +<DIV class="code"> +<PRE> +%module example +class Ko { + static void threats(); +}; +</PRE> +</DIV> would be executed in PHP as,<DIV class="code"> +<PRE> +include("example.php"); +Ko::threats(); +</PRE> +</DIV> +<H3><A name="Php_nn2_7"></A>29.2.7 PHP Pragmas, Startup and Shutdown + code</H3> +<P> To place PHP code in the generated "example.php" file one can use + the<B> code</B> pragma. The code is inserted after loading the shared + object.</P> +<DIV class="code"> +<PRE> +%module example +%pragma(php) code=" +# This code is inserted into example.php +echo \"example.php execution\\n\"; +" +</PRE> +</DIV> +<P> Results in the following in "example.php"</P> +<DIV class="code"> +<PRE> +# This code is inserted into example.php +echo "example.php execution\n"; +</PRE> +</DIV> +<P> The<B> include</B> pragma is a short cut to add include statements + to the example.php file.</P> +<DIV class="code"> +<PRE> +%module example +%pragma(php) code=" +include \"include.php\"; +" +%pragma(php) include="include.php" // equivalent. +</PRE> +</DIV> +<P> The<B> phpinfo</B> pragma inserts code in the <TT>PHP_MINFO_FUNCTION</TT> + which is called from PHP's phpinfo() function.</P> +<DIV class="code"> +<PRE> +%module example; +%pragma(php) phpinfo=" + zend_printf("An example of PHP support through SWIG\n"); + php_info_print_table_start(); + php_info_print_table_header(2, \"Directive\", \"Value\"); + php_info_print_table_row(2, \"Example support\", \"enabled\"); + php_info_print_table_end(); +" +</PRE> +</DIV> +<P> To insert code into the <TT>PHP_MINIT_FUNCTION</TT>, one can use + either <TT>%init</TT> or <TT>%minit</TT>.</P> +<DIV class="code"> +<PRE> +%module example; +%init { + zend_printf("Inserted into PHP_MINIT_FUNCTION\n"); +} +%minit { + zend_printf("Inserted into PHP_MINIT_FUNCTION\n"); +} +</PRE> +</DIV> +<P> To insert code into the <TT>PHP_MSHUTDOWN_FUNCTION</TT>, one can use + either <TT>%init</TT> or <TT>%minit</TT>.</P> +<DIV class="code"> +<PRE> +%module example; +%mshutdown { + zend_printf("Inserted into PHP_MSHUTDOWN_FUNCTION\n"); +} +</PRE> +</DIV> +<P> The <TT>%rinit</TT> and <TT>%rshutdown</TT> statements insert code + into the request init and shutdown code respectively.</P> +<H2><A name="Php_nn3"></A>29.3 Cross language polymorphism</H2> +<P> Proxy classes provide a more natural, object-oriented way to access + extension classes. As described above, each proxy instance has an + associated C++ instance, and method calls to the proxy are passed to + the C++ instance transparently via C wrapper functions.</P> +<P> This arrangement is asymmetric in the sense that no corresponding + mechanism exists to pass method calls down the inheritance chain from + C++ to PHP. In particular, if a C++ class has been extended in PHP (by + extending the proxy class), these extensions will not be visible from + C++ code. Virtual method calls from C++ are thus not able access the + lowest implementation in the inheritance chain.</P> +<P> Changes have been made to SWIG 1.3.18 to address this problem and + make the relationship between C++ classes and proxy classes more + symmetric. To achieve this goal, new classes called directors are + introduced at the bottom of the C++ inheritance chain. Support for + generating PHP classes has been added in SWIG 1.3.40. The job of the + directors is to route method calls correctly, either to C++ + implementations higher in the inheritance chain or to PHP + implementations lower in the inheritance chain. The upshot is that C++ + classes can be extended in PHP and from C++ these extensions look + exactly like native C++ classes. Neither C++ code nor PHP code needs to + know where a particular method is implemented: the combination of proxy + classes, director classes, and C wrapper functions takes care of all + the cross-language method routing transparently.</P> +<H3><A name="Php_nn3_1"></A>29.3.1 Enabling directors</H3> +<P> The director feature is disabled by default. To use directors you + must make two changes to the interface file. First, add the "directors" + option to the %module directive, like this:</P> +<DIV class="code"> +<PRE> +%module(directors="1") modulename +</PRE> +</DIV> +<P> Without this option no director code will be generated. Second, you + must use the %feature("director") directive to tell SWIG which classes + and methods should get directors. The %feature directive can be applied + globally, to specific classes, and to specific methods, like this:</P> +<DIV class="code"> +<PRE> +// generate directors for all classes that have virtual methods +%feature("director"); + +// generate directors for all virtual methods in class Foo +%feature("director") Foo; + +// generate a director for just Foo::bar() +%feature("director") Foo::bar; +</PRE> +</DIV> +<P> You can use the %feature("nodirector") directive to turn off + directors for specific classes or methods. So for example,</P> +<DIV class="code"> +<PRE> +%feature("director") Foo; +%feature("nodirector") Foo::bar; +</PRE> +</DIV> +<P> will generate directors for all virtual methods of class Foo except + bar().</P> +<P> Directors can also be generated implicitly through inheritance. In + the following, class Bar will get a director class that handles the + methods one() and two() (but not three()):</P> +<DIV class="code"> +<PRE> +%feature("director") Foo; +class Foo { +public: + Foo(int foo); + virtual void one(); + virtual void two(); +}; + +class Bar: public Foo { +public: + virtual void three(); +}; +</PRE> +</DIV> +<P> then at the PHP side you can define</P> +<DIV class="targetlang"> +<PRE> +require("mymodule.php"); + +class MyFoo extends Foo { + function one() { + print "one from php\n"; + } +} +</PRE> +</DIV> +<H3><A name="Php_nn3_2"></A>29.3.2 Director classes</H3> +<P> For each class that has directors enabled, SWIG generates a new + class that derives from both the class in question and a special <TT> +Swig::Director</TT> class. These new classes, referred to as director + classes, can be loosely thought of as the C++ equivalent of the PHP + proxy classes. The director classes store a pointer to their underlying + PHP object. Indeed, this is quite similar to the "_cPtr" and "thisown" + members of the PHP proxy classes.</P> +<P> For simplicity let's ignore the <TT>Swig::Director</TT> class and + refer to the original C++ class as the director's base class. By + default, a director class extends all virtual methods in the + inheritance chain of its base class (see the preceding section for how + to modify this behavior). Thus all virtual method calls, whether they + originate in C++ or in PHP via proxy classes, eventually end up in at + the implementation in the director class. The job of the director + methods is to route these method calls to the appropriate place in the + inheritance chain. By "appropriate place" we mean the method that would + have been called if the C++ base class and its extensions in PHP were + seamlessly integrated. That seamless integration is exactly what the + director classes provide, transparently skipping over all the messy + extension API glue that binds the two languages together.</P> +<P> In reality, the "appropriate place" is one of only two + possibilities: C++ or PHP. Once this decision is made, the rest is + fairly easy. If the correct implementation is in C++, then the lowest + implementation of the method in the C++ inheritance chain is called + explicitly. If the correct implementation is in PHP, the Zend API is + used to call the method of the underlying PHP object (after which the + usual virtual method resolution in PHP automatically finds the right + implementation).</P> +<P> Now how does the director decide which language should handle the + method call? The basic rule is to handle the method in PHP, unless + there's a good reason not to. The reason for this is simple: PHP has + the most "extended" implementation of the method. This assertion is + guaranteed, since at a minimum the PHP proxy class implements the + method. If the method in question has been extended by a class derived + from the proxy class, that extended implementation will execute exactly + as it should. If not, the proxy class will route the method call into a + C wrapper function, expecting that the method will be resolved in C++. + The wrapper will call the virtual method of the C++ instance, and since + the director extends this the call will end up right back in the + director method. Now comes the "good reason not to" part. If the + director method were to blindly call the PHP method again, it would get + stuck in an infinite loop. We avoid this situation by adding special + code to the C wrapper function that tells the director method to not do + this. The C wrapper function compares the called and the declaring + class name of the given method. If these are not the same, then the C + wrapper function tells the director to resolve the method by calling up + the C++ inheritance chain, preventing an infinite loop.</P> +<P> One more point needs to be made about the relationship between + director classes and proxy classes. When a proxy class instance is + created in PHP, SWIG creates an instance of the original C++ class and + assigns it to <TT>->_cPtr</TT>. This is exactly what happens without + directors and is true even if directors are enabled for the particular + class in question. When a class<I> derived</I> from a proxy class is + created, however, SWIG then creates an instance of the corresponding + C++ director class. The reason for this difference is that user-defined + subclasses may override or extend methods of the original class, so the + director class is needed to route calls to these methods correctly. For + unmodified proxy classes, all methods are ultimately implemented in C++ + so there is no need for the extra overhead involved with routing the + calls through PHP.</P> +<H3><A name="Php_nn3_3"></A>29.3.3 Ownership and object destruction</H3> +<P> Memory management issues are slightly more complicated with + directors than for proxy classes alone. PHP instances hold a pointer to + the associated C++ director object, and the director in turn holds a + pointer back to the PHP object. By default, proxy classes own their C++ + director object and take care of deleting it when they are garbage + collected.</P> +<P> This relationship can be reversed by calling the special <TT> +->thisown</TT> property of the proxy class. After setting this property + to <TT>0</TT>, the director class no longer destroys the PHP object. + Assuming no outstanding references to the PHP object remain, the PHP + object will be destroyed at the same time. This is a good thing, since + directors and proxies refer to each other and so must be created and + destroyed together. Destroying one without destroying the other will + likely cause your program to segfault.</P> +<P> Here is an example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + ... +}; +class FooContainer { +public: + void addFoo(Foo *); + ... +}; +</PRE> +</DIV> +<BR><DIV class="targetlang"> +<PRE> +$c = new FooContainer(); +$a = new Foo(); +$a->thisown = 0; +$c->addFoo($a); +</PRE> +</DIV> +<P> In this example, we are assuming that FooContainer will take care of + deleting all the Foo pointers it contains at some point.</P> +<H3><A name="Php_nn3_4"></A>29.3.4 Exception unrolling</H3> +<P> With directors routing method calls to PHP, and proxies routing them + to C++, the handling of exceptions is an important concern. By default, + the directors ignore exceptions that occur during method calls that are + resolved in PHP. To handle such exceptions correctly, it is necessary + to temporarily translate them into C++ exceptions. This can be done + with the %feature("director:except") directive. The following code + should suffice in most cases:</P> +<DIV class="code"> +<PRE> +%feature("director:except") { + if ($error == FAILURE) { + throw Swig::DirectorMethodException(); + } +} +</PRE> +</DIV> +<P> This code will check the PHP error state after each method call from + a director into PHP, and throw a C++ exception if an error occurred. + This exception can be caught in C++ to implement an error handler. + Currently no information about the PHP error is stored in the + Swig::DirectorMethodException object, but this will likely change in + the future.</P> +<P> It may be the case that a method call originates in PHP, travels up + to C++ through a proxy class, and then back into PHP via a director + method. If an exception occurs in PHP at this point, it would be nice + for that exception to find its way back to the original caller. This + can be done by combining a normal %exception directive with the <TT> +director:except</TT> handler shown above. Here is an example of a + suitable exception handler:</P> +<DIV class="code"> +<PRE> +%exception { + try { $action } + catch (Swig::DirectorException &e) { SWIG_fail; } +} +</PRE> +</DIV> +<P> The class Swig::DirectorException used in this example is actually a + base class of Swig::DirectorMethodException, so it will trap this + exception. Because the PHP error state is still set when + Swig::DirectorMethodException is thrown, PHP will register the + exception as soon as the C wrapper function returns.</P> +<H3><A name="Php_nn3_5"></A>29.3.5 Overhead and code bloat</H3> +<P> Enabling directors for a class will generate a new director method + for every virtual method in the class' inheritance chain. This alone + can generate a lot of code bloat for large hierarchies. Method + arguments that require complex conversions to and from target language + types can result in large director methods. For this reason it is + recommended that you selectively enable directors only for specific + classes that are likely to be extended in PHP and used in C++.</P> +<P> Compared to classes that do not use directors, the call routing in + the director methods does add some overhead. In particular, at least + one dynamic cast and one extra function call occurs per method call + from PHP. Relative to the speed of PHP execution this is probably + completely negligible. For worst case routing, a method call that + ultimately resolves in C++ may take one extra detour through PHP in + order to ensure that the method does not have an extended PHP + implementation. This could result in a noticeable overhead in some + cases.</P> +<P> Although directors make it natural to mix native C++ objects with + PHP objects (as director objects) via a common base class pointer, one + should be aware of the obvious fact that method calls to PHP objects + will be much slower than calls to C++ objects. This situation can be + optimized by selectively enabling director methods (using the %feature + directive) for only those methods that are likely to be extended in + PHP.</P> +<H3><A name="Php_nn3_6"></A>29.3.6 Typemaps</H3> +<P> Typemaps for input and output of most of the basic types from + director classes have been written. These are roughly the reverse of + the usual input and output typemaps used by the wrapper code. The + typemap operation names are 'directorin', 'directorout', and + 'directorargout'. The director code does not currently use any of the + other kinds of typemaps. It is not clear at this point which kinds are + appropriate and need to be supported.</P> +<H3><A name="Php_nn3_7"></A>29.3.7 Miscellaneous</H3> +<P> Director typemaps for STL classes are mostly in place, and hence you + should be able to use std::string, etc., as you would any other type.</P> +<HR NOSHADE> +<H1><A name="Pike"></A>30 SWIG and Pike</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Pike_nn2">Preliminaries</A> +<UL> +<LI><A href="#Pike_nn3">Running SWIG</A></LI> +<LI><A href="#Pike_nn4">Getting the right header files</A></LI> +<LI><A href="#Pike_nn5">Using your module</A></LI> +</UL> +</LI> +<LI><A href="#Pike_nn6">Basic C/C++ Mapping</A> +<UL> +<LI><A href="#Pike_nn7">Modules</A></LI> +<LI><A href="#Pike_nn8">Functions</A></LI> +<LI><A href="#Pike_nn9">Global variables</A></LI> +<LI><A href="#Pike_nn10">Constants and enumerated types</A></LI> +<LI><A href="#Pike_nn11">Constructors and Destructors</A></LI> +<LI><A href="#Pike_nn12">Static Members</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P> This chapter describes SWIG support for Pike. As of this writing, + the SWIG Pike module is still under development and is not considered + ready for prime time. The Pike module is being developed against the + Pike 7.4.10 release and may not be compatible with previous versions of + Pike.</P> +<P> This chapter covers most SWIG features, but certain low-level + details are covered in less depth than in earlier chapters. At the very + least, make sure you read the "<A href="#SWIG">SWIG Basics</A>" + chapter. +<BR></P> +<H2><A name="Pike_nn2"></A>30.1 Preliminaries</H2> +<H3><A name="Pike_nn3"></A>30.1.1 Running SWIG</H3> +<P> Suppose that you defined a SWIG module such as the following:</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>%{ +<BR>#include "example.h" +<BR>%} +<BR> +<BR>int fact(int n); +<BR></PRE> +</DIV> +<P> To build a C extension module for Pike, run SWIG using the <TT>-pike</TT> + option :</P> +<DIV class="code"> +<PRE>$ <B>swig -pike example.i</B> +<BR></PRE> +</DIV> +<P> If you're building a C++ extension, be sure to add the <TT>-c++</TT> + option:</P> +<DIV class="code"> +<PRE>$ <B>swig -c++ -pike example.i</B> +<BR></PRE> +</DIV> +<P> This creates a single source file named <TT>example_wrap.c</TT> (or <TT> +example_wrap.cxx</TT>, if you ran SWIG with the <TT>-c++</TT> option). + The SWIG-generated source file contains the low-level wrappers that + need to be compiled and linked with the rest of your C/C++ application + to create an extension module.</P> +<P> The name of the wrapper file is derived from the name of the input + file. For example, if the input file is <TT>example.i</TT>, the name of + the wrapper file is <TT>example_wrap.c</TT>. To change this, you can + use the <TT>-o</TT> option:</P> +<DIV class="code"> +<PRE>$ <B>swig -pike -o pseudonym.c example.i</B> +<BR></PRE> +</DIV> +<H3><A name="Pike_nn4"></A>30.1.2 Getting the right header files</H3> +<P> In order to compile the C/C++ wrappers, the compiler needs to know + the path to the Pike header files. These files are usually contained in + a directory such as</P> +<DIV class="code"> +<PRE>/usr/local/pike/7.4.10/include/pike +<BR></PRE> +</DIV> +<P> There doesn't seem to be any way to get Pike itself to reveal the + location of these files, so you may need to hunt around for them. + You're looking for files with the names <TT>global.h</TT>, <TT> +program.h</TT> and so on.</P> +<H3><A name="Pike_nn5"></A>30.1.3 Using your module</H3> +<P> To use your module, simply use Pike's <TT>import</TT> statement:</P> +<DIV class="code"> +<PRE> +$ <B>pike</B> +Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend) +> <B>import example;</B> +> <B>fact(4);</B> +(1) Result: 24 +</PRE> +</DIV> +<H2><A name="Pike_nn6"></A>30.2 Basic C/C++ Mapping</H2> +<H3><A name="Pike_nn7"></A>30.2.1 Modules</H3> +<P> All of the code for a given SWIG module is wrapped into a single + Pike module. Since the name of the shared library that implements your + module ultimately determines the module's name (as far as Pike is + concerned), SWIG's <TT>%module</TT> directive doesn't really have any + significance.</P> +<H3><A name="Pike_nn8"></A>30.2.2 Functions</H3> +<P> Global functions are wrapped as new Pike built-in functions. For + example,</P> +<DIV class="code"> +<PRE> +%module example + +int fact(int n); +</PRE> +</DIV> +<P> creates a new built-in function <TT>example.fact(n)</TT> that works + exactly as you'd expect it to:</P> +<DIV class="code"> +<PRE> +> <B>import example;</B> +> <B>fact(4);</B> +(1) Result: 24 +</PRE> +</DIV> +<H3><A name="Pike_nn9"></A>30.2.3 Global variables</H3> +<P> Global variables are currently wrapped as a pair of of functions, + one to get the current value of the variable and another to set it. For + example, the declaration</P> +<DIV class="code"> +<PRE> +%module example + +double Foo; +</PRE> +</DIV> +<P> will result in two functions, <TT>Foo_get()</TT> and <TT>Foo_set()</TT> +:</P> +<DIV class="code"> +<PRE> +> <B>import example;</B> +> <B>Foo_get();</B> +(1) Result: 3.000000 +> <B>Foo_set(3.14159);</B> +(2) Result: 0 +> <B>Foo_get();</B> +(3) Result: 3.141590 +</PRE> +</DIV> +<H3><A name="Pike_nn10"></A>30.2.4 Constants and enumerated types</H3> +<P> Enumerated types in C/C++ declarations are wrapped as Pike + constants, not as Pike enums.</P> +<H3><A name="Pike_nn11"></A>30.2.5 Constructors and Destructors</H3> +<P> Constructors are wrapped as <TT>create()</TT> methods, and + destructors are wrapped as <TT>destroy()</TT> methods, for Pike + classes.</P> +<H3><A name="Pike_nn12"></A>30.2.6 Static Members</H3> +<P> Since Pike doesn't support static methods or data for Pike classes, + static member functions in your C++ classes are wrapped as regular + functions and static member variables are wrapped as pairs of functions + (one to get the value of the static member variable, and another to set + it). The names of these functions are prepended with the name of the + class. For example, given this C++ class declaration:</P> +<DIV class="code"> +<PRE> +class Shape +{ +public: + static void print(); + static int nshapes; +}; +</PRE> +</DIV> +<P> SWIG will generate a <TT>Shape_print()</TT> method that invokes the + static <TT>Shape::print()</TT> member function, as well as a pair of + methods, <TT>Shape_nshapes_get()</TT> and <TT>Shape_nshapes_set()</TT>, + to get and set the value of <TT>Shape::nshapes</TT>.</P> +<HR NOSHADE> +<H1><A name="Python"></A>31 SWIG and Python</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Python_nn2">Overview</A></LI> +<LI><A href="#Python_nn3">Preliminaries</A> +<UL> +<LI><A href="#Python_nn4">Running SWIG</A></LI> +<LI><A href="#Python_nn6">Using distutils</A></LI> +<LI><A href="#Python_nn7">Hand compiling a dynamic module</A></LI> +<LI><A href="#Python_nn8">Static linking</A></LI> +<LI><A href="#Python_nn9">Using your module</A></LI> +<LI><A href="#Python_nn10">Compilation of C++ extensions</A></LI> +<LI><A href="#Python_nn11">Compiling for 64-bit platforms</A></LI> +<LI><A href="#Python_nn12">Building Python Extensions under Windows</A></LI> +</UL> +</LI> +<LI><A href="#Python_nn13">A tour of basic C/C++ wrapping</A> +<UL> +<LI><A href="#Python_nn14">Modules</A></LI> +<LI><A href="#Python_nn15">Functions</A></LI> +<LI><A href="#Python_nn16">Global variables</A></LI> +<LI><A href="#Python_nn17">Constants and enums</A></LI> +<LI><A href="#Python_nn18">Pointers</A></LI> +<LI><A href="#Python_nn19">Structures</A></LI> +<LI><A href="#Python_nn20">C++ classes</A></LI> +<LI><A href="#Python_nn21">C++ inheritance</A></LI> +<LI><A href="#Python_nn22">Pointers, references, values, and arrays</A></LI> +<LI><A href="#Python_nn23">C++ overloaded functions</A></LI> +<LI><A href="#Python_nn24">C++ operators</A></LI> +<LI><A href="#Python_nn25">C++ namespaces</A></LI> +<LI><A href="#Python_nn26">C++ templates</A></LI> +<LI><A href="#Python_nn27">C++ Smart Pointers</A></LI> +<LI><A href="#Python_nn27a">C++ Reference Counted Objects (ref/unref)</A> +</LI> +</UL> +</LI> +<LI><A href="#Python_nn28">Further details on the Python class interface</A> +<UL> +<LI><A href="#Python_nn29">Proxy classes</A></LI> +<LI><A href="#Python_nn30">Memory management</A></LI> +<LI><A href="#Python_nn31">Python 2.2 and classic classes</A></LI> +</UL> +</LI> +<LI><A href="#Python_directors">Cross language polymorphism</A> +<UL> +<LI><A href="#Python_nn33">Enabling directors</A></LI> +<LI><A href="#Python_nn34">Director classes</A></LI> +<LI><A href="#Python_nn35">Ownership and object destruction</A></LI> +<LI><A href="#Python_nn36">Exception unrolling</A></LI> +<LI><A href="#Python_nn37">Overhead and code bloat</A></LI> +<LI><A href="#Python_nn38">Typemaps</A></LI> +<LI><A href="#Python_nn39">Miscellaneous</A></LI> +</UL> +</LI> +<LI><A href="#Python_nn40">Common customization features</A> +<UL> +<LI><A href="#Python_nn41">C/C++ helper functions</A></LI> +<LI><A href="#Python_nn42">Adding additional Python code</A></LI> +<LI><A href="#Python_nn43">Class extension with %extend</A></LI> +<LI><A href="#Python_nn44">Exception handling with %exception</A></LI> +</UL> +</LI> +<LI><A href="#Python_nn45">Tips and techniques</A> +<UL> +<LI><A href="#Python_nn46">Input and output parameters</A></LI> +<LI><A href="#Python_nn47">Simple pointers</A></LI> +<LI><A href="#Python_nn48">Unbounded C Arrays</A></LI> +<LI><A href="#Python_nn49">String handling</A></LI> +<LI><A href="#Python_nn50">Arrays</A></LI> +<LI><A href="#Python_nn51">String arrays</A></LI> +<LI><A href="#Python_nn52">STL wrappers</A></LI> +</UL> +</LI> +<LI><A href="#Python_nn53">Typemaps</A> +<UL> +<LI><A href="#Python_nn54">What is a typemap?</A></LI> +<LI><A href="#Python_nn55">Python typemaps</A></LI> +<LI><A href="#Python_nn56">Typemap variables</A></LI> +<LI><A href="#Python_nn57">Useful Python Functions</A></LI> +</UL> +</LI> +<LI><A href="#Python_nn58">Typemap Examples</A> +<UL> +<LI><A href="#Python_nn59">Converting Python list to a char **</A></LI> +<LI><A href="#Python_nn60">Expanding a Python object into multiple + arguments</A></LI> +<LI><A href="#Python_nn61">Using typemaps to return arguments</A></LI> +<LI><A href="#Python_nn62">Mapping Python tuples into small arrays</A></LI> +<LI><A href="#Python_nn63">Mapping sequences to C arrays</A></LI> +<LI><A href="#Python_nn64">Pointer handling</A></LI> +</UL> +</LI> +<LI><A href="#Python_nn65">Docstring Features</A> +<UL> +<LI><A href="#Python_nn66">Module docstring</A></LI> +<LI><A href="#Python_nn67">%feature("autodoc")</A> +<UL> +<LI><A href="#Python_nn68">%feature("autodoc", "0")</A></LI> +<LI><A href="#Python_nn69">%feature("autodoc", "1")</A></LI> +<LI><A href="#Python_nn70">%feature("autodoc", "docstring")</A></LI> +</UL> +</LI> +<LI><A href="#Python_nn71">%feature("docstring")</A></LI> +</UL> +</LI> +<LI><A href="#Python_nn72">Python Packages</A></LI> +<LI><A href="#Python_python3support">Python 3 Support</A> +<UL> +<LI><A href="#Python_nn74">Function annotation</A></LI> +<LI><A href="#Python_nn75">Buffer interface</A></LI> +<LI><A href="#Python_nn76">Abstract base classes</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P><B> Caution: This chapter is under repair!</B></P> +<P> This chapter describes SWIG's support of Python. SWIG is compatible + with most recent Python versions including Python 3.0 and Python 2.6, + as well as older versions dating back to Python 2.0. For the best + results, consider using Python 2.3 or newer.</P> +<P> This chapter covers most SWIG features, but certain low-level + details are covered in less depth than in earlier chapters. At the very + least, make sure you read the "<A href="#SWIG">SWIG Basics</A>" + chapter.</P> +<H2><A name="Python_nn2"></A>31.1 Overview</H2> +<P> To build Python extension modules, SWIG uses a layered approach in + which parts of the extension module are defined in C and other parts + are defined in Python. The C layer contains low-level wrappers whereas + Python code is used to define high-level features.</P> +<P> This layered approach recognizes the fact that certain aspects of + extension building are better accomplished in each language (instead of + trying to do everything in C or C++). Furthermore, by generating code + in both languages, you get a lot more flexibility since you can enhance + the extension module with support code in either language.</P> +<P> In describing the Python interface, this chapter starts by covering + the basics of configuration, compiling, and installing Python modules. + Next, the Python interface to common C and C++ programming features is + described. Advanced customization features such as typemaps are then + described followed by a discussion of low-level implementation details.</P> +<H2><A name="Python_nn3"></A>31.2 Preliminaries</H2> +<H3><A name="Python_nn4"></A>31.2.1 Running SWIG</H3> +<P> Suppose that you defined a SWIG module such as the following:</P> +<DIV class="code"> +<PRE> +/* File: example.i */ +%module example + +%{ +#define SWIG_FILE_WITH_INIT +#include "example.h" +%} + +int fact(int n); +</PRE> +</DIV> +<P> The <TT>#define SWIG_FILE_WITH_INIT</TT> line inserts a macro that + specifies that the resulting C file should be built as a python + extension, inserting the module <TT>init</TT> code. This <TT>.i</TT> + file wraps the following simple C file:</P> +<DIV class="code"> +<PRE> +/* File: example.c */ + +#include "example.h" + +int fact(int n) { + if (n < 0){ /* This should probably return an error, but this is simpler */ + return 0; + } + if (n == 0) { + return 1; + } + else { + /* testing for overflow would be a good idea here */ + return n * fact(n-1); + } +} + +</PRE> +</DIV> +<P> With the header file:</P> +<DIV class="code"> +<PRE> +/* File: example.h */ + +int fact(int n); +</PRE> +</DIV> +<P> To build a Python module, run SWIG using the <TT>-python</TT> + option:</P> +<DIV class="shell"> +<PRE> +$ swig -python example.i +</PRE> +</DIV> +<P> If building a C++ extension, add the <TT>-c++</TT> option:</P> +<DIV class="shell"> +<PRE> +$ swig -c++ -python example.i +</PRE> +</DIV> +<P> This creates two different files; a C/C++ source file <TT> +example_wrap.c</TT> or <TT>example_wrap.cxx</TT> and a Python source + file <TT>example.py</TT>. The generated C source file contains the + low-level wrappers that need to be compiled and linked with the rest of + your C/C++ application to create an extension module. The Python source + file contains high-level support code. This is the file that you will + import to use the module.</P> +<P> The name of the wrapper file is derived from the name of the input + file. For example, if the input file is <TT>example.i</TT>, the name of + the wrapper file is <TT>example_wrap.c</TT>. To change this, you can + use the <TT>-o</TT> option. The name of the Python file is derived from + the module name specified with <TT>%module</TT>. If the module name is <TT> +example</TT>, then a file <TT>example.py</TT> is created.</P> +<P> The following sections have further practical examples and details + on how you might go about compiling and using the generated files.</P> +<H3><A name="Python_nn6"></A>31.2.2 Using distutils</H3> +<P> The preferred approach to building an extension module for python is + to compile it with distutils, which comes with all recent versions of + python (<A href="http://docs.python.org/dist/dist.html">Distutils Docs</A> +).</P> +<P> Distutils takes care of making sure that your extension is built + with all the correct flags, headers, etc. for the version of Python it + is run with. Distutils will compile your extension into a shared object + file or DLL (<TT>.so</TT> on Linux, <TT>.pyd</TT> on Windows, etc). In + addition, distutils can handle installing your package into + site-packages, if that is desired. A configuration file (conventionally + called: <TT>setup.py</TT>) describes the extension (and related python + modules). The distutils will then generate all the right compiler + directives to build it for you.</P> +<P> Here is a sample <TT>setup.py</TT> file for the above example:</P> +<DIV class="code"> +<PRE> +#!/usr/bin/env python + +""" +setup.py file for SWIG example +""" + +from distutils.core import setup, Extension + + +example_module = Extension('_example', + sources=['example_wrap.c', 'example.c'], + ) + +setup (name = 'example', + version = '0.1', + author = "SWIG Docs", + description = """Simple swig example from docs""", + ext_modules = [example_module], + py_modules = ["example"], + ) +</PRE> +</DIV> +<P> In this example, the line: <TT>example_module = Extension(....)</TT> + creates an Extension module object, defining the name as <TT>_example</TT> +, and using the source code files: <TT>example_wrap.c</TT>, generated by + swig, and <TT>example.c</TT>, your original c source. The swig (and + other python extension modules) tradition is for the compiled extension + to have the name of the python portion, prefixed by an underscore. If + the name of your python module is "<TT>example.py</TT>", then the name + of the corresponding object file will be"<TT>_example.so</TT>"</P> +<P> The <TT>setup</TT> call then sets up distutils to build your + package, defining some meta data, and passing in your extension module + object. Once this is saved as <TT>setup.py</TT>, you can build your + extension with these commands:</P> +<DIV class="shell"> +<PRE> +$ swig -python example.i +$ python setup.py build_ext --inplace +</PRE> +</DIV> +<P> And a .so, or .pyd or... will be created for you. It will build a + version that matches the python that you run the command with. Taking + apart the command line:</P> +<UL> +<LI> <TT>python</TT> -- the version of python you want to build for</LI> +<LI> <TT>setup.py</TT> -- the name of your setup script (it can be + called anything, but setup.py is the tradition)</LI> +<LI> <TT>build_ext</TT> -- telling distutils to build extensions</LI> +<LI> <TT>--inplace</TT> -- this tells distutils to put the extension lib + in the current dir. Otherwise, it will put it inside a build hierarchy, + and you'd have to move it to use it.</LI> +</UL> +<P> The distutils have many other features, consult the python distutils + docs for details.</P> +<P> This same approach works on all platforms if the appropriate + compiler is installed. (it can even build extensions to the standard + Windows Python using MingGW)</P> +<H3><A name="Python_nn7"></A>31.2.3 Hand compiling a dynamic module</H3> +<P> While the preferred approach to building an extension module is to + use the distutils, some people like to integrate building extensions + with a larger build system, and thus may wish to compile their modules + without the distutils. To do this, you need to compile your program + using commands like this (shown for Linux):</P> +<DIV class="shell"> +<PRE> +$ swig -python example.i +$ gcc -O2 -fPIC -c example.c +$ gcc -O2 -fPIC -c example_wrap.c -I/usr/local/include/python2.5 +$ gcc -shared example.o example_wrap.o -o _example.so +</PRE> +</DIV> +<P> The exact commands for doing this vary from platform to platform. + However, SWIG tries to guess the right options when it is installed. + Therefore, you may want to start with one of the examples in the <TT> +SWIG/Examples/python</TT> directory. If that doesn't work, you will need + to read the man-pages for your compiler and linker to get the right set + of options. You might also check the <A href="http://www.dabeaz.com/cgi-bin/wiki.pl"> +SWIG Wiki</A> for additional information.</P> +<P> When linking the module,<B> the name of the output file has to match + the name of the module prefixed by an underscore</B>. If the name of + your module is "<TT>example</TT>", then the name of the corresponding + object file should be "<TT>_example.so</TT>" or "<TT>_examplemodule.so</TT> +". The name of the module is specified using the <TT>%module</TT> + directive or the <TT>-module</TT> command line option.</P> +<P><B> Compatibility Note:</B> In SWIG-1.3.13 and earlier releases, + module names did not include the leading underscore. This is because + modules were normally created as C-only extensions without the extra + Python support file (instead, creating Python code was supported as an + optional feature). This has been changed in SWIG-1.3.14 and is + consistent with other Python extension modules. For example, the <TT> +socket</TT> module actually consists of two files; <TT>socket.py</TT> + and <TT>_socket.so</TT>. Many other built-in Python modules follow a + similar convention.</P> +<H3><A name="Python_nn8"></A>31.2.4 Static linking</H3> +<P> An alternative approach to dynamic linking is to rebuild the Python + interpreter with your extension module added to it. In the past, this + approach was sometimes necessary due to limitations in dynamic loading + support on certain machines. However, the situation has improved + greatly over the last few years and you should not consider this + approach unless there is really no other option.</P> +<P> The usual procedure for adding a new module to Python involves + finding the Python source, adding an entry to the <TT>Modules/Setup</TT> + file, and rebuilding the interpreter using the Python Makefile. + However, newer Python versions have changed the build process. You may + need to edit the 'setup.py' file in the Python distribution instead.</P> +<P> In earlier versions of SWIG, the <TT>embed.i</TT> library file could + be used to rebuild the interpreter. For example:</P> +<DIV class="code"> +<PRE> +%module example + +%inline %{ +extern int fact(int); +extern int mod(int, int); +extern double My_variable; +%} + +%include "embed.i" // Include code for a static version of Python + +</PRE> +</DIV> +<P> The <TT>embed.i</TT> library file includes supporting code that + contains everything needed to rebuild Python. To rebuild the + interpreter, you simply do something like this:</P> +<DIV class="shell"> +<PRE> +$ swig -python example.i +$ gcc example.c example_wrap.c \ + -Xlinker -export-dynamic \ + -DHAVE_CONFIG_H -I/usr/local/include/python2.1 \ + -I/usr/local/lib/python2.1/config \ + -L/usr/local/lib/python2.1/config -lpython2.1 -lm -ldl \ + -o mypython + +</PRE> +</DIV> +<P> You will need to supply the same libraries that were used to build + Python the first time. This may include system libraries such as <TT> +-lsocket</TT>, <TT>-lnsl</TT>, and <TT>-lpthread</TT>. Assuming this + actually works, the new version of Python should be identical to the + default version except that your extension module will be a built-in + part of the interpreter.</P> +<P><B> Comment:</B> In practice, you should probably try to avoid static + linking if possible. Some programmers may be inclined to use static + linking in the interest of getting better performance. However, the + performance gained by static linking tends to be rather minimal in most + situations (and quite frankly not worth the extra hassle in the opinion + of this author).</P> +<P><B> Compatibility note:</B> The <TT>embed.i</TT> library file is + deprecated and has not been maintained for several years. Even though + it appears to "work" with Python 2.1, no future support is guaranteed. + If using static linking, you might want to rely on a different approach + (perhaps using distutils).</P> +<H3><A name="Python_nn9"></A>31.2.5 Using your module</H3> +<P> To use your module, simply use the Python <TT>import</TT> statement. + If all goes well, you will be able to this:</P> +<DIV class="targetlang"> +<PRE> +$ python +>>> import example +>>> example.fact(4) +24 +>>> +</PRE> +</DIV> +<P> A common error received by first-time users is the following:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +Traceback (most recent call last): + File "<stdin>", line 1, in ? + File "example.py", line 2, in ? + import _example +ImportError: No module named _example +</PRE> +</DIV> +<P> If you get this message, it means that you either forgot to compile + the wrapper code into an extension module or you didn't give the + extension module the right name. Make sure that you compiled the + wrappers into a module called <TT>_example.so</TT>. And don't forget + the leading underscore (_).</P> +<P> Another possible error is the following:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +Traceback (most recent call last): + File "<stdin>", line 1, in ? +ImportError: dynamic module does not define init function (init_example) +>>> +</PRE> +</DIV> +<P> This error is almost always caused when a bad name is given to the + shared object file. For example, if you created a file <TT>example.so</TT> + instead of <TT>_example.so</TT> you would get this error. + Alternatively, this error could arise if the name of the module is + inconsistent with the module name supplied with the <TT>%module</TT> + directive. Double-check the interface to make sure the module name and + the shared object filename match. Another possible cause of this error + is forgetting to link the SWIG-generated wrapper code with the rest of + your application when creating the extension module.</P> +<P> Another common error is something similar to the following:</P> +<DIV class="targetlang"> +<PRE> +Traceback (most recent call last): + File "example.py", line 3, in ? + import example +ImportError: ./_example.so: undefined symbol: fact +</PRE> +</DIV> +<P> This error usually indicates that you forgot to include some object + files or libraries in the linking of the shared library file. Make sure + you compile both the SWIG wrapper file and your original program into a + shared library file. Make sure you pass all of the required libraries + to the linker.</P> +<P> Sometimes unresolved symbols occur because a wrapper has been + created for a function that doesn't actually exist in a library. This + usually occurs when a header file includes a declaration for a function + that was never actually implemented or it was removed from a library + without updating the header file. To fix this, you can either edit the + SWIG input file to remove the offending declaration or you can use the <TT> +%ignore</TT> directive to ignore the declaration.</P> +<P> Finally, suppose that your extension module is linked with another + library like this:</P> +<DIV class="shell"> +<PRE> +$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib <B>-lfoo</B> \ + -o _example.so +</PRE> +</DIV> +<P> If the <TT>foo</TT> library is compiled as a shared library, you + might encounter the following problem when you try to use your module:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +Traceback (most recent call last): + File "<stdin>", line 1, in ? +ImportError: libfoo.so: cannot open shared object file: No such file or directory +>>> +</PRE> +</DIV> +<P> This error is generated because the dynamic linker can't locate the <TT> +libfoo.so</TT> library. When shared libraries are loaded, the system + normally only checks a few standard locations such as <TT>/usr/lib</TT> + and <TT>/usr/local/lib</TT>. To fix this problem, there are several + things you can do. First, you can recompile your extension module with + extra path information. For example, on Linux you can do this:</P> +<DIV class="shell"> +<PRE> +$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \ + <B>-Xlinker -rpath /home/beazley/projects/lib </B> \ + -o _example.so +</PRE> +</DIV> +<P> Alternatively, you can set the <TT>LD_LIBRARY_PATH</TT> environment + variable to include the directory with your shared libraries. If + setting <TT>LD_LIBRARY_PATH</TT>, be aware that setting this variable + can introduce a noticeable performance impact on all other applications + that you run. To set it only for Python, you might want to do this + instead:</P> +<DIV class="shell"> +<PRE> +$ env LD_LIBRARY_PATH=/home/beazley/projects/lib python +</PRE> +</DIV> +<P> Finally, you can use a command such as <TT>ldconfig</TT> (Linux) or <TT> +crle</TT> (Solaris) to add additional search paths to the default system + configuration (this requires root access and you will need to read the + man pages).</P> +<H3><A name="Python_nn10"></A>31.2.6 Compilation of C++ extensions</H3> +<P> Compilation of C++ extensions has traditionally been a tricky + problem. Since the Python interpreter is written in C, you need to take + steps to make sure C++ is properly initialized and that modules are + compiled correctly. This should be a non-issue if you're using + distutils, as it takes care of all that for you. The following is + included for historical reasons, and in case you need to compile on + your own.</P> +<P> On most machines, C++ extension modules should be linked using the + C++ compiler. For example:</P> +<DIV class="shell"> +<PRE> +$ swig -c++ -python example.i +$ g++ -O2 -fPIC -c example.cxx +$ g++ -O2 -fPIC -c example_wrap.cxx -I/usr/local/include/python2.5 +$ g++ -shared example.o example_wrap.o -o _example.so +</PRE> +</DIV> +<P> The -fPIC option tells GCC to generate position-independent code + (PIC) which is required for most architectures (it's not vital on x86, + but still a good idea as it allows code pages from the library to be + shared between processes). Other compilers may need a different option + specified instead of -fPIC.</P> +<P> In addition to this, you may need to include additional library + files to make it work. For example, if you are using the Sun C++ + compiler on Solaris, you often need to add an extra library <TT>-lCrun</TT> + like this:</P> +<DIV class="shell"> +<PRE> +$ swig -c++ -python example.i +$ CC -c example.cxx +$ CC -c example_wrap.cxx -I/usr/local/include/python2.5 +$ CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o _example.so -lCrun +</PRE> +</DIV> +<P> Of course, the extra libraries to use are completely + non-portable---you will probably need to do some experimentation.</P> +<P> Sometimes people have suggested that it is necessary to relink the + Python interpreter using the C++ compiler to make C++ extension modules + work. In the experience of this author, this has never actually + appeared to be necessary. Relinking the interpreter with C++ really + only includes the special run-time libraries described above---as long + as you link your extension modules with these libraries, it should not + be necessary to rebuild Python.</P> +<P> If you aren't entirely sure about the linking of a C++ extension, + you might look at an existing C++ program. On many Unix machines, the <TT> +ldd</TT> command will list library dependencies. This should give you + some clues about what you might have to include when you link your + extension module. For example:</P> +<DIV class="shell"> +<PRE> +$ ldd swig + libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000) + libm.so.6 => /lib/libm.so.6 (0x4005b000) + libc.so.6 => /lib/libc.so.6 (0x40077000) + /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) +</PRE> +</DIV> +<P> As a final complication, a major weakness of C++ is that it does not + define any sort of standard for binary linking of libraries. This means + that C++ code compiled by different compilers will not link together + properly as libraries nor is the memory layout of classes and data + structures implemented in any kind of portable manner. In a monolithic + C++ program, this problem may be unnoticed. However, in Python, it is + possible for different extension modules to be compiled with different + C++ compilers. As long as these modules are self-contained, this + probably won't matter. However, if these modules start sharing data, + you will need to take steps to avoid segmentation faults and other + erratic program behavior. If working with lots of software components, + you might want to investigate using a more formal standard such as COM.</P> +<H3><A name="Python_nn11"></A>31.2.7 Compiling for 64-bit platforms</H3> +<P> On platforms that support 64-bit applications (Solaris, Irix, etc.), + special care is required when building extension modules. On these + machines, 64-bit applications are compiled and linked using a different + set of compiler/linker options. In addition, it is not generally + possible to mix 32-bit and 64-bit code together in the same + application.</P> +<P> To utilize 64-bits, the Python executable will need to be recompiled + as a 64-bit application. In addition, all libraries, wrapper code, and + every other part of your application will need to be compiled for + 64-bits. If you plan to use other third-party extension modules, they + will also have to be recompiled as 64-bit extensions.</P> +<P> If you are wrapping commercial software for which you have no source + code, you will be forced to use the same linking standard as used by + that software. This may prevent the use of 64-bit extensions. It may + also introduce problems on platforms that support more than one linking + standard (e.g., -o32 and -n32 on Irix).</P> +<P> On the Linux x86_64 platform (Opteron or EM64T), besides of the + required compiler option -fPIC discussed above, you will need to be + careful about the libraries you link with or the library path you use. + In general, a Linux distribution will have two set of libraries, one + for native x86_64 programs (under /usr/lib64), and another for 32 bits + compatibility (under /usr/lib). Also, the compiler options -m32 and + -m64 allow you to choose the desired binary format for your python + extension.</P> +<H3><A name="Python_nn12"></A>31.2.8 Building Python Extensions under + Windows</H3> +<P> Building a SWIG extension to Python under Windows is roughly similar + to the process used with Unix. Using the distutils, it is essentially + identical. If you have the same version of the MS compiler that Python + was built with (the python2.4 and python2.5 distributed by python.org + are built with Visual Studio 2003), the standard <TT>python setup.py + build</TT> should just work.</P> +<P> As of python2.5, the distutils support building extensions with + MingGW out of the box. Following the instruction here: <A href="http://boodebr.org/main/python/build-windows-extensions"> +Building Python extensions for Windows with only free tools</A> should + get you started.</P> +<P> If you need to build it on your own, the following notes are + provided:</P> +<P> You will need to create a DLL that can be loaded into the + interpreter. This section briefly describes the use of SWIG with + Microsoft Visual C++. As a starting point, many of SWIG's examples + include project files. You might want to take a quick look at these in + addition to reading this section.</P> +<P> In Developer Studio, SWIG should be invoked as a custom build + option. This is usually done as follows:</P> +<UL> +<LI>Open up a new workspace and use the AppWizard to select a DLL + project.</LI> +<LI>Add both the SWIG interface file (the .i file), any supporting C + files, and the name of the wrapper file that will be created by SWIG + (ie. <TT>example_wrap.c</TT>). Note : If using C++, choose a different + suffix for the wrapper file such as <TT>example_wrap.cxx</TT>. Don't + worry if the wrapper file doesn't exist yet--Developer Studio keeps a + reference to it.</LI> +<LI>Select the SWIG interface file and go to the settings menu. Under + settings, select the "Custom Build" option.</LI> +<LI>Enter "SWIG" in the description field.</LI> +<LI>Enter "<TT>swig -python -o $(ProjDir)\$(InputName)_wrap.c + $(InputPath)</TT>" in the "Build command(s) field"</LI> +<LI>Enter "<TT>$(ProjDir)\$(InputName)_wrap.c</TT>" in the "Output + files(s) field".</LI> +<LI>Next, select the settings for the entire project and go to + "C++:Preprocessor". Add the include directories for your Python + installation under "Additional include directories".</LI> +<LI>Define the symbol __WIN32__ under preprocessor options.</LI> +<LI>Finally, select the settings for the entire project and go to "Link + Options". Add the Python library file to your link libraries. For + example "python21.lib". Also, set the name of the output file to match + the name of your Python module, ie. _example.pyd - Note that + _example.dll also worked with Python-2.4 and earlier.</LI> +<LI>Build your project.</LI> +</UL> +<P> If all went well, SWIG will be automatically invoked whenever you + build your project. Any changes made to the interface file will result + in SWIG being automatically executed to produce a new version of the + wrapper file.</P> +<P> To run your new Python extension, simply run Python and use the <TT> +import</TT> command as normal. For example :</P> +<DIV class="targetlang"> +<PRE> +$ python +>>> import example +>>> print example.fact(4) +24 +>>> +</PRE> +</DIV> +<P> If you get an <TT>ImportError</TT> exception when importing the + module, you may have forgotten to include additional library files when + you built your module. If you get an access violation or some kind of + general protection fault immediately upon import, you have a more + serious problem. This is often caused by linking your extension module + against the wrong set of Win32 debug or thread libraries. You will have + to fiddle around with the build options of project to try and track + this down.</P> +<P> Some users have reported success in building extension modules using + Cygwin and other compilers. However, the problem of building usable + DLLs with these compilers tends to be rather problematic. For the + latest information, you may want to consult the <A href="http://www.dabeaz.com/cgi-bin/wiki.pl"> + SWIG Wiki</A>.</P> +<H2><A name="Python_nn13"></A>31.3 A tour of basic C/C++ wrapping</H2> +<P> By default, SWIG tries to build a very natural Python interface to + your C/C++ code. Functions are wrapped as functions, classes are + wrapped as classes, and so forth. This section briefly covers the + essential aspects of this wrapping.</P> +<H3><A name="Python_nn14"></A>31.3.1 Modules</H3> +<P> The SWIG <TT>%module</TT> directive specifies the name of the Python + module. If you specify `<TT>%module example</TT>', then everything is + wrapped into a Python '<TT>example</TT>' module. Underneath the covers, + this module consists of a Python source file <TT>example.py</TT> and a + low-level extension module <TT>_example.so</TT>. When choosing a module + name, make sure you don't use the same name as a built-in Python + command or standard module name.</P> +<H3><A name="Python_nn15"></A>31.3.2 Functions</H3> +<P> Global functions are wrapped as new Python built-in functions. For + example,</P> +<DIV class="code"> +<PRE> +%module example +int fact(int n); +</PRE> +</DIV> +<P> creates a built-in function <TT>example.fact(n)</TT> that works + exactly like you think it does:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> print example.fact(4) +24 +>>> +</PRE> +</DIV> +<H3><A name="Python_nn16"></A>31.3.3 Global variables</H3> +<P> C/C++ global variables are fully supported by SWIG. However, the + underlying mechanism is somewhat different than you might expect due to + the way that Python assignment works. When you type the following in + Python</P> +<DIV class="targetlang"> +<PRE> +a = 3.4 +</PRE> +</DIV> +<P> "a" becomes a name for an object containing the value 3.4. If you + later type</P> +<DIV class="targetlang"> +<PRE> +b = a +</PRE> +</DIV> +<P> then "a" and "b" are both names for the object containing the value + 3.4. Thus, there is only one object containing 3.4 and "a" and "b" are + both names that refer to it. This is quite different than C where a + variable name refers to a memory location in which a value is stored + (and assignment copies data into that location). Because of this, there + is no direct way to map variable assignment in C to variable assignment + in Python.</P> +<P> To provide access to C global variables, SWIG creates a special + object called `<TT>cvar</TT>' that is added to each SWIG generated + module. Global variables are then accessed as attributes of this + object. For example, consider this interface</P> +<DIV class="code"> +<PRE> +// SWIG interface file with global variables +%module example +... +%inline %{ +extern int My_variable; +extern double density; +%} +... +</PRE> +</DIV> +<P> Now look at the Python interface:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> # Print out value of a C global variable +>>> print example.cvar.My_variable +4 +>>> # Set the value of a C global variable +>>> example.cvar.density = 0.8442 +>>> # Use in a math operation +>>> example.cvar.density = example.cvar.density*1.10 +</PRE> +</DIV> +<P> If you make an error in variable assignment, you will receive an + error message. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> example.cvar.density = "Hello" +Traceback (most recent call last): + File "<stdin>", line 1, in ? +TypeError: C variable 'density (double )' +>>> +</PRE> +</DIV> +<P> If a variable is declared as <TT>const</TT>, it is wrapped as a + read-only variable. Attempts to modify its value will result in an + error.</P> +<P> To make ordinary variables read-only, you can use the <TT>%immutable</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +%{ +extern char *path; +%} +%immutable; +extern char *path; +%mutable; +</PRE> +</DIV> +<P> The <TT>%immutable</TT> directive stays in effect until it is + explicitly disabled or cleared using <TT>%mutable</TT>. See the <A href="#SWIG_readonly_variables"> +Creating read-only variables</A> section for further details.</P> +<P> If you just want to make a specific variable immutable, supply a + declaration name. For example:</P> +<DIV class="code"> +<PRE> +%{ +extern char *path; +%} +%immutable path; +... +extern char *path; // Read-only (due to %immutable) +</PRE> +</DIV> +<P> If you would like to access variables using a name other than "<TT> +cvar</TT>", it can be changed using the <TT>-globals</TT> option :</P> +<DIV class="shell"> +<PRE> +$ swig -python -globals myvar example.i +</PRE> +</DIV> +<P> Some care is in order when importing multiple SWIG modules. If you + use the "<TT>from <file> import *</TT>" style of importing, you will + get a name clash on the variable `<TT>cvar</TT>' and you will only be + able to access global variables from the last module loaded. To prevent + this, you might consider renaming <TT>cvar</TT> or making it private to + the module by giving it a name that starts with a leading underscore. + SWIG does not create <TT>cvar</TT> if there are no global variables in + a module.</P> +<H3><A name="Python_nn17"></A>31.3.4 Constants and enums</H3> +<P> C/C++ constants are installed as Python objects containing the + appropriate value. To create a constant, use <TT>#define</TT>, <TT>enum</TT> +, or the <TT>%constant</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +#define PI 3.14159 +#define VERSION "1.0" + +enum Beverage { ALE, LAGER, STOUT, PILSNER }; + +%constant int FOO = 42; +%constant const char *path = "/usr/local"; +</PRE> +</DIV> +<P> For enums, make sure that the definition of the enumeration actually + appears in a header file or in the wrapper file somehow---if you just + stick an enum in a SWIG interface without also telling the C compiler + about it, the wrapper code won't compile.</P> +<P> Note: declarations declared as <TT>const</TT> are wrapped as + read-only variables and will be accessed using the <TT>cvar</TT> object + described in the previous section. They are not wrapped as constants. + For further discussion about this, see the <A href="#SWIG">SWIG Basics</A> + chapter.</P> +<P> Constants are not guaranteed to remain constant in Python---the name + of the constant could be accidentally reassigned to refer to some other + object. Unfortunately, there is no easy way for SWIG to generate code + that prevents this. You will just have to be careful.</P> +<H3><A name="Python_nn18"></A>31.3.5 Pointers</H3> +<P> C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no + problem working with incomplete type information. Here is a rather + simple interface:</P> +<DIV class="code"> +<PRE> +%module example + +FILE *fopen(const char *filename, const char *mode); +int fputs(const char *, FILE *); +int fclose(FILE *); +</PRE> +</DIV> +<P> When wrapped, you will be able to use the functions in a natural way + from Python. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> f = example.fopen("junk","w") +>>> example.fputs("Hello World\n", f) +>>> example.fclose(f) +</PRE> +</DIV> +<P> If this makes you uneasy, rest assured that there is no deep magic + involved. Underneath the covers, pointers to C/C++ objects are simply + represented as opaque values using an especial python container object:</P> +<DIV class="targetlang"> +<PRE> +>>> print f +<Swig Object at _08a71808_p_FILE> +</PRE> +</DIV> +<P> This pointer value can be freely passed around to different C + functions that expect to receive an object of type <TT>FILE *</TT>. The + only thing you can't do is dereference the pointer from Python. Of + course, that isn't much of a concern in this example.</P> +<P> In older versions of Swig (1.3.22 or older), pointers were + represented using a plain string object. If you have an old package + that still requires that representation, or you just feel nostalgic, + you can always retrieve it by casting the pointer object to a string:</P> +<DIV class="targetlang"> +<PRE> +>>> print str(f) +_c0671108_p_FILE +</PRE> +</DIV> +<P> Also, if you need to pass the raw pointer value to some external + python library, you can do it by casting the pointer object to an + integer:</P> +<DIV class="targetlang"> +<PRE> +>>> print int(f) +135833352 +</PRE> +</DIV> +<P> However, the inverse operation is not possible, i.e., you can't + build a Swig pointer object from a raw integer value.</P> +<P> Note also that the '0' or NULL pointer is always represented by <TT> +None</TT>, no matter what type swig is addressing. In the previous + example, you can call:</P> +<DIV class="targetlang"> +<PRE> +>>> example.fclose(None) +</PRE> +</DIV> +<P> and that will be equivalent to the following, but not really useful, + C code:</P> +<DIV class="code"> +<PRE> +FILE *f = NULL; +fclose(f); +</PRE> +</DIV> +<P> As much as you might be inclined to modify a pointer value directly + from Python, don't. The hexadecimal encoding is not necessarily the + same as the logical memory address of the underlying object. Instead it + is the raw byte encoding of the pointer value. The encoding will vary + depending on the native byte-ordering of the platform (i.e., big-endian + vs. little-endian). Similarly, don't try to manually cast a pointer to + a new type by simply replacing the type-string. This may not work like + you expect, it is particularly dangerous when casting C++ objects. If + you need to cast a pointer or change its value, consider writing some + helper functions instead. For example:</P> +<DIV class="code"> +<PRE> +%inline %{ +/* C-style cast */ +Bar *FooToBar(Foo *f) { + return (Bar *) f; +} + +/* C++-style cast */ +Foo *BarToFoo(Bar *b) { + return dynamic_cast<Foo*>(b); +} + +Foo *IncrFoo(Foo *f, int i) { + return f+i; +} +%} +</PRE> +</DIV> +<P> Also, if working with C++, you should always try to use the new C++ + style casts. For example, in the above code, the C-style cast may + return a bogus result whereas as the C++-style cast will return <TT> +None</TT> if the conversion can't be performed.</P> +<H3><A name="Python_nn19"></A>31.3.6 Structures</H3> +<P> If you wrap a C structure, it is wrapped by a Python class. This + provides a very natural interface. For example,</P> +<DIV class="code"> +<PRE> +struct Vector { + double x,y,z; +}; + +</PRE> +</DIV> +<P> is used as follows:</P> +<DIV class="targetlang"> +<PRE> +>>> v = example.Vector() +>>> v.x = 3.5 +>>> v.y = 7.2 +>>> print v.x, v.y, v.z +7.8 -4.5 0.0 +>>> +</PRE> +</DIV> +<P> Similar access is provided for unions and the data members of C++ + classes.</P> +<P> If you print out the value of <TT>v</TT> in the above example, you + will see something like this:</P> +<DIV class="targetlang"> +<PRE> +>>> print v +<C Vector instance at _18e31408_p_Vector> +</PRE> +</DIV> +<P> This object is actually a Python instance that has been wrapped + around a pointer to the low-level C structure. This instance doesn't + actually do anything--it just serves as a proxy. The pointer to the C + object can be found in the the <TT>.this</TT> attribute. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> print v.this +_18e31408_p_Vector +>>> +</PRE> +</DIV> +<P> Further details about the Python proxy class are covered a little + later.</P> +<P> <TT>const</TT> members of a structure are read-only. Data members + can also be forced to be read-only using the <TT>%immutable</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +struct Foo { + ... + %immutable; + int x; /* Read-only members */ + char *name; + %mutable; + ... +}; +</PRE> +</DIV> +<P> When <TT>char *</TT> members of a structure are wrapped, the + contents are assumed to be dynamically allocated using <TT>malloc</TT> + or <TT>new</TT> (depending on whether or not SWIG is run with the -c++ + option). When the structure member is set, the old contents will be + released and a new value created. If this is not the behavior you want, + you will have to use a typemap (described later).</P> +<P> If a structure contains arrays, access to those arrays is managed + through pointers. For example, consider this:</P> +<DIV class="code"> +<PRE> +struct Bar { + int x[16]; +}; +</PRE> +</DIV> +<P> If accessed in Python, you will see behavior like this:</P> +<DIV class="targetlang"> +<PRE> +>>> b = example.Bar() +>>> print b.x +_801861a4_p_int +>>> +</PRE> +</DIV> +<P> This pointer can be passed around to functions that expect to + receive an <TT>int *</TT> (just like C). You can also set the value of + an array member using another pointer. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> c = example.Bar() +>>> c.x = b.x # Copy contents of b.x to c.x +</PRE> +</DIV> +<P> For array assignment, SWIG copies the entire contents of the array + starting with the data pointed to by <TT>b.x</TT>. In this example, 16 + integers would be copied. Like C, SWIG makes no assumptions about + bounds checking---if you pass a bad pointer, you may get a segmentation + fault or access violation.</P> +<P> When a member of a structure is itself a structure, it is handled as + a pointer. For example, suppose you have two structures like this:</P> +<DIV class="code"> +<PRE> +struct Foo { + int a; +}; + +struct Bar { + Foo f; +}; +</PRE> +</DIV> +<P> Now, suppose that you access the <TT>f</TT> attribute of <TT>Bar</TT> + like this:</P> +<DIV class="targetlang"> +<PRE> +>>> b = Bar() +>>> x = b.f +</PRE> +</DIV> +<P> In this case, <TT>x</TT> is a pointer that points to the <TT>Foo</TT> + that is inside <TT>b</TT>. This is the same value as generated by this + C code:</P> +<DIV class="code"> +<PRE> +Bar b; +Foo *x = &b->f; /* Points inside b */ +</PRE> +</DIV> +<P> Because the pointer points inside the structure, you can modify the + contents and everything works just like you would expect. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> b = Bar() +>>> b.f.a = 3 # Modify attribute of structure member +>>> x = b.f +>>> x.a = 3 # Modifies the same structure +</PRE> +</DIV> +<H3><A name="Python_nn20"></A>31.3.7 C++ classes</H3> +<P> C++ classes are wrapped by Python classes as well. For example, if + you have this class,</P> +<DIV class="code"> +<PRE> +class List { +public: + List(); + ~List(); + int search(char *item); + void insert(char *item); + void remove(char *item); + char *get(int n); + int length; +}; +</PRE> +</DIV> +<P> you can use it in Python like this:</P> +<DIV class="targetlang"> +<PRE> +>>> l = example.List() +>>> l.insert("Ale") +>>> l.insert("Stout") +>>> l.insert("Lager") +>>> l.get(1) +'Stout' +>>> print l.length +3 +>>> +</PRE> +</DIV> +<P> Class data members are accessed in the same manner as C structures.</P> +<P> Static class members present a special problem for Python. Prior to + Python-2.2, Python classes had no support for static methods and no + version of Python supports static member variables in a manner that + SWIG can utilize. Therefore, SWIG generates wrappers that try to work + around some of these issues. To illustrate, suppose you have a class + like this:</P> +<DIV class="code"> +<PRE> +class Spam { +public: + static void foo(); + static int bar; + +}; +</PRE> +</DIV> +<P> In Python, the static member can be access in three different ways:</P> +<DIV class="targetlang"> +<PRE> +>>> example.Spam_foo() # Spam::foo() +>>> s = example.Spam() +>>> s.foo() # Spam::foo() via an instance +>>> example.Spam.foo() # Spam::foo(). Python-2.2 only +</PRE> +</DIV> +<P> The first two methods of access are supported in all versions of + Python. The last technique is only available in Python-2.2 and later + versions.</P> +<P> Static member variables are currently accessed as global variables. + This means, they are accessed through <TT>cvar</TT> like this:</P> +<DIV class="targetlang"> +<PRE> +>>> print example.cvar.Spam_bar +7 +</PRE> +</DIV> +<H3><A name="Python_nn21"></A>31.3.8 C++ inheritance</H3> +<P> SWIG is fully aware of issues related to C++ inheritance. Therefore, + if you have classes like this</P> +<DIV class="code"> +<PRE> +class Foo { +... +}; + +class Bar : public Foo { +... +}; +</PRE> +</DIV> +<P> those classes are wrapped into a hierarchy of Python classes that + reflect the same inheritance structure. All of the usual Python utility + functions work normally:</P> +<DIV class="targetlang"> +<PRE> +>>> b = Bar() +>>> instance(b,Foo) +1 +>>> issubclass(Bar,Foo) +1 +>>> issubclass(Foo,Bar) +0 +</PRE> +</DIV> +<P> Furthermore, if you have functions like this</P> +<DIV class="code"> +<PRE> +void spam(Foo *f); +</PRE> +</DIV> +<P> then the function <TT>spam()</TT> accepts <TT>Foo *</TT> or a + pointer to any class derived from <TT>Foo</TT>.</P> +<P> It is safe to use multiple inheritance with SWIG.</P> +<H3><A name="Python_nn22"></A>31.3.9 Pointers, references, values, and + arrays</H3> +<P> In C++, there are many different ways a function might receive and + manipulate objects. For example:</P> +<DIV class="code"> +<PRE> +void spam1(Foo *x); // Pass by pointer +void spam2(Foo &x); // Pass by reference +void spam3(const Foo &x);// Pass by const reference +void spam4(Foo x); // Pass by value +void spam5(Foo x[]); // Array of objects +</PRE> +</DIV> +<P> In Python, there is no detailed distinction like this--specifically, + there are only "objects". There are no pointers, references, arrays, + and so forth. Because of this, SWIG unifies all of these types together + in the wrapper code. For instance, if you actually had the above + functions, it is perfectly legal to do this:</P> +<DIV class="targetlang"> +<PRE> +>>> f = Foo() # Create a Foo +>>> spam1(f) # Ok. Pointer +>>> spam2(f) # Ok. Reference +>>> spam3(f) # Ok. Const reference +>>> spam4(f) # Ok. Value. +>>> spam5(f) # Ok. Array (1 element) +</PRE> +</DIV> +<P> Similar behavior occurs for return values. For example, if you had + functions like this,</P> +<DIV class="code"> +<PRE> +Foo *spam6(); +Foo &spam7(); +Foo spam8(); +const Foo &spam9(); +</PRE> +</DIV> +<P> then all three functions will return a pointer to some <TT>Foo</TT> + object. Since the third function (spam8) returns a value, newly + allocated memory is used to hold the result and a pointer is returned + (Python will release this memory when the return value is garbage + collected). The fourth case (spam9) which returns a const reference, in + most of the cases will be treated as a returning value, and it will + follow the same allocation/deallocation process.</P> +<H3><A name="Python_nn23"></A>31.3.10 C++ overloaded functions</H3> +<P> C++ overloaded functions, methods, and constructors are mostly + supported by SWIG. For example, if you have two functions like this:</P> +<DIV class="code"> +<PRE> +void foo(int); +void foo(char *c); +</PRE> +</DIV> +<P> You can use them in Python in a straightforward manner:</P> +<DIV class="targetlang"> +<PRE> +>>> foo(3) # foo(int) +>>> foo("Hello") # foo(char *c) +</PRE> +</DIV> +<P> Similarly, if you have a class like this,</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + Foo(const Foo &); + ... +}; +</PRE> +</DIV> +<P> you can write Python code like this:</P> +<DIV class="targetlang"> +<PRE> +>>> f = Foo() # Create a Foo +>>> g = Foo(f) # Copy f +</PRE> +</DIV> +<P> Overloading support is not quite as flexible as in C++. Sometimes + there are methods that SWIG can't disambiguate. For example:</P> +<DIV class="code"> +<PRE> +void spam(int); +void spam(short); +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +void foo(Bar *b); +void foo(Bar &b); +</PRE> +</DIV> +<P> If declarations such as these appear, you will get a warning message + like this:</P> +<DIV class="shell"> +<PRE> +example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int) +at example.i:11. +</PRE> +</DIV> +<P> To fix this, you either need to ignore or rename one of the methods. + For example:</P> +<DIV class="code"> +<PRE> +%rename(spam_short) spam(short); +... +void spam(int); +void spam(short); // Accessed as spam_short +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +%ignore spam(short); +... +void spam(int); +void spam(short); // Ignored +</PRE> +</DIV> +<P> SWIG resolves overloaded functions and methods using a + disambiguation scheme that ranks and sorts declarations according to a + set of type-precedence rules. The order in which declarations appear in + the input does not matter except in situations where ambiguity + arises--in this case, the first declaration takes precedence.</P> +<P> Please refer to the "SWIG and C++" chapter for more information + about overloading.</P> +<H3><A name="Python_nn24"></A>31.3.11 C++ operators</H3> +<P> Certain C++ overloaded operators can be handled automatically by + SWIG. For example, consider a class like this:</P> +<DIV class="code"> +<PRE> +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c); + + Complex operator+=(const Complex &c) const; + Complex operator+(const Complex &c) const; + Complex operator-(const Complex &c) const; + Complex operator*(const Complex &c) const; + Complex operator-() const; + + double re() const { return rpart; } + double im() const { return ipart; } +}; +</PRE> +</DIV> +<P> When wrapped, it works like you expect:</P> +<DIV class="targetlang"> +<PRE> +>>> c = Complex(3,4) +>>> d = Complex(7,8) +>>> e = c + d +>>> e.re() +10.0 +>>> e.im() +12.0 +>>> c += d +>>> c.re() +10.0 +>>> c.im() +12.0 + +</PRE> +</DIV> +<P> One restriction with operator overloading support is that SWIG is + not able to fully handle operators that aren't defined as part of the + class. For example, if you had code like this</P> +<DIV class="code"> +<PRE> +class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; +</PRE> +</DIV> +<P> then SWIG ignores it and issues a warning. You can still wrap the + operator, but you may have to encapsulate it in a special function. For + example:</P> +<DIV class="code"> +<PRE> +%rename(Complex_add_dc) operator+(double, const Complex &); +</PRE> +</DIV> +<P> There are ways to make this operator appear as part of the class + using the <TT>%extend</TT> directive. Keep reading.</P> +<P> Also, be aware that certain operators don't map cleanly to Python. + For instance, overloaded assignment operators don't map to Python + semantics and will be ignored.</P> +<H3><A name="Python_nn25"></A>31.3.12 C++ namespaces</H3> +<P> SWIG is aware of C++ namespaces, but namespace names do not appear + in the module nor do namespaces result in a module that is broken up + into submodules or packages. For example, if you have a file like this,</P> +<DIV class="code"> +<PRE> +%module example + +namespace foo { + int fact(int n); + struct Vector { + double x,y,z; + }; +}; +</PRE> +</DIV> +<P> it works in Python as follows:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> example.fact(3) +6 +>>> v = example.Vector() +>>> v.x = 3.4 +>>> print v.y +0.0 +>>> +</PRE> +</DIV> +<P> If your program has more than one namespace, name conflicts (if any) + can be resolved using <TT>%rename</TT> For example:</P> +<DIV class="code"> +<PRE> +%rename(Bar_spam) Bar::spam; + +namespace Foo { + int spam(); +} + +namespace Bar { + int spam(); +} +</PRE> +</DIV> +<P> If you have more than one namespace and your want to keep their + symbols separate, consider wrapping them as separate SWIG modules. For + example, make the module name the same as the namespace and create + extension modules for each namespace separately. If your program + utilizes thousands of small deeply nested namespaces each with + identical symbol names, well, then you get what you deserve.</P> +<H3><A name="Python_nn26"></A>31.3.13 C++ templates</H3> +<P> C++ templates don't present a huge problem for SWIG. However, in + order to create wrappers, you have to tell SWIG to create wrappers for + a particular template instantiation. To do this, you use the <TT> +%template</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%module example +%{ +#include "pair.h" +%} + +template<class T1, class T2> +struct pair { + typedef T1 first_type; + typedef T2 second_type; + T1 first; + T2 second; + pair(); + pair(const T1&, const T2&); + ~pair(); +}; + +%template(pairii) pair<int,int>; +</PRE> +</DIV> +<P> In Python:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> p = example.pairii(3,4) +>>> p.first +3 +>>> p.second +4 +</PRE> +</DIV> +<P> Obviously, there is more to template wrapping than shown in this + example. More details can be found in the <A href="#SWIGPlus">SWIG and + C++</A> chapter. Some more complicated examples will appear later.</P> +<H3><A name="Python_nn27"></A>31.3.14 C++ Smart Pointers</H3> +<P> In certain C++ programs, it is common to use classes that have been + wrapped by so-called "smart pointers." Generally, this involves the use + of a template class that implements <TT>operator->()</TT> like this:</P> +<DIV class="code"> +<PRE> +template<class T> class SmartPtr { + ... + T *operator->(); + ... +} +</PRE> +</DIV> +<P> Then, if you have a class like this,</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int x; + int bar(); +}; +</PRE> +</DIV> +<P> A smart pointer would be used in C++ as follows:</P> +<DIV class="code"> +<PRE> +SmartPtr<Foo> p = CreateFoo(); // Created somehow (not shown) +... +p->x = 3; // Foo::x +int y = p->bar(); // Foo::bar +</PRE> +</DIV> +<P> To wrap this in Python, simply tell SWIG about the <TT>SmartPtr</TT> + class and the low-level <TT>Foo</TT> object. Make sure you instantiate <TT> +SmartPtr</TT> using <TT>%template</TT> if necessary. For example:</P> +<DIV class="code"> +<PRE> +%module example +... +%template(SmartPtrFoo) SmartPtr<Foo>; +... +</PRE> +</DIV> +<P> Now, in Python, everything should just "work":</P> +<DIV class="targetlang"> +<PRE> +>>> p = example.CreateFoo() # Create a smart-pointer somehow +>>> p.x = 3 # Foo::x +>>> p.bar() # Foo::bar +</PRE> +</DIV> +<P> If you ever need to access the underlying pointer returned by <TT> +operator->()</TT> itself, simply use the <TT>__deref__()</TT> method. + For example:</P> +<DIV class="targetlang"> +<PRE> +>>> f = p.__deref__() # Returns underlying Foo * +</PRE> +</DIV> +<H3><A name="Python_nn27a"></A>31.3.15 C++ Reference Counted Objects + (ref/unref)</H3> +<P> Another usual idiom in C++ is the use of reference counted objects. + Consider for example:<DIV class="code"> +<PRE> +class RCObj { + // implement the ref counting mechanism + int add_ref(); + int del_ref(); + int ref_count(); + +public: + virtual ~RCObj() = 0; + + int ref() const { + return add_ref(); + } + + int unref() const { + if (ref_count() == 0 || del_ref() == 0 ) { + delete this; + return 0; + } + return ref_count(); + } +}; + + +class A : RCObj { +public: + A(); + int foo(); +}; + + +class B { + A *_a; + +public: + B(A *a) : _a(a) { + a->ref(); + } + + ~B() { + a->unref(); + } +}; + +int main() { + A *a = new A(); + a->ref(); // 'a' is ref here + + B *b1 = new B(a); // 'a' is ref here + if (1 + 1 == 2) { + B *b2 = new B(a); // 'a' is ref here + delete b2; // 'a' is unref, but not deleted + } + + delete b1; // 'a' is unref, but not deleted + a->unref(); // 'a' is unref and deleted +} +</PRE> +</DIV></P> +<P> In the example above, the 'A' class instance 'a' is a reference + counted object, which can't be deleted arbitrarily since it is shared + between the objects 'b1' and 'b2'. 'A' is derived from an Reference + Counted Object 'RCObj', which implements the ref/unref idiom.</P> +<P> To tell SWIG that 'RCObj' and all its derived classes are reference + counted objects, you use the "ref" and "unref" features, or <TT>%ref</TT> + and <TT>%unref</TT> directives (since 1.3.28). For example:</P> +<DIV class="code"> +<PRE> +%module example +... + +%feature("ref") RCObj "$this->ref();" +%feature("unref") RCObj "$this->unref();" + +%include "rcobj.h" +%include "A.h" +... +</PRE> +</DIV> or, using the directive form:<DIV class="code"> +<PRE> +%module example +... + +%ref RCObj "$this->ref();" +%unref RCObj "$this->unref();" + +%include "rcobj.h" +%include "A.h" +... +</PRE> +</DIV> +<P> where the code passed to the "ref" and "unref" features will be + executed as needed whenever a new object is passed to python, or when + python tries to release the shadow object instance, respectively.</P> +<P> In the python side, the use of a reference counted object is not + different than any other regular instance:</P> +<DIV class="targetlang"> +<PRE> +def create_A(): + a = A() # SWIG ref 'a' (new object is passed to python) + b1 = B(a) # C++ ref 'a' + if 1 + 1 == 2: + b2 = B(a) # C++ ref 'a' + return a # 'b1' and 'b2' are released, C++ unref 'a' twice + +a = create_A() +exit # 'a' is released, SWIG unref 'a' +</PRE> +</DIV> +<P> Note that the user doesn't explicitly need to call 'a->ref()' nor + 'a->unref()' (as neither 'delete a'). Instead, SWIG take cares of + executing the "ref" and "unref" codes as needed. If the user doesn't + specify the "ref/unref" features, SWIG will produce a code equivalent + to define them as:</P> +<DIV class="code"> +<PRE> +%feature("ref") "" +%feature("unref") "delete $this;" +</PRE> +</DIV> +<P> In other words, SWIG will not do anything special when a new object + is passed to python, and it will always 'delete' the object when python + releases the proxy instance.</P> +<H2><A name="Python_nn28"></A>31.4 Further details on the Python class + interface</H2> +<P> In the previous section, a high-level view of Python wrapping was + presented. A key component of this wrapping is that structures and + classes are wrapped by Python proxy classes. This provides a very + natural Python interface and allows SWIG to support a number of + advanced features such as operator overloading. However, a number of + low-level details were omitted. This section provides a brief overview + of how the proxy classes work.</P> +<H3><A name="Python_nn29"></A>31.4.1 Proxy classes</H3> +<P> In the <A href="#SWIG">"SWIG basics"</A> and <A href="#SWIGPlus"> +"SWIG and C++"</A> chapters, details of low-level structure and class + wrapping are described. To summarize those chapters, if you have a + class like this</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int x; + int spam(int); + ... +</PRE> +</DIV> +<P> then SWIG transforms it into a set of low-level procedural wrappers. + For example:</P> +<DIV class="code"> +<PRE> +Foo *new_Foo() { + return new Foo(); +} +void delete_Foo(Foo *f) { + delete f; +} +int Foo_x_get(Foo *f) { + return f->x; +} +void Foo_x_set(Foo *f, int value) { + f->x = value; +} +int Foo_spam(Foo *f, int arg1) { + return f->spam(arg1); +} +</PRE> +</DIV> +<P> These wrappers can be found in the low-level extension module (e.g., + <TT>_example</TT>).</P> +<P> Using these wrappers, SWIG generates a high-level Python proxy class + (also known as a shadow class) like this (shown for Python 2.2):</P> +<DIV class="targetlang"> +<PRE> +import _example + +class Foo(object): + def __init__(self): + self.this = _example.new_Foo() + self.thisown = 1 + def __del__(self): + if self.thisown: + _example.delete_Foo(self.this) + def spam(self,arg1): + return _example.Foo_spam(self.this,arg1) + x = property(_example.Foo_x_get, _example.Foo_x_set) +</PRE> +</DIV> +<P> This class merely holds a pointer to the underlying C++ object (<TT> +.this</TT>) and dispatches methods and member variable access to that + object using the low-level accessor functions. From a user's point of + view, it makes the class work normally:</P> +<DIV class="targetlang"> +<PRE> +>>> f = example.Foo() +>>> f.x = 3 +>>> y = f.spam(5) +</PRE> +</DIV> +<P> The fact that the class has been wrapped by a real Python class + offers certain advantages. For instance, you can attach new Python + methods to the class and you can even inherit from it (something not + supported by Python built-in types until Python 2.2).</P> +<H3><A name="Python_nn30"></A>31.4.2 Memory management</H3> +<P> Associated with proxy object, is an ownership flag <TT>.thisown</TT> + The value of this flag determines who is responsible for deleting the + underlying C++ object. If set to 1, the Python interpreter will destroy + the C++ object when the proxy class is garbage collected. If set to 0 + (or if the attribute is missing), then the destruction of the proxy + class has no effect on the C++ object.</P> +<P> When an object is created by a constructor or returned by value, + Python automatically takes ownership of the result. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + Foo bar(); +}; +</PRE> +</DIV> +<P> In Python:</P> +<DIV class="targetlang"> +<PRE> +>>> f = Foo() +>>> f.thisown +1 +>>> g = f.bar() +>>> g.thisown +1 +</PRE> +</DIV> +<P> On the other hand, when pointers are returned to Python, there is + often no way to know where they came from. Therefore, the ownership is + set to zero. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + ... + Foo *spam(); + ... +}; +</PRE> +</DIV> +<BR><DIV class="targetlang"> +<PRE> +>>> f = Foo() +>>> s = f.spam() +>>> print s.thisown +0 +>>> +</PRE> +</DIV> +<P> This behavior is especially important for classes that act as + containers. For example, if a method returns a pointer to an object + that is contained inside another object, you definitely don't want + Python to assume ownership and destroy it!</P> +<P> A good way to indicate that ownership should be set for a returned + pointer is to use the <A href="#Library_nn11">%newobject directive</A>.</P> +<P> Related to containers, ownership issues can arise whenever an object + is assigned to a member or global variable. For example, consider this + interface:</P> +<DIV class="code"> +<PRE> +%module example + +struct Foo { + int value; + Foo *next; +}; + +Foo *head = 0; +</PRE> +</DIV> +<P> When wrapped in Python, careful observation will reveal that + ownership changes whenever an object is assigned to a global variable. + For example:</P> +<DIV class="targetlang"> +<PRE> +>>> f = example.Foo() +>>> f.thisown +1 +>>> example.cvar.head = f +>>> f.thisown +0 +>>> +</PRE> +</DIV> +<P> In this case, C is now holding a reference to the object---you + probably don't want Python to destroy it. Similarly, this occurs for + members. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> f = example.Foo() +>>> g = example.Foo() +>>> f.thisown +1 +>>> g.thisown +1 +>>> f.next = g +>>> g.thisown +0 +>>> +</PRE> +</DIV> +<P> For the most part, memory management issues remain hidden. However, + there are occasionally situations where you might have to manually + change the ownership of an object. For instance, consider code like + this:</P> +<DIV class="code"> +<PRE> +class Node { + Object *value; +public: + void set_value(Object *v) { value = v; } + ... +}; +</PRE> +</DIV> +<P> Now, consider the following Python code:</P> +<DIV class="targetlang"> +<PRE> +>>> v = Object() # Create an object +>>> n = Node() # Create a node +>>> n.set_value(v) # Set value +>>> v.thisown +1 +>>> del v +</PRE> +</DIV> +<P> In this case, the object <TT>n</TT> is holding a reference to <TT>v</TT> + internally. However, SWIG has no way to know that this has occurred. + Therefore, Python still thinks that it has ownership of the object. + Should the proxy object be destroyed, then the C++ destructor will be + invoked and <TT>n</TT> will be holding a stale-pointer. If you're + lucky, you will only get a segmentation fault.</P> +<P> To work around this, it is always possible to flip the ownership + flag. For example,</P> +<DIV class="targetlang"> +<PRE> +>>> v.thisown = 0 +</PRE> +</DIV> +<P> It is also possible to deal with situations like this using + typemaps--an advanced topic discussed later.</P> +<H3><A name="Python_nn31"></A>31.4.3 Python 2.2 and classic classes</H3> +<P> SWIG makes every attempt to preserve backwards compatibility with + older versions of Python to the extent that it is possible. However, in + Python-2.2, an entirely new type of class system was introduced. This + new-style class system offers many enhancements including static member + functions, properties (managed attributes), and class methods. Details + about all of these changes can be found on <A href="//www.python.org"> +www.python.org</A> and is not repeated here.</P> +<P> To address differences between Python versions, SWIG currently emits + dual-mode proxy class wrappers. In Python-2.2 and newer releases, these + wrappers encapsulate C++ objects in new-style classes that take + advantage of new features (static methods and properties). However, if + these very same wrappers are imported into an older version of Python, + old-style classes are used instead.</P> +<P> This dual-nature of the wrapper code means that you can create + extension modules with SWIG and those modules will work with all + versions of Python ranging from Python-1.4 to the very latest release. + Moreover, the wrappers take advantage of Python-2.2 features when + available.</P> +<P> For the most part, the interface presented to users is the same + regardless of what version of Python is used. The only incompatibility + lies in the handling of static member functions. In Python-2.2, they + can be accessed via the class itself. In Python-2.1 and earlier, they + have to be accessed as a global function or through an instance (see + the earlier section).</P> +<H2><A name="Python_directors"></A>31.5 Cross language polymorphism</H2> +<P> Proxy classes provide a more natural, object-oriented way to access + extension classes. As described above, each proxy instance has an + associated C++ instance, and method calls to the proxy are passed to + the C++ instance transparently via C wrapper functions.</P> +<P> This arrangement is asymmetric in the sense that no corresponding + mechanism exists to pass method calls down the inheritance chain from + C++ to Python. In particular, if a C++ class has been extended in + Python (by extending the proxy class), these extensions will not be + visible from C++ code. Virtual method calls from C++ are thus not able + access the lowest implementation in the inheritance chain.</P> +<P> Changes have been made to SWIG 1.3.18 to address this problem and + make the relationship between C++ classes and proxy classes more + symmetric. To achieve this goal, new classes called directors are + introduced at the bottom of the C++ inheritance chain. The job of the + directors is to route method calls correctly, either to C++ + implementations higher in the inheritance chain or to Python + implementations lower in the inheritance chain. The upshot is that C++ + classes can be extended in Python and from C++ these extensions look + exactly like native C++ classes. Neither C++ code nor Python code needs + to know where a particular method is implemented: the combination of + proxy classes, director classes, and C wrapper functions takes care of + all the cross-language method routing transparently.</P> +<H3><A name="Python_nn33"></A>31.5.1 Enabling directors</H3> +<P> The director feature is disabled by default. To use directors you + must make two changes to the interface file. First, add the "directors" + option to the %module directive, like this:</P> +<DIV class="code"> +<PRE> +%module(directors="1") modulename +</PRE> +</DIV> +<P> Without this option no director code will be generated. Second, you + must use the %feature("director") directive to tell SWIG which classes + and methods should get directors. The %feature directive can be applied + globally, to specific classes, and to specific methods, like this:</P> +<DIV class="code"> +<PRE> +// generate directors for all classes that have virtual methods +%feature("director"); + +// generate directors for all virtual methods in class Foo +%feature("director") Foo; + +// generate a director for just Foo::bar() +%feature("director") Foo::bar; +</PRE> +</DIV> +<P> You can use the %feature("nodirector") directive to turn off + directors for specific classes or methods. So for example,</P> +<DIV class="code"> +<PRE> +%feature("director") Foo; +%feature("nodirector") Foo::bar; +</PRE> +</DIV> +<P> will generate directors for all virtual methods of class Foo except + bar().</P> +<P> Directors can also be generated implicitly through inheritance. In + the following, class Bar will get a director class that handles the + methods one() and two() (but not three()):</P> +<DIV class="code"> +<PRE> +%feature("director") Foo; +class Foo { +public: + Foo(int foo); + virtual void one(); + virtual void two(); +}; + +class Bar: public Foo { +public: + virtual void three(); +}; +</PRE> +</DIV> +<P> then at the python side you can define</P> +<DIV class="targetlang"> +<PRE> +import mymodule + +class MyFoo(mymodule.Foo): + def __init__(self, foo): + mymodule.Foo(self, foo) + + def one(self): + print "one from python" +</PRE> +</DIV> +<H3><A name="Python_nn34"></A>31.5.2 Director classes</H3> +<P> For each class that has directors enabled, SWIG generates a new + class that derives from both the class in question and a special <TT> +Swig::Director</TT> class. These new classes, referred to as director + classes, can be loosely thought of as the C++ equivalent of the Python + proxy classes. The director classes store a pointer to their underlying + Python object and handle various issues related to object ownership. + Indeed, this is quite similar to the "this" and "thisown" members of + the Python proxy classes.</P> +<P> For simplicity let's ignore the <TT>Swig::Director</TT> class and + refer to the original C++ class as the director's base class. By + default, a director class extends all virtual methods in the + inheritance chain of its base class (see the preceding section for how + to modify this behavior). Thus all virtual method calls, whether they + originate in C++ or in Python via proxy classes, eventually end up in + at the implementation in the director class. The job of the director + methods is to route these method calls to the appropriate place in the + inheritance chain. By "appropriate place" we mean the method that would + have been called if the C++ base class and its extensions in Python + were seamlessly integrated. That seamless integration is exactly what + the director classes provide, transparently skipping over all the messy + extension API glue that binds the two languages together.</P> +<P> In reality, the "appropriate place" is one of only two + possibilities: C++ or Python. Once this decision is made, the rest is + fairly easy. If the correct implementation is in C++, then the lowest + implementation of the method in the C++ inheritance chain is called + explicitly. If the correct implementation is in Python, the Python API + is used to call the method of the underlying Python object (after which + the usual virtual method resolution in Python automatically finds the + right implementation).</P> +<P> Now how does the director decide which language should handle the + method call? The basic rule is to handle the method in Python, unless + there's a good reason not to. The reason for this is simple: Python has + the most "extended" implementation of the method. This assertion is + guaranteed, since at a minimum the Python proxy class implements the + method. If the method in question has been extended by a class derived + from the proxy class, that extended implementation will execute exactly + as it should. If not, the proxy class will route the method call into a + C wrapper function, expecting that the method will be resolved in C++. + The wrapper will call the virtual method of the C++ instance, and since + the director extends this the call will end up right back in the + director method. Now comes the "good reason not to" part. If the + director method were to blindly call the Python method again, it would + get stuck in an infinite loop. We avoid this situation by adding + special code to the C wrapper function that tells the director method + to not do this. The C wrapper function compares the pointer to the + Python object that called the wrapper function to the pointer stored by + the director. If these are the same, then the C wrapper function tells + the director to resolve the method by calling up the C++ inheritance + chain, preventing an infinite loop.</P> +<P> One more point needs to be made about the relationship between + director classes and proxy classes. When a proxy class instance is + created in Python, SWIG creates an instance of the original C++ class + and assigns it to <TT>.this</TT>. This is exactly what happens without + directors and is true even if directors are enabled for the particular + class in question. When a class<I> derived</I> from a proxy class is + created, however, SWIG then creates an instance of the corresponding + C++ director class. The reason for this difference is that user-defined + subclasses may override or extend methods of the original class, so the + director class is needed to route calls to these methods correctly. For + unmodified proxy classes, all methods are ultimately implemented in C++ + so there is no need for the extra overhead involved with routing the + calls through Python.</P> +<H3><A name="Python_nn35"></A>31.5.3 Ownership and object destruction</H3> +<P> Memory management issues are slightly more complicated with + directors than for proxy classes alone. Python instances hold a pointer + to the associated C++ director object, and the director in turn holds a + pointer back to the Python object. By default, proxy classes own their + C++ director object and take care of deleting it when they are garbage + collected.</P> +<P> This relationship can be reversed by calling the special <TT> +__disown__()</TT> method of the proxy class. After calling this method, + the <TT>.thisown</TT> flag is set to zero, and the director class + increments the reference count of the Python object. When the director + class is deleted it decrements the reference count. Assuming no + outstanding references to the Python object remain, the Python object + will be destroyed at the same time. This is a good thing, since + directors and proxies refer to each other and so must be created and + destroyed together. Destroying one without destroying the other will + likely cause your program to segfault.</P> +<P> To help ensure that no references to the Python object remain after + calling <TT>__disown__()</TT>, this method returns a weak reference to + the Python object. Weak references are only available in Python + versions 2.1 and higher, so for older versions you must explicitly + delete all references. Here is an example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + ... +}; +class FooContainer { +public: + void addFoo(Foo *); + ... +}; +</PRE> +</DIV> +<BR><DIV class="targetlang"> +<PRE> +>>> c = FooContainer() +>>> a = Foo().__disown()__ +>>> c.addFoo(a) +>>> b = Foo() +>>> b = b.__disown()__ +>>> c.addFoo(b) +>>> c.addFoo(Foo().__disown()__) +</PRE> +</DIV> +<P> In this example, we are assuming that FooContainer will take care of + deleting all the Foo pointers it contains at some point. Note that no + hard references to the Foo objects remain in Python.</P> +<H3><A name="Python_nn36"></A>31.5.4 Exception unrolling</H3> +<P> With directors routing method calls to Python, and proxies routing + them to C++, the handling of exceptions is an important concern. By + default, the directors ignore exceptions that occur during method calls + that are resolved in Python. To handle such exceptions correctly, it is + necessary to temporarily translate them into C++ exceptions. This can + be done with the %feature("director:except") directive. The following + code should suffice in most cases:</P> +<DIV class="code"> +<PRE> +%feature("director:except") { + if ($error != NULL) { + throw Swig::DirectorMethodException(); + } +} +</PRE> +</DIV> +<P> This code will check the Python error state after each method call + from a director into Python, and throw a C++ exception if an error + occurred. This exception can be caught in C++ to implement an error + handler. Currently no information about the Python error is stored in + the Swig::DirectorMethodException object, but this will likely change + in the future.</P> +<P> It may be the case that a method call originates in Python, travels + up to C++ through a proxy class, and then back into Python via a + director method. If an exception occurs in Python at this point, it + would be nice for that exception to find its way back to the original + caller. This can be done by combining a normal %exception directive + with the <TT>director:except</TT> handler shown above. Here is an + example of a suitable exception handler:</P> +<DIV class="code"> +<PRE> +%exception { + try { $action } + catch (Swig::DirectorException &e) { SWIG_fail; } +} +</PRE> +</DIV> +<P> The class Swig::DirectorException used in this example is actually a + base class of Swig::DirectorMethodException, so it will trap this + exception. Because the Python error state is still set when + Swig::DirectorMethodException is thrown, Python will register the + exception as soon as the C wrapper function returns.</P> +<H3><A name="Python_nn37"></A>31.5.5 Overhead and code bloat</H3> +<P> Enabling directors for a class will generate a new director method + for every virtual method in the class' inheritance chain. This alone + can generate a lot of code bloat for large hierarchies. Method + arguments that require complex conversions to and from target language + types can result in large director methods. For this reason it is + recommended that you selectively enable directors only for specific + classes that are likely to be extended in Python and used in C++.</P> +<P> Compared to classes that do not use directors, the call routing in + the director methods does add some overhead. In particular, at least + one dynamic cast and one extra function call occurs per method call + from Python. Relative to the speed of Python execution this is probably + completely negligible. For worst case routing, a method call that + ultimately resolves in C++ may take one extra detour through Python in + order to ensure that the method does not have an extended Python + implementation. This could result in a noticeable overhead in some + cases.</P> +<P> Although directors make it natural to mix native C++ objects with + Python objects (as director objects) via a common base class pointer, + one should be aware of the obvious fact that method calls to Python + objects will be much slower than calls to C++ objects. This situation + can be optimized by selectively enabling director methods (using the + %feature directive) for only those methods that are likely to be + extended in Python.</P> +<H3><A name="Python_nn38"></A>31.5.6 Typemaps</H3> +<P> Typemaps for input and output of most of the basic types from + director classes have been written. These are roughly the reverse of + the usual input and output typemaps used by the wrapper code. The + typemap operation names are 'directorin', 'directorout', and + 'directorargout'. The director code does not currently use any of the + other kinds of typemaps. It is not clear at this point which kinds are + appropriate and need to be supported.</P> +<H3><A name="Python_nn39"></A>31.5.7 Miscellaneous</H3> +<P> Director typemaps for STL classes are in place, and hence you should + be able to use std::vector, std::string, etc., as you would any other + type.</P> +<P><B> Note:</B> The director typemaps for return types based in const + references, such as<DIV class="code"> +<PRE> +class Foo { +… + virtual const int& bar(); +… +}; +</PRE> +</DIV></P> +<P> will work only for simple call scenarios. Usually the resulting code + is neither thread or reentrant safe. Hence, the user is advised to + avoid returning const references in director methods. For example, the + user could modify the method interface to use lvalue return types, + wherever possible, for example</P> +<DIV class="code"> +<PRE> +class Foo { +… + virtual int bar(); +… +}; +</PRE> +</DIV> +<P> If that is not possible, the user should avoid enabling the director + feature for reentrant, recursive or threaded member methods that return + const references.</P> +<H2><A name="Python_nn40"></A>31.6 Common customization features</H2> +<P> The last section presented the absolute basics of C/C++ wrapping. If + you do nothing but feed SWIG a header file, you will get an interface + that mimics the behavior described. However, sometimes this isn't + enough to produce a nice module. Certain types of functionality might + be missing or the interface to certain functions might be awkward. This + section describes some common SWIG features that are used to improve + your the interface to an extension module.</P> +<H3><A name="Python_nn41"></A>31.6.1 C/C++ helper functions</H3> +<P> Sometimes when you create a module, it is missing certain bits of + functionality. For example, if you had a function like this</P> +<DIV class="code"> +<PRE> +void set_transform(Image *im, double m[4][4]); +</PRE> +</DIV> +<P> it would be accessible from Python, but there may be no easy way to + call it. For example, you might get errors like this:</P> +<DIV class="targetlang"> +<PRE> +>>> a = [ +... [1,0,0,0], +... [0,1,0,0], +... [0,0,1,0], +... [0,0,0,1]] +>>> set_transform(im,a) +Traceback (most recent call last): + File "<stdin>", line 1, in ? +TypeError: Type error. Expected _p_a_4__double +</PRE> +</DIV> +<P> The problem here is that there is no easy way to construct and + manipulate a suitable <TT>double [4][4]</TT> value to use. To fix this, + you can write some extra C helper functions. Just use the <TT>%inline</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +%inline %{ +/* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */ +double (*new_mat44())[4] { + return (double (*)[4]) malloc(16*sizeof(double)); +} +void free_mat44(double (*x)[4]) { + free(x); +} +void mat44_set(double x[4][4], int i, int j, double v) { + x[i][j] = v; +} +double mat44_get(double x[4][4], int i, int j) { + return x[i][j]; +} +%} +</PRE> +</DIV> +<P> From Python, you could then write code like this:</P> +<DIV class="targetlang"> +<PRE> +>>> a = new_mat44() +>>> mat44_set(a,0,0,1.0) +>>> mat44_set(a,1,1,1.0) +>>> mat44_set(a,2,2,1.0) +... +>>> set_transform(im,a) +>>> +</PRE> +</DIV> +<P> Admittedly, this is not the most elegant looking approach. However, + it works and it wasn't too hard to implement. It is possible to clean + this up using Python code, typemaps, and other customization features + as covered in later sections.</P> +<H3><A name="Python_nn42"></A>31.6.2 Adding additional Python code</H3> +<P> If writing support code in C isn't enough, it is also possible to + write code in Python. This code gets inserted in to the <TT>.py</TT> + file created by SWIG. One use of Python code might be to supply a + high-level interface to certain functions. For example:</P> +<DIV class="code"> +<PRE> +void set_transform(Image *im, double x[4][4]); + +... +/* Rewrite the high level interface to set_transform */ +%pythoncode %{ +def set_transform(im,x): + a = new_mat44() + for i in range(4): + for j in range(4): + mat44_set(a,i,j,x[i][j]) + _example.set_transform(im,a) + free_mat44(a) +%} +</PRE> +</DIV> +<P> In this example, <TT>set_transform()</TT> provides a high-level + Python interface built on top of low-level helper functions. For + example, this code now seems to work:</P> +<DIV class="targetlang"> +<PRE> +>>> a = [ +... [1,0,0,0], +... [0,1,0,0], +... [0,0,1,0], +... [0,0,0,1]] +>>> set_transform(im,a) +>>> +</PRE> +</DIV> +<P> Admittedly, this whole scheme for wrapping the two-dimension array + argument is rather ad-hoc. Besides, shouldn't a Python list or a + Numeric Python array just work normally? We'll get to those examples + soon enough. For now, think of this example as an illustration of what + can be done without having to rely on any of the more advanced + customization features.</P> +<P>Sometimes you may want to replace or modify the wrapper function that + SWIG creates in the proxy <TT>.py</TT> file. The Python module in SWIG + provides some features that enable you do do this. First, to entirely + replace a proxy function you can use <TT>%feature("shadow")</TT>. For + example:</P> +<DIV class="code"> +<PRE> +%module example + +// Rewrite bar() python code + +%feature("shadow") Foo::bar(int) %{ +def bar(*args): + #do something before + $action + #do something after +%} + +class Foo { +public: + int bar(int x); +} +</PRE> +</DIV> +<P> where <TT>$action</TT> will be replaced by the call to the C/C++ + proper method.</P> +<P> Often the proxy function created by SWIG is fine, but you simply + want to add code to it without touching the rest of the generated + function body. For these cases SWIG provides the <TT>pythonprepend</TT> + and <TT>pythonappend</TT> features which do exactly as their names + suggest. The <TT>pythonprepend</TT> feature will insert its value at + the beginning of the proxy function, and <TT>pythonappend</TT> will + insert code at the end of the proxy, just before the return statement.</P> +<DIV class="code"> +<PRE> +%module example + +// Add python code to bar() + +%feature("pythonprepend") Foo::bar(int) %{ + #do something before C++ call +%} + +%feature("pythonappend") Foo::bar(int) %{ + #do something after C++ call +%} + + +class Foo { +public: + int bar(int x); +} +</PRE> +</DIV> +<P> Notes: Usually the <TT>pythonappend</TT> and <TT>pythonprepend</TT> + features are safer to use than the <TT>shadow</TT> feature. Also, from + SWIG version 1.3.28 you can use the directive forms <TT>%pythonappend</TT> + and <TT>%pythonprepend</TT> as follows:</P> +<DIV class="code"> +<PRE> +%module example + +// Add python code to bar() + +%pythonprepend Foo::bar(int) %{ + #do something before C++ call +%} + +%pythonappend Foo::bar(int) %{ + #do something after C++ call +%} + + +class Foo { +public: + int bar(int x); +} +</PRE> +</DIV> +<H3><A name="Python_nn43"></A>31.6.3 Class extension with %extend</H3> +<P> One of the more interesting features of SWIG is that it can extend + structures and classes with new methods--at least in the Python + interface. Here is a simple example:</P> +<DIV class="code"> +<PRE> +%module example +%{ +#include "someheader.h" +%} + +struct Vector { + double x,y,z; +}; + +%extend Vector { + char *__str__() { + static char tmp[1024]; + sprintf(tmp,"Vector(%g,%g,%g)", $self->x,$self->y,$self->z); + return tmp; + } + Vector(double x, double y, double z) { + Vector *v = (Vector *) malloc(sizeof(Vector)); + v->x = x; + v->y = y; + v->z = z; + return v; + } +}; +</PRE> +</DIV> +<P> Now, in Python</P> +<DIV class="targetlang"> +<PRE> +>>> v = example.Vector(2,3,4) +>>> print v +Vector(2,3,4) +>>> +</PRE> +</DIV> +<P> <TT>%extend</TT> can be used for many more tasks than this. For + example, if you wanted to overload a Python operator, you might do + this:</P> +<DIV class="code"> +<PRE> +%extend Vector { + Vector __add__(Vector *other) { + Vector v; + v.x = $self->x + other->x; + v.y = $self->y + other->y; + v.z = $self->z + other->z; + return v; + } +}; +</PRE> +</DIV> +<P> Use it like this:</P> +<DIV class="targetlang"> +<PRE> +>>> import example +>>> v = example.Vector(2,3,4) +>>> w = example.Vector(10,11,12) +>>> print v+w +Vector(12,14,16) +>>> +</PRE> +</DIV> +<P> <TT>%extend</TT> works with both C and C++ code. It does not modify + the underlying object in any way---the extensions only show up in the + Python interface.</P> +<H3><A name="Python_nn44"></A>31.6.4 Exception handling with %exception</H3> +<P> If a C or C++ function throws an error, you may want to convert that + error into a Python exception. To do this, you can use the <TT> +%exception</TT> directive. <TT>%exception</TT> simply lets you rewrite + part of the generated wrapper code to include an error check.</P> +<P> In C, a function often indicates an error by returning a status code + (a negative number or a NULL pointer perhaps). Here is a simple example + of how you might handle that:</P> +<DIV class="code"> +<PRE> +%exception malloc { + $action + if (!result) { + PyErr_SetString(PyExc_MemoryError,"Not enough memory"); + return NULL; + } +} +void *malloc(size_t nbytes); +</PRE> +</DIV> +<P> In Python,</P> +<DIV class="targetlang"> +<PRE> +>>> a = example.malloc(2000000000) +Traceback (most recent call last): + File "<stdin>", line 1, in ? +MemoryError: Not enough memory +>>> +</PRE> +</DIV> +<P> If a library provides some kind of general error handling framework, + you can also use that. For example:</P> +<DIV class="code"> +<PRE> +%exception { + $action + if (err_occurred()) { + PyErr_SetString(PyExc_RuntimeError, err_message()); + return NULL; + } +} +</PRE> +</DIV> +<P> No declaration name is given to <TT>%exception</TT>, it is applied + to all wrapper functions.</P> +<P> C++ exceptions are also easy to handle. For example, you can write + code like this:</P> +<DIV class="code"> +<PRE> +%exception getitem { + try { + $action + } catch (std::out_of_range &e) { + PyErr_SetString(PyExc_IndexError, const_cast<char*>(e.what())); + return NULL; + } +} + +class Base { +public: + Foo *getitem(int index); // Exception handled added + ... +}; +</PRE> +</DIV> +<P> When raising a Python exception from C, use the <TT> +PyErr_SetString()</TT> function as shown above. The following exception + types can be used as the first argument.</P> +<DIV class="code"> +<PRE> +PyExc_ArithmeticError +PyExc_AssertionError +PyExc_AttributeError +PyExc_EnvironmentError +PyExc_EOFError +PyExc_Exception +PyExc_FloatingPointError +PyExc_ImportError +PyExc_IndexError +PyExc_IOError +PyExc_KeyError +PyExc_KeyboardInterrupt +PyExc_LookupError +PyExc_MemoryError +PyExc_NameError +PyExc_NotImplementedError +PyExc_OSError +PyExc_OverflowError +PyExc_RuntimeError +PyExc_StandardError +PyExc_SyntaxError +PyExc_SystemError +PyExc_TypeError +PyExc_UnicodeError +PyExc_ValueError +PyExc_ZeroDivisionError +</PRE> +</DIV> +<P> The language-independent <TT>exception.i</TT> library file can also + be used to raise exceptions. See the <A href="#Library">SWIG Library</A> + chapter.</P> +<H2><A name="Python_nn45"></A>31.7 Tips and techniques</H2> +<P> Although SWIG is largely automatic, there are certain types of + wrapping problems that require additional user input. Examples include + dealing with output parameters, strings, binary data, and arrays. This + chapter discusses the common techniques for solving these problems.</P> +<H3><A name="Python_nn46"></A>31.7.1 Input and output parameters</H3> +<P> A common problem in some C programs is handling parameters passed as + simple pointers. For example:</P> +<DIV class="code"> +<PRE> +void add(int x, int y, int *result) { + *result = x + y; +} +</PRE> +</DIV> +<P> or perhaps</P> +<DIV class="code"> +<PRE> +int sub(int *x, int *y) { + return *x-*y; +} +</PRE> +</DIV> +<P> The easiest way to handle these situations is to use the <TT> +typemaps.i</TT> file. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +void add(int, int, int *OUTPUT); +int sub(int *INPUT, int *INPUT); +</PRE> +</DIV> +<P> In Python, this allows you to pass simple values. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> a = add(3,4) +>>> print a +7 +>>> b = sub(7,4) +>>> print b +3 +>>> +</PRE> +</DIV> +<P> Notice how the <TT>INPUT</TT> parameters allow integer values to be + passed instead of pointers and how the <TT>OUTPUT</TT> parameter + creates a return result.</P> +<P> If you don't want to use the names <TT>INPUT</TT> or <TT>OUTPUT</TT> +, use the <TT>%apply</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +%apply int *OUTPUT { int *result }; +%apply int *INPUT { int *x, int *y}; + +void add(int x, int y, int *result); +int sub(int *x, int *y); +</PRE> +</DIV> +<P> If a function mutates one of its parameters like this,</P> +<DIV class="code"> +<PRE> +void negate(int *x) { + *x = -(*x); +} +</PRE> +</DIV> +<P> you can use <TT>INOUT</TT> like this:</P> +<DIV class="code"> +<PRE> +%include "typemaps.i" +... +void negate(int *INOUT); +</PRE> +</DIV> +<P> In Python, a mutated parameter shows up as a return value. For + example:</P> +<DIV class="targetlang"> +<PRE> +>>> a = negate(3) +>>> print a +-3 +>>> +</PRE> +</DIV> +<P> Note: Since most primitive Python objects are immutable, it is not + possible to perform in-place modification of a Python object passed as + a parameter.</P> +<P> The most common use of these special typemap rules is to handle + functions that return more than one value. For example, sometimes a + function returns a result as well as a special error code:</P> +<DIV class="code"> +<PRE> +/* send message, return number of bytes sent, along with success code */ +int send_message(char *text, int len, int *success); +</PRE> +</DIV> +<P> To wrap such a function, simply use the <TT>OUTPUT</TT> rule above. + For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +%apply int *OUTPUT { int *success }; +... +int send_message(char *text, int *success); +</PRE> +</DIV> +<P> When used in Python, the function will return multiple values.</P> +<DIV class="targetlang"> +<PRE> +bytes, success = send_message("Hello World") +if not success: + print "Whoa!" +else: + print "Sent", bytes +</PRE> +</DIV> +<P> Another common use of multiple return values are in query functions. + For example:</P> +<DIV class="code"> +<PRE> +void get_dimensions(Matrix *m, int *rows, int *columns); +</PRE> +</DIV> +<P> To wrap this, you might use the following:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +%apply int *OUTPUT { int *rows, int *columns }; +... +void get_dimensions(Matrix *m, int *rows, *columns); +</PRE> +</DIV> +<P> Now, in Python:</P> +<DIV class="targetlang"> +<PRE> +>>> r,c = get_dimensions(m) +</PRE> +</DIV> +<P> Be aware that the primary purpose of the <TT>typemaps.i</TT> file is + to support primitive datatypes. Writing a function like this</P> +<DIV class="code"> +<PRE> +void foo(Bar *OUTPUT); +</PRE> +</DIV> +<P> may not have the intended effect since <TT>typemaps.i</TT> does not + define an OUTPUT rule for <TT>Bar</TT>.</P> +<H3><A name="Python_nn47"></A>31.7.2 Simple pointers</H3> +<P> If you must work with simple pointers such as <TT>int *</TT> or <TT> +double *</TT> and you don't want to use <TT>typemaps.i</TT>, consider + using the <TT>cpointer.i</TT> library file. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "cpointer.i" + +%inline %{ +extern void add(int x, int y, int *result); +%} + +%pointer_functions(int, intp); +</PRE> +</DIV> +<P> The <TT>%pointer_functions(type,name)</TT> macro generates five + helper functions that can be used to create, destroy, copy, assign, and + dereference a pointer. In this case, the functions are as follows:</P> +<DIV class="code"> +<PRE> +int *new_intp(); +int *copy_intp(int *x); +void delete_intp(int *x); +void intp_assign(int *x, int value); +int intp_value(int *x); +</PRE> +</DIV> +<P> In Python, you would use the functions like this:</P> +<DIV class="targetlang"> +<PRE> +>>> result = new_intp() +>>> print result +_108fea8_p_int +>>> add(3,4,result) +>>> print intp_value(result) +7 +>>> +</PRE> +</DIV> +<P> If you replace <TT>%pointer_functions()</TT> by <TT> +%pointer_class(type,name)</TT>, the interface is more class-like.</P> +<DIV class="targetlang"> +<PRE> +>>> result = intp() +>>> add(3,4,result) +>>> print result.value() +7 +</PRE> +</DIV> +<P> See the <A href="#Library">SWIG Library</A> chapter for further + details.</P> +<H3><A name="Python_nn48"></A>31.7.3 Unbounded C Arrays</H3> +<P> Sometimes a C function expects an array to be passed as a pointer. + For example,</P> +<DIV class="code"> +<PRE> +int sumitems(int *first, int nitems) { + int i, sum = 0; + for (i = 0; i < nitems; i++) { + sum += first[i]; + } + return sum; +} +</PRE> +</DIV> +<P> To wrap this into Python, you need to pass an array pointer as the + first argument. A simple way to do this is to use the <TT>carrays.i</TT> + library file. For example:</P> +<DIV class="code"> +<PRE> +%include "carrays.i" +%array_class(int, intArray); +</PRE> +</DIV> +<P> The <TT>%array_class(type, name)</TT> macro creates wrappers for an + unbounded array object that can be passed around as a simple pointer + like <TT>int *</TT> or <TT>double *</TT>. For instance, you will be + able to do this in Python:</P> +<DIV class="targetlang"> +<PRE> +>>> a = intArray(10000000) # Array of 10-million integers +>>> for i in xrange(10000): # Set some values +... a[i] = i +>>> sumitems(a,10000) +49995000 +>>> +</PRE> +</DIV> +<P> The array "object" created by <TT>%array_class()</TT> does not + encapsulate pointers inside a special array object. In fact, there is + no bounds checking or safety of any kind (just like in C). Because of + this, the arrays created by this library are extremely low-level + indeed. You can't iterate over them nor can you even query their + length. In fact, any valid memory address can be accessed if you want + (negative indices, indices beyond the end of the array, etc.). Needless + to say, this approach is not going to suit all applications. On the + other hand, this low-level approach is extremely efficient and well + suited for applications in which you need to create buffers, package + binary data, etc.</P> +<H3><A name="Python_nn49"></A>31.7.4 String handling</H3> +<P> If a C function has an argument of <TT>char *</TT>, then a Python + string can be passed as input. For example:</P> +<DIV class="code"> +<PRE> +// C +void foo(char *s); +</PRE> +</DIV><DIV class="targetlang"> +<PRE> +# Python +>>> foo("Hello") +</PRE> +</DIV> +<P> When a Python string is passed as a parameter, the C function + receives a pointer to the raw data contained in the string. Since + Python strings are immutable, it is illegal for your program to change + the value. In fact, doing so will probably crash the Python + interpreter.</P> +<P> If your program modifies the input parameter or uses it to return + data, consider using the <TT>cstring.i</TT> library file described in + the <A href="#Library">SWIG Library</A> chapter.</P> +<P> When functions return a <TT>char *</TT>, it is assumed to be a + NULL-terminated string. Data is copied into a new Python string and + returned.</P> +<P> If your program needs to work with binary data, you can use a + typemap to expand a Python string into a pointer/length argument pair. + As luck would have it, just such a typemap is already defined. Just do + this:</P> +<DIV class="code"> +<PRE> +%apply (char *STRING, int LENGTH) { (char *data, int size) }; +... +int parity(char *data, int size, int initial); +</PRE> +</DIV> +<P> Now in Python:</P> +<DIV class="targetlang"> +<PRE> +>>> parity("e\x09ffss\x00\x00\x01\nx", 0) +</PRE> +</DIV> +<P> If you need to return binary data, you might use the <TT>cstring.i</TT> + library file. The <TT>cdata.i</TT> library can also be used to extra + binary data from arbitrary pointers.</P> +<H3><A name="Python_nn50"></A>31.7.5 Arrays</H3> +<H3><A name="Python_nn51"></A>31.7.6 String arrays</H3> +<H3><A name="Python_nn52"></A>31.7.7 STL wrappers</H3> +<H2><A name="Python_nn53"></A>31.8 Typemaps</H2> +<P> This section describes how you can modify SWIG's default wrapping + behavior for various C/C++ datatypes using the <TT>%typemap</TT> + directive. This is an advanced topic that assumes familiarity with the + Python C API as well as the material in the "<A href="#Typemaps"> +Typemaps</A>" chapter.</P> +<P> Before proceeding, it should be stressed that typemaps are not a + required part of using SWIG---the default wrapping behavior is enough + in most cases. Typemaps are only used if you want to change some aspect + of the primitive C-Python interface or if you want to elevate your guru + status.</P> +<H3><A name="Python_nn54"></A>31.8.1 What is a typemap?</H3> +<P> A typemap is nothing more than a code generation rule that is + attached to a specific C datatype. For example, to convert integers + from Python to C, you might define a typemap like this:</P> +<DIV class="code"> +<PRE> +%module example + +%typemap(in) int { + $1 = (int) PyLong_AsLong($input); + printf("Received an integer : %d\n",$1); +} +%inline %{ +extern int fact(int n); +%} +</PRE> +</DIV> +<P> Typemaps are always associated with some specific aspect of code + generation. In this case, the "in" method refers to the conversion of + input arguments to C/C++. The datatype <TT>int</TT> is the datatype to + which the typemap will be applied. The supplied C code is used to + convert values. In this code a number of special variable prefaced by a + <TT>$</TT> are used. The <TT>$1</TT> variable is placeholder for a + local variable of type <TT>int</TT>. The <TT>$input</TT> variable is + the input object of type <TT>PyObject *</TT>.</P> +<P> When this example is compiled into a Python module, it operates as + follows:</P> +<DIV class="targetlang"> +<PRE> +>>> from example import * +>>> fact(6) +Received an integer : 6 +720 +</PRE> +</DIV> +<P> In this example, the typemap is applied to all occurrences of the <TT> +int</TT> datatype. You can refine this by supplying an optional + parameter name. For example:</P> +<DIV class="code"> +<PRE> +%module example + +%typemap(in) int nonnegative { + $1 = (int) PyLong_AsLong($input); + if ($1 < 0) { + PyErr_SetString(PyExc_ValueError,"Expected a nonnegative value."); + return NULL; + } +} +%inline %{ +extern int fact(int nonnegative); +%} +</PRE> +</DIV> +<P> In this case, the typemap code is only attached to arguments that + exactly match <TT>int nonnegative</TT>.</P> +<P> The application of a typemap to specific datatypes and argument + names involves more than simple text-matching--typemaps are fully + integrated into the SWIG C++ type-system. When you define a typemap for + <TT>int</TT>, that typemap applies to <TT>int</TT> and qualified + variations such as <TT>const int</TT>. In addition, the typemap system + follows <TT>typedef</TT> declarations. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int n { + $1 = (int) PyLong_AsLong($input); + printf("n = %d\n",$1); +} +%inline %{ +typedef int Integer; +extern int fact(Integer n); // Above typemap is applied +%} +</PRE> +</DIV> +<P> Typemaps can also be defined for groups of consecutive arguments. + For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (char *str, int len) { + $1 = PyString_AsString($input); + $2 = PyString_Size($input); +}; + +int count(char c, char *str, int len); +</PRE> +</DIV> +<P> When a multi-argument typemap is defined, the arguments are always + handled as a single Python object. This allows the function to be used + like this (notice how the length parameter is omitted):</P> +<DIV class="targetlang"> +<PRE> +>>> example.count('e','Hello World') +1 +>>> +</PRE> +</DIV> +<H3><A name="Python_nn55"></A>31.8.2 Python typemaps</H3> +<P> The previous section illustrated an "in" typemap for converting + Python objects to C. A variety of different typemap methods are defined + by the Python module. For example, to convert a C integer back into a + Python object, you might define an "out" typemap like this:</P> +<DIV class="code"> +<PRE> +%typemap(out) int { + $result = PyInt_FromLong((long) $1); +} +</PRE> +</DIV> +<P> A detailed list of available methods can be found in the "<A href="#Typemaps"> +Typemaps</A>" chapter.</P> +<P> However, the best source of typemap information (and examples) is + probably the Python module itself. In fact, all of SWIG's default type + handling is defined by typemaps. You can view these typemaps by looking + at the files in the SWIG library. Just take into account that in the + latest versions of swig (1.3.22+), the library files are not very + pristine clear for the casual reader, as they used to be. The extensive + use of macros and other ugly techniques in the latest version produce a + very powerful and consistent python typemap library, but at the cost of + simplicity and pedagogic value.</P> +<P> To learn how to write a simple or your first typemap, you better + take a look at the SWIG library version 1.3.20 or so.</P> +<H3><A name="Python_nn56"></A>31.8.3 Typemap variables</H3> +<P> Within typemap code, a number of special variables prefaced with a <TT> +$</TT> may appear. A full list of variables can be found in the "<A href="#Typemaps"> +Typemaps</A>" chapter. This is a list of the most common variables:</P> +<P> <TT>$1</TT></P> +<DIV class="indent"> A C local variable corresponding to the actual type + specified in the <TT>%typemap</TT> directive. For input values, this is + a C local variable that's supposed to hold an argument value. For + output values, this is the raw result that's supposed to be returned to + Python.</DIV> +<P> <TT>$input</TT></P> +<DIV class="indent"> A <TT>PyObject *</TT> holding a raw Python object + with an argument or variable value.</DIV> +<P> <TT>$result</TT></P> +<DIV class="indent"> A <TT>PyObject *</TT> that holds the result to be + returned to Python.</DIV> +<P> <TT>$1_name</TT></P> +<DIV class="indent"> The parameter name that was matched.</DIV> +<P> <TT>$1_type</TT></P> +<DIV class="indent"> The actual C datatype matched by the typemap.</DIV> +<P> <TT>$1_ltype</TT></P> +<DIV class="indent"> An assignable version of the datatype matched by + the typemap (a type that can appear on the left-hand-side of a C + assignment operation). This type is stripped of qualifiers and may be + an altered version of <TT>$1_type</TT>. All arguments and local + variables in wrapper functions are declared using this type so that + their values can be properly assigned.</DIV> +<P> <TT>$symname</TT></P> +<DIV class="indent"> The Python name of the wrapper function being + created.</DIV> +<H3><A name="Python_nn57"></A>31.8.4 Useful Python Functions</H3> +<P> When you write a typemap, you usually have to work directly with + Python objects. The following functions may prove to be useful.</P> +<P><B> Python Integer Functions</B></P> +<DIV class="code"> +<PRE> +PyObject *PyInt_FromLong(long l); +long PyInt_AsLong(PyObject *); +int PyInt_Check(PyObject *); +</PRE> +</DIV> +<P><B> Python Floating Point Functions</B></P> +<DIV class="code"> +<PRE> +PyObject *PyFloat_FromDouble(double); +double PyFloat_AsDouble(PyObject *); +int PyFloat_Check(PyObject *); +</PRE> +</DIV> +<P><B> Python String Functions</B></P> +<DIV class="code"> +<PRE> +PyObject *PyString_FromString(char *); +PyObject *PyString_FromStringAndSize(char *, lint len); +int PyString_Size(PyObject *); +char *PyString_AsString(PyObject *); +int PyString_Check(PyObject *); +</PRE> +</DIV> +<P><B> Python List Functions</B></P> +<DIV class="code"> +<PRE> +PyObject *PyList_New(int size); +int PyList_Size(PyObject *list); +PyObject *PyList_GetItem(PyObject *list, int i); +int PyList_SetItem(PyObject *list, int i, PyObject *item); +int PyList_Insert(PyObject *list, int i, PyObject *item); +int PyList_Append(PyObject *list, PyObject *item); +PyObject *PyList_GetSlice(PyObject *list, int i, int j); +int PyList_SetSlice(PyObject *list, int i, int , PyObject *list2); +int PyList_Sort(PyObject *list); +int PyList_Reverse(PyObject *list); +PyObject *PyList_AsTuple(PyObject *list); +int PyList_Check(PyObject *); +</PRE> +</DIV> +<P><B> Python Tuple Functions</B></P> +<DIV class="code"> +<PRE> +PyObject *PyTuple_New(int size); +int PyTuple_Size(PyObject *); +PyObject *PyTuple_GetItem(PyObject *, int i); +int PyTuple_SetItem(PyObject *, int i, PyObject *item); +PyObject *PyTuple_GetSlice(PyObject *t, int i, int j); +int PyTuple_Check(PyObject *); +</PRE> +</DIV> +<P><B> Python Dictionary Functions</B></P> +<DIV class="code"> +<PRE> +PyObject *PyDict_New(); +int PyDict_Check(PyObject *); +int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val); +int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val); +int PyDict_DelItem(PyObject *p, PyObject *key); +int PyDict_DelItemString(PyObject *p, char *key); +PyObject* PyDict_Keys(PyObject *p); +PyObject* PyDict_Values(PyObject *p); +PyObject* PyDict_GetItem(PyObject *p, PyObject *key); +PyObject* PyDict_GetItemString(PyObject *p, const char *key); +int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue); +Py_ssize_t PyDict_Size(PyObject *p); +int PyDict_Update(PyObject *a, PyObject *b); +int PyDict_Merge(PyObject *a, PyObject *b, int override); +PyObject* PyDict_Items(PyObject *p); +</PRE> +</DIV> +<P><B> Python File Conversion Functions</B></P> +<DIV class="code"> +<PRE> +PyObject *PyFile_FromFile(FILE *f); +FILE *PyFile_AsFile(PyObject *); +int PyFile_Check(PyObject *); +</PRE> +</DIV> +<P><B> Abstract Object Interface</B></P> +<DIV class="code"> +<PRE> +write me +</PRE> +</DIV> +<H2><A name="Python_nn58"></A>31.9 Typemap Examples</H2> +<P> This section includes a few examples of typemaps. For more examples, + you might look at the files "<TT>python.swg</TT>" and "<TT>typemaps.i</TT> +" in the SWIG library.</P> +<H3><A name="Python_nn59"></A>31.9.1 Converting Python list to a char **</H3> +<P> A common problem in many C programs is the processing of command + line arguments, which are usually passed in an array of NULL terminated + strings. The following SWIG interface file allows a Python list object + to be used as a <TT>char **</TT> object.</P> +<DIV class="code"> +<PRE> +%module argv + +// This tells SWIG to treat char ** as a special case +%typemap(in) char ** { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $1 = (char **) malloc((size+1)*sizeof(char *)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyString_Check(o)) + $1[i] = PyString_AsString(PyList_GetItem($input,i)); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free($1); + return NULL; + } + } + $1[i] = 0; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +// This cleans up the char ** array we malloc'd before the function call +%typemap(freearg) char ** { + free((char *) $1); +} + +// Now a test function +%inline %{ +int print_args(char **argv) { + int i = 0; + while (argv[i]) { + printf("argv[%d] = %s\n", i,argv[i]); + i++; + } + return i; +} +%} + +</PRE> +</DIV> +<P> When this module is compiled, the wrapped C function now operates as + follows :</P> +<DIV class="targetlang"> +<PRE> +>>> from argv import * +>>> print_args(["Dave","Mike","Mary","Jane","John"]) +argv[0] = Dave +argv[1] = Mike +argv[2] = Mary +argv[3] = Jane +argv[4] = John +5 +</PRE> +</DIV> +<P> In the example, two different typemaps are used. The "in" typemap is + used to receive an input argument and convert it to a C array. Since + dynamic memory allocation is used to allocate memory for the array, the + "freearg" typemap is used to later release this memory after the + execution of the C function.</P> +<H3><A name="Python_nn60"></A>31.9.2 Expanding a Python object into + multiple arguments</H3> +<P> Suppose that you had a collection of C functions with arguments such + as the following:</P> +<DIV class="code"> +<PRE> +int foo(int argc, char **argv); +</PRE> +</DIV> +<P> In the previous example, a typemap was written to pass a Python list + as the <TT>char **argv</TT>. This allows the function to be used from + Python as follows:</P> +<DIV class="targetlang"> +<PRE> +>>> foo(4, ["foo","bar","spam","1"]) +</PRE> +</DIV> +<P> Although this works, it's a little awkward to specify the argument + count. To fix this, a multi-argument typemap can be defined. This is + not very difficult--you only have to make slight modifications to the + previous example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (int argc, char **argv) { + /* Check if is a list */ + if (PyList_Check($input)) { + int i; + $1 = PyList_Size($input); + $2 = (char **) malloc(($1+1)*sizeof(char *)); + for (i = 0; i < $1; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyString_Check(o)) + $2[i] = PyString_AsString(PyList_GetItem($input,i)); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free($2); + return NULL; + } + } + $2[i] = 0; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(freearg) (int argc, char **argv) { + free((char *) $2); +} +</PRE> +</DIV> +<P> When writing a multiple-argument typemap, each of the types is + referenced by a variable such as <TT>$1</TT> or <TT>$2</TT>. The + typemap code simply fills in the appropriate values from the supplied + Python object.</P> +<P> With the above typemap in place, you will find it no longer + necessary to supply the argument count. This is automatically set by + the typemap code. For example:</P> +<DIV class="targetlang"> +<PRE> +>>> foo(["foo","bar","spam","1"]) +</PRE> +</DIV> +<H3><A name="Python_nn61"></A>31.9.3 Using typemaps to return arguments</H3> +<P> A common problem in some C programs is that values may be returned + in arguments rather than in the return value of a function. For + example:</P> +<DIV class="code"> +<PRE> +/* Returns a status value and two values in out1 and out2 */ +int spam(double a, double b, double *out1, double *out2) { + ... Do a bunch of stuff ... + *out1 = result1; + *out2 = result2; + return status; +}; + +</PRE> +</DIV> +<P> A typemap can be used to handle this case as follows :</P> +<DIV class="code"> +<PRE> +%module outarg + +// This tells SWIG to treat an double * argument with name 'OutValue' as +// an output value. We'll append the value to the current result which +// is guaranteed to be a List object by SWIG. + +%typemap(argout) double *OutValue { + PyObject *o, *o2, *o3; + o = PyFloat_FromDouble(*$1); + if ((!$result) || ($result == Py_None)) { + $result = o; + } else { + if (!PyTuple_Check($result)) { + PyObject *o2 = $result; + $result = PyTuple_New(1); + PyTuple_SetItem(target,0,o2); + } + o3 = PyTuple_New(1); + PyTuple_SetItem(o3,0,o); + o2 = $result; + $result = PySequence_Concat(o2,o3); + Py_DECREF(o2); + Py_DECREF(o3); + } +} + +int spam(double a, double b, double *OutValue, double *OutValue); + +</PRE> +</DIV> +<P> The typemap works as follows. First, a check is made to see if any + previous result exists. If so, it is turned into a tuple and the new + output value is concatenated to it. Otherwise, the result is returned + normally. For the sample function <TT>spam()</TT>, there are three + output values--meaning that the function will return a 3-tuple of the + results.</P> +<P> As written, the function must accept 4 arguments as input values, + last two being pointers to doubles. If these arguments are only used to + hold output values (and have no meaningful input value), an additional + typemap can be written. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in,numinputs=0) double *OutValue(double temp) { + $1 = &temp; +} + +</PRE> +</DIV> +<P> By specifying numinputs=0, the input value is ignored. However, + since the argument still has to be set to some meaningful value before + calling C, it is set to point to a local variable <TT>temp</TT>. When + the function stores its output value, it will simply be placed in this + local variable. As a result, the function can now be used as follows:</P> +<DIV class="targetlang"> +<PRE> +>>> a = spam(4,5) +>>> print a +(0, 2.45, 5.0) +>>> x,y,z = spam(4,5) +>>> +</PRE> +</DIV> +<H3><A name="Python_nn62"></A>31.9.4 Mapping Python tuples into small + arrays</H3> +<P> In some applications, it is sometimes desirable to pass small arrays + of numbers as arguments. For example :</P> +<DIV class="code"> +<PRE> +extern void set_direction(double a[4]); // Set direction vector +</PRE> +</DIV> +<P> This too, can be handled used typemaps as follows :</P> +<DIV class="code"> +<PRE> +// Grab a 4 element array as a Python 4-tuple +%typemap(in) double[4](double temp[4]) { // temp[4] becomes a local variable + int i; + if (PyTuple_Check($input)) { + if (!PyArg_ParseTuple($input,"dddd",temp,temp+1,temp+2,temp+3)) { + PyErr_SetString(PyExc_TypeError,"tuple must have 4 elements"); + return NULL; + } + $1 = &temp[0]; + } else { + PyErr_SetString(PyExc_TypeError,"expected a tuple."); + return NULL; + } +} + +</PRE> +</DIV> +<P> This allows our <TT>set_direction</TT> function to be called from + Python as follows :</P> +<DIV class="targetlang"> +<PRE> +>>> set_direction((0.5,0.0,1.0,-0.25)) +</PRE> +</DIV> +<P> Since our mapping copies the contents of a Python tuple into a C + array, such an approach would not be recommended for huge arrays, but + for small structures, this approach works fine.</P> +<H3><A name="Python_nn63"></A>31.9.5 Mapping sequences to C arrays</H3> +<P> Suppose that you wanted to generalize the previous example to handle + C arrays of different sizes. To do this, you might write a typemap as + follows:</P> +<DIV class="code"> +<PRE> +// Map a Python sequence into any sized C double array +%typemap(in) double[ANY](double temp[$1_dim0]) { + int i; + if (!PySequence_Check($input)) { + PyErr_SetString(PyExc_TypeError,"Expecting a sequence"); + return NULL; + } + if (PyObject_Length($input) != $1_dim0) { + PyErr_SetString(PyExc_ValueError,"Expecting a sequence with $1_dim0 elements"); + return NULL; + } + for (i =0; i < $1_dim0; i++) { + PyObject *o = PySequence_GetItem($input,i); + if (!PyFloat_Check(o)) { + Py_XDECREF(o); + PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats"); + return NULL; + } + temp[i] = PyFloat_AsDouble(o); + Py_DECREF(o); + } + $1 = &temp[0]; +} +</PRE> +</DIV> +<P> In this case, the variable <TT>$1_dim0</TT> is expanded to match the + array dimensions actually used in the C code. This allows the typemap + to be applied to types such as:</P> +<DIV class="code"> +<PRE> +void foo(double x[10]); +void bar(double a[4], double b[8]); +</PRE> +</DIV> +<P> Since the above typemap code gets inserted into every wrapper + function where used, it might make sense to use a helper function + instead. This will greatly reduce the amount of wrapper code. For + example:</P> +<DIV class="code"> +<PRE> +%{ +static int convert_darray(PyObject *input, double *ptr, int size) { + int i; + if (!PySequence_Check(input)) { + PyErr_SetString(PyExc_TypeError,"Expecting a sequence"); + return 0; + } + if (PyObject_Length(input) != size) { + PyErr_SetString(PyExc_ValueError,"Sequence size mismatch"); + return 0; + } + for (i =0; i < size; i++) { + PyObject *o = PySequence_GetItem(input,i); + if (!PyFloat_Check(o)) { + Py_XDECREF(o); + PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats"); + return 0; + } + ptr[i] = PyFloat_AsDouble(o); + Py_DECREF(o); + } + return 1; +} +%} + +%typemap(in) double [ANY](double temp[$1_dim0]) { + if (!convert_darray($input,temp,$1_dim0))) { + return NULL; + } + $1 = &temp[0]; +} +</PRE> +</DIV> +<H3><A name="Python_nn64"></A>31.9.6 Pointer handling</H3> +<P> Occasionally, it might be necessary to convert pointer values that + have been stored using the SWIG typed-pointer representation. Since + there are several ways in which pointers can be represented, the + following two functions are used to safely perform this conversion:</P> +<P> <TT>int SWIG_ConvertPtr(PyObject *obj, void **ptr, swig_type_info + *ty, int flags)</TT></P> +<DIV class="indent"> Converts a Python object <TT>obj</TT> to a C + pointer. The result of the conversion is placed into the pointer + located at <TT>ptr</TT>. <TT>ty</TT> is a SWIG type descriptor + structure. <TT>flags</TT> is used to handle error checking and other + aspects of conversion. It is the bitwise-or of several flag values + including <TT>SWIG_POINTER_EXCEPTION</TT> and <TT>SWIG_POINTER_DISOWN</TT> +. The first flag makes the function raise an exception on type error. + The second flag additionally steals ownership of an object. Returns 0 + on success and -1 on error.</DIV> +<P> <TT>PyObject *SWIG_NewPointerObj(void *ptr, swig_type_info *ty, int + own)</TT></P> +<DIV class="indent"> Creates a new Python pointer object. <TT>ptr</TT> + is the pointer to convert, <TT>ty</TT> is the SWIG type descriptor + structure that describes the type, and <TT>own</TT> is a flag that + indicates whether or not Python should take ownership of the pointer.</DIV> +<P> Both of these functions require the use of a special SWIG + type-descriptor structure. This structure contains information about + the mangled name of the datatype, type-equivalence information, as well + as information about converting pointer values under C++ inheritance. + For a type of <TT>Foo *</TT>, the type descriptor structure is usually + accessed as follows:</P> +<DIV class="code"> +<PRE> +Foo *f; +if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, SWIG_POINTER_EXCEPTION) == -1) + return NULL; + +PyObject *obj; +obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0); +</PRE> +</DIV> +<P> In a typemap, the type descriptor should always be accessed using + the special typemap variable <TT>$1_descriptor</TT>. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) Foo * { +if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1) + return NULL; +} +</PRE> +</DIV> +<P> If necessary, the descriptor for any type can be obtained using the <TT> +$descriptor()</TT> macro in a typemap. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) Foo * { +if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), + SWIG_POINTER_EXCEPTION)) == -1) + return NULL; +} +</PRE> +</DIV> +<P> Although the pointer handling functions are primarily intended for + manipulating low-level pointers, both functions are fully aware of + Python proxy classes. Specifically, <TT>SWIG_ConvertPtr()</TT> will + retrieve a pointer from any object that has a <TT>this</TT> attribute. + In addition, <TT>SWIG_NewPointerObj()</TT> can automatically generate a + proxy class object (if applicable).</P> +<H2><A name="Python_nn65"></A>31.10 Docstring Features</H2> +<P> Using docstrings in Python code is becoming more and more important + and more tools are coming on the scene that take advantage of them, + everything from full-blown documentation generators to class browsers + and popup call-tips in Python-aware IDEs. Given the way that SWIG + generates the proxy code by default, your users will normally get + something like <TT>"function_name(*args)"</TT> in the popup calltip of + their IDE which is next to useless when the real function prototype + might be something like this:</P> +<DIV class="code"> +<PRE> +bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL); +</PRE> +</DIV> +<P> The features described in this section make it easy for you to add + docstrings to your modules, functions and methods that can then be used + by the various tools out there to make the programming experience of + your users much simpler.</P> +<H3><A name="Python_nn66"></A>31.10.1 Module docstring</H3> +<P> Python allows a docstring at the beginning of the <TT>.py</TT> file + before any other statements, and it is typically used to give a general + description of the entire module. SWIG supports this by setting an + option of the <TT>%module</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%module(docstring="This is the example module's docstring") example +</PRE> +</DIV> +<P> When you have more than just a line or so then you can retain the + easy readability of the <TT>%module</TT> directive by using a macro. + For example:</P> +<DIV class="code"> +<PRE> +%define DOCSTRING +"The `XmlResource` class allows program resources defining menus, +layout of controls on a panel, etc. to be loaded from an XML file." +%enddef + +%module(docstring=DOCSTRING) xrc +</PRE> +</DIV> +<H3><A name="Python_nn67"></A>31.10.2 %feature("autodoc")</H3> +<P> As alluded to above SWIG will generate all the function and method + proxy wrappers with just "*args" (or "*args, **kwargs" if the -keyword + option is used) for a parameter list and will then sort out the + individual parameters in the C wrapper code. This is nice and simple + for the wrapper code, but makes it difficult to be programmer and tool + friendly as anyone looking at the <TT>.py</TT> file will not be able to + find out anything about the parameters that the functions accept.</P> +<P>But since SWIG does know everything about the function it is possible + to generate a docstring containing the parameter types, names and + default values. Since many of the docstring tools are adopting a + standard of recognizing if the first thing in the docstring is a + function prototype then using that instead of what they found from + introspection, then life is good once more.</P> +<P>SWIG's Python module provides support for the "autodoc" feature, + which when attached to a node in the parse tree will cause a docstring + to be generated that includes the name of the function, parameter + names, default values if any, and return type if any. There are also + three options for autodoc controlled by the value given to the feature, + described below.</P> +<H4><A name="Python_nn68"></A>31.10.2.1 %feature("autodoc", "0")</H4> +<P> When the "0" option is given then the types of the parameters will<EM> + not</EM> be included in the autodoc string. For example, given this + function prototype:</P> +<DIV class="code"> +<PRE> +%feature("autodoc", "0"); +bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL); +</PRE> +</DIV> +<P> Then Python code like this will be generated:</P> +<DIV class="targetlang"> +<PRE> +def function_name(*args, **kwargs): + """function_name(x, y, foo=None, bar=None) -> bool""" + ... +</PRE> +</DIV> +<H4><A name="Python_nn69"></A>31.10.2.2 %feature("autodoc", "1")</H4> +<P> When the "1" option is used then the parameter types<EM> will</EM> + be used in the autodoc string. In addition, an attempt is made to + simplify the type name such that it makes more sense to the Python + user. Pointer, reference and const info is removed, <TT>%rename</TT>'s + are evaluated, etc. (This is not always successful, but works most of + the time. See the next section for what to do when it doesn't.) Given + the example above, then turning on the parameter types with the "1" + option will result in Python code like this:</P> +<DIV class="targetlang"> +<PRE> +def function_name(*args, **kwargs): + """function_name(int x, int y, Foo foo=None, Bar bar=None) -> bool""" + ... +</PRE> +</DIV> +<H4><A name="Python_nn70"></A>31.10.2.3 %feature("autodoc", "docstring")</H4> +<P> Finally, there are times when the automatically generated autodoc + string will make no sense for a Python programmer, particularly when a + typemap is involved. So if you give an explicit value for the autodoc + feature then that string will be used in place of the automatically + generated string. For example:</P> +<DIV class="code"> +<PRE> +%feature("autodoc", "GetPosition() -> (x, y)") GetPosition; +void GetPosition(int* OUTPUT, int* OUTPUT); +</PRE> +</DIV> +<H3><A name="Python_nn71"></A>31.10.3 %feature("docstring")</H3> +<P> In addition to the autodoc strings described above, you can also + attach any arbitrary descriptive text to a node in the parse tree with + the "docstring" feature. When the proxy module is generated then any + docstring associated with classes, function or methods are output. If + an item already has an autodoc string then it is combined with the + docstring and they are output together. If the docstring is all on a + single line then it is output like this::</P> +<DIV class="targetlang"> +<PRE> +"""This is the docstring""" +</PRE> +</DIV> +<P> Otherwise, to aid readability it is output like this:</P> +<DIV class="targetlang"> +<PRE> +""" +This is a multi-line docstring +with more than one line. +""" +</PRE> +</DIV> +<H2><A name="Python_nn72"></A>31.11 Python Packages</H2> +<P> Using the <TT>package</TT> option of the <TT>%module</TT> directive + allows you to specify what Python package that the module will be + living in when installed.</P> +<DIV class="code"> +<PRE> +%module(package="wx") xrc +</PRE> +</DIV> +<P> This is useful when the <TT>.i</TT> file is <TT>%import</TT>ed by + another <TT>.i</TT> file. By default SWIG will assume that the importer + is able to find the importee with just the module name, but if they + live in separate Python packages then that won't work. However if the + importee specifies what its package is with the <TT>%module</TT> option + then the Python code generated for the importer will use that package + name when importing the other module and also in base class + declarations, etc. if the package name is different than its own.</P> +<H2><A name="Python_python3support"></A>31.12 Python 3 Support</H2> +<P> SWIG is able to support Python 3.0. The wrapper code generated by + SWIG can be compiled with both Python 2.x or 3.0. Further more, by + passing the <TT>-py3</TT> command line option to SWIG, wrapper code + with some Python 3 specific features can be generated (see below + subsections for details of these features). The <TT>-py3</TT> option + also disables some incompatible features for Python 3, such as <TT> +-classic</TT>.</P> +<P> There is a list of known-to-be-broken features in Python 3:</P> +<UL> +<LI>No more support for FILE* typemaps, because PyFile_AsFile has been + dropped in Python 3.</LI> +<LI>The <TT>-apply</TT> command line option is removed and generating + code using apply() is no longer supported.</LI> +</UL> +<P> The following are Python 3.0 new features that are currently + supported by SWIG.</P> +<H3><A name="Python_nn74"></A>31.12.1 Function annotation</H3> +<P> The <TT>-py3</TT> option will enable function annotation support. + When used SWIG is able to generate proxy method definitions like this:</P> +<DIV class="code"> +<PRE> + def foo(self, bar : "int" = 0) -> "void" : ... +</PRE> +</DIV> +<P> Also, even if without passing SWIG the <TT>-py3</TT> option, the + parameter list still could be generated:</P> +<DIV class="code"> +<PRE> + def foo(self, bar = 0): ... +</PRE> +</DIV> +<P> But for overloaded function or method, the parameter list would + fallback to <TT>*args</TT> or <TT>self, *args</TT>, and <TT>**kwargs</TT> + may be append depend on whether you enabled the keyword argument. This + fallback is due to all overloaded functions share the same function in + SWIG generated proxy class.</P> +<P> For detailed usage of function annotation, see PEP 3107.</P> +<H3><A name="Python_nn75"></A>31.12.2 Buffer interface</H3> +<P> Buffer protocols were revised in Python 3. SWIG also gains a series + of new typemaps to support buffer interfaces. These typemap macros are + defined in <TT>pybuffer.i</TT>, which must be included in order to use + them. By using these typemaps, your wrapped function will be able to + accept any Python object that exposes a suitable buffer interface.</P> +<P> For example, the <TT>get_path()</TT> function puts the path string + into the memory pointed to by its argument:</P> +<DIV class="code"> +<PRE> +void get_path(char *s); +</PRE> +</DIV> +<P> Then you can write a typemap like this: (the following example is + applied to both Python 3.0 and 2.6, since the <TT>bytearray</TT> type + is backported to 2.6.</P> +<DIV class="code"> +<PRE> +%include <pybuffer.i> +%pybuffer_mutable_string(char *str); +void get_path(char *s); +</PRE> +</DIV> +<P> And then on the Python side the wrapped <TT>get_path</TT> could be + used in this way:</P> +<DIV class="targetlang"> +<PRE> +>>> p = bytearray(10) +>>> get_path(p) +>>> print(p) +bytearray(b'/Foo/Bar/\x00') +</PRE> +</DIV> +<P> The macros defined in <TT>pybuffer.i</TT> are similar to those in <TT> +cstring.i</TT>:</P> +<P><B> %pybuffer_mutable_binary(parm, size_parm)</B></P> +<DIV class="indent"> +<P> The macro can be used to generate a typemap which maps a buffer of + an object to a pointer provided by <TT>parm</TT> and a size argument + provided by <TT>size_parm</TT>. For example:</P> +<DIV class="code"> +<PRE> +%pybuffer_mutable_binary(char *str, size_t size); +... +int snprintf(char *str, size_t size, const char *format, ...); +</PRE> +</DIV> +<P> In Python:</P> +<DIV class="targetlang"> +<PRE> +>>> buf = bytearray(6) +>>> snprintf(buf, "Hello world!") +>>> print(buf) +bytearray(b'Hello\x00') +>>> +</PRE> +</DIV></DIV> +<P><B> %pybuffer_mutable_string(parm)</B></P> +<DIV class="indent"> +<P> This typemap macro requires the buffer to be a zero terminated + string, and maps the pointer of the buffer to <TT>parm</TT>. For + example:</P> +<DIV class="code"> +<PRE> +%pybuffer_mutable_string(char *str); +... +size_t make_upper(char *str); +</PRE> +</DIV> +<P> In Python:</P> +<DIV class="targetlang"> +<PRE> +>>> buf = bytearray(b'foo\x00') +>>> make_upper(buf) +>>> print(buf) +bytearray(b'FOO\x00') +>>> +</PRE> +</DIV> +<P> Both <TT>%pybuffer_mutable_binary</TT> and <TT> +%pybuffer_mutable_string</TT> require the provided buffer to be mutable, + eg. they can accept a <TT>bytearray</TT> type but can't accept an + immutable <TT>byte</TT> type.</P> +</DIV> +<P><B> %pybuffer_binary(parm, size_parm)</B></P> +<DIV class="indent"> +<P> This macro maps an object's buffer to a pointer <TT>parm</TT> and a + size <TT>size_parm</TT>. It is similar to <TT>%pybuffer_mutable_binary</TT> +, except the <TT>%pybuffer_binary</TT> an accept both mutable and + immutable buffers. As a result, the wrapped function should not modify + the buffer.</P> +</DIV> +<P><B> %pybuffer_string(parm)</B></P> +<DIV class="indent"> +<P> This macro maps an object's buffer as a string pointer <TT>parm</TT> +. It is similar to <TT>%pybuffer_mutable_string</TT> but the buffer + could be both mutable and immutable. And your function should not + modify the buffer.</P> +</DIV> +<H3><A name="Python_nn76"></A>31.12.3 Abstract base classes</H3> +<P> By including <TT>pyabc.i</TT> and using the <TT>-py3</TT> command + line option when calling SWIG, the proxy classes of the STL containers + will automatically gain an appropriate abstract base class. For + example, the following SWIG interface:</P> +<DIV class="code"> +<PRE> +%include <pyabc.i> +%include <std_map.i> +%include <std_list.i> + +namespace std { + %template(Mapii) map<int, int>; + %template(IntList) list<int>; +} +</PRE> +</DIV> +<P> will generate a Python proxy class <TT>Mapii</TT> inheriting from <TT> +collections.MutableMap</TT> and a proxy class <TT>IntList</TT> + inheriting from <TT>collections.MutableSequence</TT>.</P> +<P> <TT>pyabc.i</TT> also provides a macro <TT>%pythonabc</TT> that + could be used to define an abstract base class for your own C++ class:</P> +<DIV class="code"> +<PRE> +%pythonabc(MySet, collections.MutableSet); +</PRE> +</DIV> +<P> For details of abstract base class, please see PEP 3119.</P> + +<!-- LocalWords: polymorphism Typemaps STL typemap typemaps Docstring autodoc + --> + +<!-- LocalWords: docstring SWIG's cxx py GCC linux DLL gcc fPIC Wiki Xlinker + --> + +<!-- LocalWords: examplemodule DHAVE CONFIG lpython lm ldl mypython lsocket + --> + +<!-- LocalWords: lnsl lpthread distutils enums namespaces + --> +<HR NOSHADE> +<H1><A name="Ruby"></A>32 SWIG and Ruby</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Ruby_nn2">Preliminaries</A> +<UL> +<LI><A href="#Ruby_nn3">Running SWIG</A></LI> +<LI><A href="#Ruby_nn4">Getting the right header files</A></LI> +<LI><A href="#Ruby_nn5">Compiling a dynamic module</A></LI> +<LI><A href="#Ruby_nn6">Using your module</A></LI> +<LI><A href="#Ruby_nn7">Static linking</A></LI> +<LI><A href="#Ruby_nn8">Compilation of C++ extensions</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn9">Building Ruby Extensions under Windows 95/NT</A> +<UL> +<LI><A href="#Ruby_nn10">Running SWIG from Developer Studio</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn11">The Ruby-to-C/C++ Mapping</A> +<UL> +<LI><A href="#Ruby_nn12">Modules</A></LI> +<LI><A href="#Ruby_nn13">Functions</A></LI> +<LI><A href="#Ruby_nn14">Variable Linking</A></LI> +<LI><A href="#Ruby_nn15">Constants</A></LI> +<LI><A href="#Ruby_nn16">Pointers</A></LI> +<LI><A href="#Ruby_nn17">Structures</A></LI> +<LI><A href="#Ruby_nn18">C++ classes</A></LI> +<LI><A href="#Ruby_nn19">C++ Inheritance</A></LI> +<LI><A href="#Ruby_nn20">C++ Overloaded Functions</A></LI> +<LI><A href="#Ruby_nn21">C++ Operators</A></LI> +<LI><A href="#Ruby_nn22">C++ namespaces</A></LI> +<LI><A href="#Ruby_nn23">C++ templates</A></LI> +<LI><A href="#Ruby_nn23_1">C++ Standard Template Library (STL)</A></LI> +<LI><A href="#C_STL_Functors">C++ STL Functors</A></LI> +<LI><A href="#Ruby_C_Iterators">C++ STL Iterators</A></LI> +<LI><A href="#Ruby_nn24">C++ Smart Pointers</A></LI> +<LI><A href="#Ruby_nn25">Cross-Language Polymorphism</A> +<UL> +<LI><A href="#Ruby_nn26">Exception Unrolling</A></LI> +</UL> +</LI> +</UL> +</LI> +<LI><A href="#Ruby_nn27">Naming</A> +<UL> +<LI><A href="#Ruby_nn28">Defining Aliases</A></LI> +<LI><A href="#Ruby_nn29">Predicate Methods</A></LI> +<LI><A href="#Ruby_nn30">Bang Methods</A></LI> +<LI><A href="#Ruby_nn31">Getters and Setters</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn32">Input and output parameters</A></LI> +<LI><A href="#Ruby_nn33">Exception handling</A> +<UL> +<LI><A href="#Ruby_nn34">Using the %exception directive</A></LI> +<LI><A href="#Ruby_nn34_2">Handling Ruby Blocks</A></LI> +<LI><A href="#Ruby_nn35">Raising exceptions</A></LI> +<LI><A href="#Ruby_nn36">Exception classes</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn37">Typemaps</A> +<UL> +<LI><A href="#Ruby_nn38">What is a typemap?</A></LI> +<LI><A href="#Ruby_Typemap_scope">Typemap scope</A></LI> +<LI><A href="#Ruby_Copying_a_typemap">Copying a typemap</A></LI> +<LI><A href="#Ruby_Deleting_a_typemap">Deleting a typemap</A></LI> +<LI><A href="#Ruby_Placement_of_typemaps">Placement of typemaps</A></LI> +<LI><A href="#Ruby_nn39">Ruby typemaps</A> +<UL> +<LI><A href="#Ruby_in_typemap"> "in" typemap</A></LI> +<LI><A href="#Ruby_typecheck_typemap">"typecheck" typemap</A></LI> +<LI><A href="#Ruby_out_typemap"> "out" typemap</A></LI> +<LI><A href="#Ruby_arginit_typemap">"arginit" typemap</A></LI> +<LI><A href="#Ruby_default_typemap">"default" typemap</A></LI> +<LI><A href="#Ruby_check_typemap">"check" typemap</A></LI> +<LI><A href="#Ruby_argout_typemap_">"argout" typemap</A></LI> +<LI><A href="#Ruby_freearg_typemap_">"freearg" typemap</A></LI> +<LI><A href="#Ruby_newfree_typemap">"newfree" typemap</A></LI> +<LI><A href="#Ruby_memberin_typemap">"memberin" typemap</A></LI> +<LI><A href="#Ruby_varin_typemap">"varin" typemap</A></LI> +<LI><A href="#Ruby_varout_typemap_">"varout" typemap</A></LI> +<LI><A href="#Ruby_throws_typemap">"throws" typemap</A></LI> +<LI><A href="#Ruby_directorin_typemap">directorin typemap</A></LI> +<LI><A href="#Ruby_directorout_typemap">directorout typemap</A></LI> +<LI><A href="#Ruby_directorargout_typemap">directorargout typemap</A></LI> +<LI><A href="#Ruby_ret_typemap">ret typemap</A></LI> +<LI><A href="#Ruby_globalin_typemap">globalin typemap</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn40">Typemap variables</A></LI> +<LI><A href="#Ruby_nn41">Useful Functions</A> +<UL> +<LI><A href="#Ruby_nn42">C Datatypes to Ruby Objects</A></LI> +<LI><A href="#Ruby_nn43">Ruby Objects to C Datatypes</A></LI> +<LI><A href="#Ruby_nn44">Macros for VALUE</A></LI> +<LI><A href="#Ruby_nn45">Exceptions</A></LI> +<LI><A href="#Ruby_nn46">Iterators</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn47">Typemap Examples</A></LI> +<LI><A href="#Ruby_nn48">Converting a Ruby array to a char **</A></LI> +<LI><A href="#Ruby_nn49">Collecting arguments in a hash</A></LI> +<LI><A href="#Ruby_nn50">Pointer handling</A> +<UL> +<LI><A href="#Ruby_nn51">Ruby Datatype Wrapping</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn52">Example: STL Vector to Ruby Array</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn65">Docstring Features</A> +<UL> +<LI><A href="#Ruby_nn66">Module docstring</A></LI> +<LI><A href="#Ruby_nn67">%feature("autodoc")</A> +<UL> +<LI><A href="#Ruby_nn68">%feature("autodoc", "0")</A></LI> +<LI><A href="#Ruby_autodoc1">%feature("autodoc", "1")</A></LI> +<LI><A href="#Ruby_autodoc2">%feature("autodoc", "2")</A></LI> +<LI><A href="#Ruby_feature_autodoc3">%feature("autodoc", "3")</A></LI> +<LI><A href="#Ruby_nn70">%feature("autodoc", "docstring")</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn71">%feature("docstring")</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn53">Advanced Topics</A> +<UL> +<LI><A href="#Ruby_nn54">Operator overloading</A></LI> +<LI><A href="#Ruby_nn55">Creating Multi-Module Packages</A></LI> +<LI><A href="#Ruby_nn56">Specifying Mixin Modules</A></LI> +</UL> +</LI> +<LI><A href="#Ruby_nn57">Memory Management</A> +<UL> +<LI><A href="#Ruby_nn58">Mark and Sweep Garbage Collector</A></LI> +<LI><A href="#Ruby_nn59">Object Ownership</A></LI> +<LI><A href="#Ruby_nn60">Object Tracking</A></LI> +<LI><A href="#Ruby_nn61">Mark Functions</A></LI> +<LI><A href="#Ruby_nn62">Free Functions</A></LI> +<LI><A href="#Ruby_nn63">Embedded Ruby and the C++ Stack</A></LI> +</UL> +</LI> +</UL> +</DIV> +<!-- INDEX --> +<P>This chapter describes SWIG's support of Ruby.</P> +<H2><A name="Ruby_nn2"></A>32.1 Preliminaries</H2> +<P> SWIG 1.3 is known to work with Ruby versions 1.6 and later. Given + the choice, you should use the latest stable version of Ruby. You + should also determine if your system supports shared libraries and + dynamic loading. SWIG will work with or without dynamic loading, but + the compilation process will vary.</P> +<P>This chapter covers most SWIG features, but in less depth than is + found in earlier chapters. At the very least, make sure you also read + the "<A href="#SWIG">SWIG Basics</A>" chapter. It is also assumed that + the reader has a basic understanding of Ruby.</P> +<H3><A name="Ruby_nn3"></A>32.1.1 Running SWIG</H3> +<P> To build a Ruby module, run SWIG using the <TT>-ruby</TT> option:</P> +<DIV class="code shell"> +<PRE>$ <B>swig -ruby example.i</B> +</PRE> +</DIV> +<P> If building a C++ extension, add the <TT>-c++</TT> option:</P> +<DIV class="code shell"> +<PRE>$ <B>swig -c++ -ruby example.i</B> +</PRE> +</DIV> +<P> This creates a file <TT>example_wrap.c</TT> (<TT>example_wrap.cxx</TT> + if compiling a C++ extension) that contains all of the code needed to + build a Ruby extension module. To finish building the module, you need + to compile this file and link it with the rest of your program.</P> +<H3><A name="Ruby_nn4"></A>32.1.2 Getting the right header files</H3> +<P> In order to compile the wrapper code, the compiler needs the <TT> +ruby.h</TT> header file. This file is usually contained in a directory + such as</P> +<DIV class="code shell diagram"> +<PRE>/usr/lib/ruby/1.8/x86_64-linux-gnu/ruby.h +<BR>/usr/local/lib/ruby/1.6/i686-linux/ruby.h +<BR></PRE> +</DIV> +<P> The exact location may vary on your machine, but the above location + is typical. If you are not entirely sure where Ruby is installed, you + can run Ruby to find out. For example:</P> +<DIV class="code shell"> +<PRE>$ <B>ruby -e 'puts $:.join("\n")'</B> +<BR>/usr/local/lib/ruby/site_ruby/1.6 /usr/local/lib/ruby/site_ruby/1.6/i686-linux +<BR>/usr/local/lib/ruby/site_ruby /usr/local/lib/ruby/1.6 /usr/local/lib/ruby/1.6/i686-linux . +<BR> </PRE> +</DIV> +<H3><A name="Ruby_nn5"></A>32.1.3 Compiling a dynamic module</H3> +<P> Ruby extension modules are typically compiled into shared libraries + that the interpreter loads dynamically at runtime. Since the exact + commands for doing this vary from platform to platform, your best bet + is to follow the steps described in the <TT>README.EXT</TT> file from + the Ruby distribution:</P> +<OL> +<LI> +<P>Create a file called <TT>extconf.rb</TT> that looks like the + following:</P> +<DIV class="code targetlang"> +<PRE>require 'mkmf' +<BR>create_makefile('example') +<BR></PRE> +</DIV></LI> +<LI> +<P>Type the following to build the extension:</P> +<DIV class="code shell"> +<PRE>$ <B>ruby extconf.rb</B> +<BR>$ <B>make</B> +<BR>$ <B>make install</B> + </PRE> +</DIV></LI> +</OL> +<P> Of course, there is the problem that mkmf does not work correctly on + all platforms, e.g, HPUX. If you need to add your own make rules to the + file that <TT>extconf.rb</TT> produces, you can add this:</P> +<DIV class="code targetlang"> +<PRE>open("Makefile", "a") { |mf| +<BR> puts <<EOM +<BR> # Your make rules go here +<BR> EOM +<BR>} +<BR></PRE> +</DIV> +<P> to the end of the <TT>extconf.rb</TT> file. If for some reason you + don't want to use the standard approach, you'll need to determine the + correct compiler and linker flags for your build platform. For example, + a typical sequence of commands for the Linux operating system would + look something like this:</P> +<DIV class="code shell"> +<PRE>$ <B>swig -ruby example.i</B> +<BR>$ <B>gcc -c example.c</B> +<BR>$ <B>gcc -c example_wrap.c -I/usr/local/lib/ruby/1.6/i686-linux</B> +<BR>$ <B>gcc -shared example.o example_wrap.o -o example.so</B> +</PRE> +</DIV> +<P> For other platforms it may be necessary to compile with the <TT> +-fPIC</TT> option to generate position-independent code. If in doubt, + consult the manual pages for your compiler and linker to determine the + correct set of options. You might also check the <A href="http://www.dabeaz.com/cgi-bin/wiki.pl"> +SWIG Wiki</A> for additional information.</P> +<H3><A name="Ruby_nn6"></A>32.1.4 Using your module</H3> +<P> Ruby<I> module</I> names must be capitalized, but the convention for + Ruby<I> feature</I> names is to use lowercase names. So, for example, + the<B> Etc</B> extension module is imported by requiring the<B> etc</B> + feature:</P> +<DIV class="code targetlang"> +<PRE># The feature name begins with a lowercase letter... +<BR>require 'etc' +<BR> +<BR># ... but the module name begins with an uppercase letter +<BR>puts "Your login name: #{Etc.getlogin}" +<BR></PRE> +</DIV> +<P> To stay consistent with this practice, you should always specify a<B> + lowercase</B> module name with SWIG's <TT>%module</TT> directive. SWIG + will automatically correct the resulting Ruby module name for your + extension. So for example, a SWIG interface file that begins with:</P> +<DIV class="code"> +<PRE>%module example +<BR></PRE> +</DIV> +<P> will result in an extension module using the feature name "example" + and Ruby module name "Example".</P> +<H3><A name="Ruby_nn7"></A>32.1.5 Static linking</H3> +<P> An alternative approach to dynamic linking is to rebuild the Ruby + interpreter with your extension module added to it. In the past, this + approach was sometimes necessary due to limitations in dynamic loading + support on certain machines. However, the situation has improved + greatly over the last few years and you should not consider this + approach unless there is really no other option.</P> +<P>The usual procedure for adding a new module to Ruby involves finding + the Ruby source, adding an entry to the <TT>ext/Setup</TT> file, adding + your directory to the list of extensions in the file, and finally + rebuilding Ruby.</P> +<H3><A name="Ruby_nn8"></A>32.1.6 Compilation of C++ extensions</H3> +<P> On most machines, C++ extension modules should be linked using the + C++ compiler. For example:</P> +<DIV class="code shell"> +<PRE>$ <B>swig -c++ -ruby example.i</B> +<BR>$ <B>g++ -c example.cxx</B> +<BR>$ <B>g++ -c example_wrap.cxx -I/usr/local/lib/ruby/1.6/i686-linux</B> +<BR>$ <B>g++ -shared example.o example_wrap.o -o example.so</B> +</PRE> +</DIV> +<P> If you've written an <TT>extconf.rb</TT> script to automatically + generate a <TT>Makefile</TT> for your C++ extension module, keep in + mind that (as of this writing) Ruby still uses <TT>gcc</TT> and not <TT> +g++</TT> as its linker. As a result, the required C++ runtime library + support will not be automatically linked into your extension module and + it may fail to load on some platforms. A workaround for this problem is + use the <TT>mkmf</TT> module's <TT>append_library()</TT> method to add + one of the C++ runtime libraries to the list of libraries linked into + your extension, e.g.</P> +<DIV class="code targetlang"> +<PRE>require 'mkmf' +<BR>$libs = append_library($libs, "supc++") +<BR>create_makefile('example') +<BR></PRE> +</DIV> +<H2><A name="Ruby_nn9"></A>32.2 Building Ruby Extensions under Windows + 95/NT</H2> +<P> Building a SWIG extension to Ruby under Windows 95/NT is roughly + similar to the process used with Unix. Normally, you will want to + produce a DLL that can be loaded into the Ruby interpreter. For all + recent versions of Ruby, the procedure described above (i.e. using an <TT> +extconf.rb</TT> script) will work with Windows as well; you should be + able to build your code into a DLL by typing:</P> +<DIV class="code shell"> +<PRE>C:\swigtest> <B>ruby extconf.rb</B> +<BR>C:\swigtest> <B>nmake</B> +<BR>C:\swigtest> <B>nmake install</B> +</PRE> +</DIV> +<P> The remainder of this section covers the process of compiling + SWIG-generated Ruby extensions with Microsoft Visual C++ 6 (i.e. within + the Developer Studio IDE, instead of using the command line tools). In + order to build extensions, you may need to download the source + distribution to the Ruby package, as you will need the Ruby header + files.</P> +<H3><A name="Ruby_nn10"></A>32.2.1 Running SWIG from Developer Studio</H3> +<P> If you are developing your application within Microsoft developer + studio, SWIG can be invoked as a custom build option. The process + roughly follows these steps :</P> +<UL> +<LI> Open up a new workspace and use the AppWizard to select a DLL + project.</LI> +<LI> Add both the SWIG interface file (the .i file), any supporting C + files, and the name of the wrapper file that will be created by SWIG + (i.e. <TT>example_wrap.c</TT>). Note : If using C++, choose a different + suffix for the wrapper file such as <TT>example_wrap.cxx</TT>. Don't + worry if the wrapper file doesn't exist yet--Developer Studio will keep + a reference to it around.</LI> +<LI> Select the SWIG interface file and go to the settings menu. Under + settings, select the "Custom Build" option.</LI> +<LI> Enter "SWIG" in the description field.</LI> +<LI> Enter "<TT>swig -ruby -o $(ProjDir)\$(InputName)_wrap.c + $(InputPath)</TT>" in the "Build command(s) field". You may have to + include the path to swig.exe.</LI> +<LI> Enter "<TT>$(ProjDir)\$(InputName)_wrap.c</TT>" in the "Output + files(s) field".</LI> +<LI> Next, select the settings for the entire project and go to the + C/C++ tab and select the Preprocessor category. Add NT=1 to the + Preprocessor definitions. This must be set else you will get + compilation errors. Also add IMPORT to the preprocessor definitions, + else you may get runtime errors. Also add the include directories for + your Ruby installation under "Additional include directories".</LI> +<LI> Next, select the settings for the entire project and go to the Link + tab and select the General category. Set the name of the output file to + match the name of your Ruby module (i.e.. example.dll). Next add the + Ruby library file to your link libraries under Object/Library modules. + For example "mswin32-ruby16.lib. You also need to add the path to the + library under the Input tab - Additional library path.</LI> +<LI> Build your project.</LI> +</UL> +<P> Now, assuming all went well, SWIG will be automatically invoked when + you build your project. Any changes made to the interface file will + result in SWIG being automatically invoked to produce a new version of + the wrapper file. To run your new Ruby extension, simply run Ruby and + use the <TT>require</TT> command as normal. For example if you have + this ruby file run.rb:</P> +<DIV class="code targetlang"> +<PRE># file: run.rb +<BR>require 'Example' +<BR> +<BR># Call a c function +<BR>print "Foo = ", Example.Foo, "\n" +<BR></PRE> +</DIV> +<P> Ensure the dll just built is in your path or current directory, then + run the Ruby script from the DOS/Command prompt:</P> +<DIV class="code shell"> +<PRE>C:\swigtest> <B>ruby run.rb</B> +<BR>Foo = 3.0 +<BR></PRE> +</DIV> +<H2><A name="Ruby_nn11"></A>32.3 The Ruby-to-C/C++ Mapping</H2> +<P> This section describes the basics of how SWIG maps C or C++ + declarations in your SWIG interface files to Ruby constructs.</P> +<H3><A name="Ruby_nn12"></A>32.3.1 Modules</H3> +<P> The SWIG <TT>%module</TT> directive specifies the name of the Ruby + module. If you specify:</P> +<DIV class="code"> +<PRE>%module example</PRE> +</DIV> +<P> then everything is wrapped into a Ruby module named <TT>Example</TT> + that is nested directly under the global module. You can specify a more + deeply nested module by specifying the fully-qualified module name in + quotes, e.g.</P> +<DIV class="code"> +<PRE>%module "foo::bar::spam"</PRE> +</DIV> +<P> An alternate method of specifying a nested module name is to use the +<!--span style="font-family: monospace;"--> + -prefix option on the SWIG command line. The prefix that you specify + with this option will be prepended to the module name specified with + the +<!--span style="font-family: monospace;"--> + %module directive in your SWIG interface file. So for example, this + declaration at the top of your SWIG interface file: +<BR></P> +<DIV class="code"> +<PRE>%module "foo::bar::spam"</PRE> +</DIV> +<P> will result in a nested module name of +<!--span style="font-family: monospace;"--> + Foo::Bar::Spam, but you can achieve the +<!--span style="font-style: italic;"--> + same effect by specifying: +<BR></P> +<DIV class="code"> +<PRE>%module spam</PRE> +</DIV> +<P> and then running SWIG with the +<!--span style="font-family: monospace;"--> + -prefix command line option: +<BR></P> +<DIV class="code shell"> +<PRE>$ <B>swig -ruby -prefix "foo::bar::" example.i</B></PRE> +</DIV> +<P> Starting with SWIG 1.3.20, you can also choose to wrap everything + into the global module by specifying the <TT>-globalmodule</TT> option + on the SWIG command line, i.e.</P> +<DIV class="code shell"> +<PRE>$ <B>swig -ruby -globalmodule example.i</B></PRE> +</DIV> +<P> Note that this does not relieve you of the requirement of specifying + the SWIG module name with the <TT>%module</TT> directive (or the <TT> +-module</TT> command-line option) as described earlier.</P> +<P>When choosing a module name, do not use the same name as a built-in + Ruby command or standard module name, as the results may be + unpredictable. Similarly, if you're using the <TT>-globalmodule</TT> + option to wrap everything into the global module, take care that the + names of your constants, classes and methods don't conflict with any of + Ruby's built-in names.</P> +<H3><A name="Ruby_nn13"></A>32.3.2 Functions</H3> +<P> Global functions are wrapped as Ruby module methods. For example, + given the SWIG interface file <TT>example.i</TT>:</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>int fact(int n); +<BR></PRE> +</DIV> +<P> and C source file <TT>example.c</TT>:</P> +<DIV class="code"> +<PRE>int fact(int n) { +<BR> if (n == 0) +<BR> return 1; +<BR> return (n * fact(n-1)); +<BR>} +<BR></PRE> +</DIV> +<P> SWIG will generate a method<I> fact</I> in the<I> Example</I> module + that can be used like so:</P> +<DIV class="code targetlang"> +<PRE>$ <B>irb</B> +<BR>irb(main):001:0> <B>require 'example'</B> +<BR>true +<BR>irb(main):002:0> <B>Example.fact(4)</B> +<BR>24 +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn14"></A>32.3.3 Variable Linking</H3> +<P> C/C++ global variables are wrapped as a pair of singleton methods + for the module: one to get the value of the global variable and one to + set it. For example, the following SWIG interface file declares two + global variables:</P> +<DIV class="code"> +<PRE>// SWIG interface file with global variables +<BR>%module example +<BR>... +<BR>%inline %{ +<BR>extern int variable1; +<BR>extern double Variable2; +<BR>%} +<BR>... +<BR></PRE> +</DIV> +<P> Now look at the Ruby interface:</P> +<DIV class="code targetlang"> +<PRE>$ <B>irb</B> +<BR>irb(main):001:0> <B>require 'Example'</B> +<BR>true +<BR>irb(main):002:0> <B>Example.variable1 = 2</B> +<BR>2 +<BR>irb(main):003:0> <B>Example.Variable2 = 4 * 10.3</B> +<BR>41.2 +<BR>irb(main):004:0> <B>Example.Variable2</B> +<BR>41.2 +<BR></PRE> +</DIV> +<P> If you make an error in variable assignment, you will receive an + error message. For example:</P> +<DIV class="code targetlang"> +<PRE>irb(main):005:0> <B>Example.Variable2 = "hello"</B> +<BR>TypeError: no implicit conversion to float from string +<BR>from (irb):5:in `Variable2=' +<BR>from (irb):5 +<BR></PRE> +</DIV> +<P> If a variable is declared as <TT>const</TT>, it is wrapped as a + read-only variable. Attempts to modify its value will result in an + error.</P> +<P>To make ordinary variables read-only, you can also use the <TT> +%immutable</TT> directive. For example:</P> +<DIV class="code"> +<PRE>%immutable; +<BR>%inline %{ +<BR>extern char *path; +<BR>%} +<BR>%mutable; +<BR></PRE> +</DIV> +<P> The <TT>%immutable</TT> directive stays in effect until it is + explicitly disabled using <TT>%mutable</TT>.</P> +<H3><A name="Ruby_nn15"></A>32.3.4 Constants</H3> +<P> C/C++ constants are wrapped as module constants initialized to the + appropriate value. To create a constant, use <TT>#define</TT> or the <TT> +%constant</TT> directive. For example:</P> +<DIV class="code"> +<PRE>#define PI 3.14159 +<BR>#define VERSION "1.0" +<BR> +<BR>%constant int FOO = 42; +<BR>%constant const char *path = "/usr/local"; +<BR> +<BR>const int BAR = 32; +<BR></PRE> +</DIV> +<P> Remember to use the :: operator in Ruby to get at these constant + values, e.g.</P> +<DIV class="code targetlang"> +<PRE>$ <B>irb</B> +<BR>irb(main):001:0> <B>require 'Example'</B> +<BR>true +<BR>irb(main):002:0> <B>Example::PI</B> +<BR>3.14159 +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn16"></A>32.3.5 Pointers</H3> +<P> "Opaque" pointers to arbitrary C/C++ types (i.e. types that aren't + explicitly declared in your SWIG interface file) are wrapped as data + objects. So, for example, consider a SWIG interface file containing + only the declarations:</P> +<DIV class="code"> +<PRE>Foo *get_foo(); +<BR>void set_foo(Foo *foo); +<BR></PRE> +</DIV> +<P> For this case, the<I> get_foo()</I> method returns an instance of an + internally generated Ruby class:</P> +<DIV class="code targetlang"> +<PRE>irb(main):001:0> <B>foo = Example::get_foo()</B> +<BR>#<SWIG::TYPE_p_Foo:0x402b1654> +<BR></PRE> +</DIV> +<P> A <TT>NULL</TT> pointer is always represented by the Ruby <TT>nil</TT> + object.</P> +<H3><A name="Ruby_nn17"></A>32.3.6 Structures</H3> +<P> C/C++ structs are wrapped as Ruby classes, with accessor methods + (i.e. "getters" and "setters") for all of the struct members. For + example, this struct declaration:</P> +<DIV class="code"> +<PRE>struct Vector { +<BR> double x, y; +<BR>}; +<BR></PRE> +</DIV> +<P> gets wrapped as a <TT>Vector</TT> class, with Ruby instance methods <TT> +x</TT>, <TT>x=</TT>, <TT>y</TT> and <TT>y=</TT>. These methods can be + used to access structure data from Ruby as follows:</P> +<DIV class="code targetlang"> +<PRE>$ <B>irb</B> +<BR>irb(main):001:0> <B>require 'Example'</B> +<BR>true +<BR>irb(main):002:0> <B>f = Example::Vector.new</B> +<BR>#<Example::Vector:0x4020b268> +<BR>irb(main):003:0> <B>f.x = 10</B> +<BR>nil +<BR>irb(main):004:0> <B>f.x</B> +<BR>10.0 +<BR></PRE> +</DIV> +<P> Similar access is provided for unions and the public data members of + C++ classes.</P> +<P><TT>const</TT> members of a structure are read-only. Data members can + also be forced to be read-only using the <TT>%immutable</TT> directive + (in C++, <TT>private</TT> may also be used). For example:</P> +<DIV class="code"> +<PRE>struct Foo { +<BR> ... +<BR> %immutable; +<BR> int x; /* Read-only members */ +<BR> char *name; +<BR> %mutable; +<BR> ... +<BR>}; +<BR></PRE> +</DIV> +<P> When <TT>char *</TT> members of a structure are wrapped, the + contents are assumed to be dynamically allocated using <TT>malloc</TT> + or <TT>new</TT> (depending on whether or not SWIG is run with the <TT> +-c++</TT> option). When the structure member is set, the old contents + will be released and a new value created. If this is not the behavior + you want, you will have to use a typemap (described shortly).</P> +<P>Array members are normally wrapped as read-only. For example, this + code:</P> +<DIV class="code"> +<PRE>struct Foo { +<BR> int x[50]; +<BR>}; +<BR></PRE> +</DIV> +<P> produces a single accessor function like this:</P> +<DIV class="code"> +<PRE>int *Foo_x_get(Foo *self) { +<BR> return self->x; +<BR>}; +<BR></PRE> +</DIV> +<P> If you want to set an array member, you will need to supply a + "memberin" typemap described in the <A href="#ruby_cpp_smart_pointers"> +section on typemaps</A>. As a special case, SWIG does generate code to + set array members of type <TT>char</TT> (allowing you to store a Ruby + string in the structure).</P> +<P>When structure members are wrapped, they are handled as pointers. For + example,</P> +<DIV class="code"> +<PRE>struct Foo { +<BR> ... +<BR>}; +<BR> +<BR>struct Bar { +<BR> Foo f; +<BR>}; +<BR></PRE> +</DIV> +<P> generates accessor functions such as this:</P> +<DIV class="code"> +<PRE>Foo *Bar_f_get(Bar *b) { +<BR> return &b->f; +<BR>} +<BR> +<BR>void Bar_f_set(Bar *b, Foo *val) { +<BR> b->f = *val; +<BR>} +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn18"></A>32.3.7 C++ classes</H3> +<P> Like structs, C++ classes are wrapped by creating a new Ruby class + of the same name with accessor methods for the public class member + data. Additionally, public member functions for the class are wrapped + as Ruby instance methods, and public static member functions are + wrapped as Ruby singleton methods. So, given the C++ class declaration:</P> +<DIV class="code"> +<PRE>class List { +<BR>public: +<BR> List(); +<BR> ~List(); +<BR> int search(char *item); +<BR> void insert(char *item); +<BR> void remove(char *item); +<BR> char *get(int n); +<BR> int length; +<BR> static void print(List *l); +<BR>}; +<BR></PRE> +</DIV> +<P> SWIG would create a <TT>List</TT> class with:</P> +<UL> +<LI> instance methods<I> search</I>,<I> insert</I>,<I> remove</I>, and<I> + get</I>;</LI> +<LI> instance methods<I> length</I> and<I> length=</I> (to get and set + the value of the<I> length</I> data member); and,</LI> +<LI> a<I> print</I> singleton method for the class.</LI> +</UL> +<P> In Ruby, these functions are used as follows:</P> +<DIV class="code targetlang"> +<PRE>require 'Example' +<BR> +<BR>l = Example::List.new +<BR> +<BR>l.insert("Ale") +<BR>l.insert("Stout") +<BR>l.insert("Lager") +<BR>Example.print(l) +<BR>l.length() +<BR>----- produces the following output +<BR>Lager +<BR>Stout +<BR>Ale +<BR>3 +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn19"></A>32.3.8 C++ Inheritance</H3> +<P> The SWIG type-checker is fully aware of C++ inheritance. Therefore, + if you have classes like this:</P> +<DIV class="code"> +<PRE>class Parent { +<BR> ... +<BR>}; +<BR> +<BR>class Child : public Parent { +<BR> ... +<BR>}; +<BR></PRE> +</DIV> +<P> those classes are wrapped into a hierarchy of Ruby classes that + reflect the same inheritance structure. All of the usual Ruby utility + methods work normally:</P> +<DIV class="code"> +<PRE>irb(main):001:0> <B>c = Child.new</B> +<BR>#<Bar:0x4016efd4> +<BR>irb(main):002:0> <B>c.instance_of? Child</B> +<BR>true +<BR>irb(main):003:0> <B>b.instance_of? Parent</B> +<BR>false +<BR>irb(main):004:0> <B>b.is_a? Child</B> +<BR>true +<BR>irb(main):005:0> <B>b.is_a? Parent</B> +<BR>true +<BR>irb(main):006:0> <B>Child < Parent</B> +<BR>true +<BR>irb(main):007:0> <B>Child > Parent</B> +<BR>false +<BR></PRE> +</DIV> +<P> Furthermore, if you have a function like this:</P> +<DIV class="code"> +<PRE>void spam(Parent *f); +<BR></PRE> +</DIV> +<P> then the function <TT>spam()</TT> accepts <TT>Parent</TT>* or a + pointer to any class derived from <TT>Parent</TT>.</P> +<P>Until recently, the Ruby module for SWIG didn't support multiple + inheritance, and this is still the default behavior. This doesn't mean + that you can't wrap C++ classes which inherit from multiple base + classes; it simply means that only the<B> first</B> base class listed + in the class declaration is considered, and any additional base classes + are ignored. As an example, consider a SWIG interface file with a + declaration like this:</P> +<DIV class="code"> +<PRE>class Derived : public Base1, public Base2 +<BR>{ +<BR> ... +<BR>}; +<BR></PRE> +</DIV> +<P> For this case, the resulting Ruby class (<TT>Derived</TT>) will only + consider <TT>Base1</TT> as its superclass. It won't inherit any of <TT> +Base2</TT>'s member functions or data and it won't recognize <TT>Base2</TT> + as an "ancestor" of <TT>Derived</TT> (i.e. the<EM> is_a?</EM> + relationship would fail). When SWIG processes this interface file, + you'll see a warning message like:</P> +<DIV class="code shell"> +<PRE>example.i:5: Warning(802): Warning for Derived: Base Base2 ignored. +<BR>Multiple inheritance is not supported in Ruby. +<BR></PRE> +</DIV> +<P> Starting with SWIG 1.3.20, the Ruby module for SWIG provides limited + support for multiple inheritance. Because the approach for dealing with + multiple inheritance introduces some limitations, this is an optional + feature that you can activate with the <TT>-minherit</TT> command-line + option:</P> +<DIV class="code shell"> +<PRE>$ <B>swig -c++ -ruby -minherit example.i</B></PRE> +</DIV> +<P> Using our previous example, if your SWIG interface file contains a + declaration like this:</P> +<DIV class="code"> +<PRE>class Derived : public Base1, public Base2 +<BR>{ +<BR> ... +<BR>}; +<BR></PRE> +</DIV> +<P> and you run SWIG with the <TT>-minherit</TT> command-line option, + then you will end up with a Ruby class <TT>Derived</TT> that appears to + "inherit" the member data and functions from both <TT>Base1</TT> and <TT> +Base2</TT>. What actually happens is that three different top-level + classes are created, with Ruby's <TT>Object</TT> class as their + superclass. Each of these classes defines a nested module named <TT> +Impl</TT>, and it's in these nested <TT>Impl</TT> modules that the + actual instance methods for the classes are defined, i.e.</P> +<DIV class="code targetlang"> +<PRE>class Base1 +<BR> module Impl +<BR> # Define Base1 methods here +<BR> end +<BR> include Impl +<BR>end +<BR> +<BR>class Base2 +<BR> module Impl +<BR> # Define Base2 methods here +<BR> end +<BR> include Impl +<BR>end +<BR> +<BR>class Derived +<BR> module Impl +<BR> include Base1::Impl +<BR> include Base2::Impl +<BR> # Define Derived methods here +<BR> end +<BR> include Impl +<BR>end +<BR></PRE> +</DIV> +<P> Observe that after the nested <TT>Impl</TT> module for a class is + defined, it is mixed-in to the class itself. Also observe that the <TT> +Derived::Impl</TT> module first mixes-in its base classes' <TT>Impl</TT> + modules, thus "inheriting" all of their behavior.</P> +<P>The primary drawback is that, unlike the default mode of operation, + neither <TT>Base1</TT> nor <TT>Base2</TT> is a true superclass of <TT> +Derived</TT> anymore:</P> +<DIV class="code targetlang"> +<PRE>obj = Derived.new +<BR>obj.is_a? Base1 # this will return false... +<BR>obj.is_a? Base2 # ... and so will this +<BR></PRE> +</DIV> +<P> In most cases, this is not a serious problem since objects of type <TT> +Derived</TT> will otherwise behave as though they inherit from both <TT> +Base1</TT> and <TT>Base2</TT> (i.e. they exhibit <A href="http://c2.com/cgi/wiki?DuckTyping"> +"Duck Typing"</A>).</P> +<H3><A name="Ruby_nn20"></A>32.3.9 C++ Overloaded Functions</H3> +<P> C++ overloaded functions, methods, and constructors are mostly + supported by SWIG. For example, if you have two functions like this:</P> +<DIV class="code"> +<PRE>void foo(int); +<BR>void foo(char *c); +<BR></PRE> +</DIV> +<P> You can use them in Ruby in a straightforward manner:</P> +<DIV class="code targetlang"> +<PRE>irb(main):001:0> <B>foo(3)</B> # foo(int) +<BR>irb(main):002:0> <B>foo("Hello")</B> # foo(char *c) +<BR></PRE> +</DIV> +<P>Similarly, if you have a class like this,</P> +<DIV class="code"> +<PRE>class Foo { +<BR>public: +<BR> Foo(); +<BR> Foo(const Foo &); +<BR> ... +<BR>}; +<BR></PRE> +</DIV> +<P>you can write Ruby code like this:</P> +<DIV class="code targetlang"> +<PRE>irb(main):001:0> <B>f = Foo.new</B> # Create a Foo +<BR>irb(main):002:0> <B>g = Foo.new(f)</B> # Copy f +<BR></PRE> +</DIV> +<P> Overloading support is not quite as flexible as in C++. Sometimes + there are methods that SWIG can't disambiguate. For example:</P> +<DIV class="code"> +<PRE>void spam(int); +<BR>void spam(short); +<BR></PRE> +</DIV> +<P>or</P> +<DIV class="code"> +<PRE>void foo(Bar *b); +<BR>void foo(Bar &b); +<BR></PRE> +</DIV> +<P> If declarations such as these appear, you will get a warning message + like this:</P> +<DIV class="code shell"> +<PRE>example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int) +<BR>at example.i:11. +<BR> </PRE> +</DIV> +<P> To fix this, you either need to ignore or rename one of the methods. + For example:</P> +<DIV class="code"> +<PRE>%rename(spam_short) spam(short); +<BR>... +<BR>void spam(int); +<BR>void spam(short); // Accessed as spam_short +<BR></PRE> +</DIV> +<P>or</P> +<DIV class="code"> +<PRE>%ignore spam(short); +<BR>... +<BR>void spam(int); +<BR>void spam(short); // Ignored +<BR></PRE> +</DIV> +<P> SWIG resolves overloaded functions and methods using a + disambiguation scheme that ranks and sorts declarations according to a + set of type-precedence rules. The order in which declarations appear in + the input does not matter except in situations where ambiguity + arises--in this case, the first declaration takes precedence.</P> +<P>Please refer to the <A href="#SWIGPlus">"SWIG and C++"</A> chapter + for more information about overloading.</P> +<H3><A name="Ruby_nn21"></A>32.3.10 C++ Operators</H3> +<P> For the most part, overloaded operators are handled automatically by + SWIG and do not require any special treatment on your part. So if your + class declares an overloaded addition operator, e.g.</P> +<DIV class="code"> +<PRE>class Complex { +<BR> ... +<BR> Complex operator+(Complex &); +<BR> ... +<BR>}; +<BR></PRE> +</DIV> +<P> the resulting Ruby class will also support the addition (+) method + correctly.</P> +<P>For cases where SWIG's built-in support is not sufficient, C++ + operators can be wrapped using the <TT>%rename</TT> directive + (available on SWIG 1.3.10 and later releases). All you need to do is + give the operator the name of a valid Ruby identifier. For example:</P> +<DIV class="code"> +<PRE>%rename(add_complex) operator+(Complex &, Complex &); +<BR>... +<BR>Complex operator+(Complex &, Complex &); +<BR></PRE> +</DIV> +<P>Now, in Ruby, you can do this:</P> +<DIV class="code targetlang"> +<PRE>a = Example::Complex.new(2, 3) +<BR>b = Example::Complex.new(4, -1) +<BR>c = Example.add_complex(a, b) +<BR></PRE> +</DIV> +<P> More details about wrapping C++ operators into Ruby operators is + discussed in the <A href="#ruby_operator_overloading">section on + operator overloading</A>.</P> +<H3><A name="Ruby_nn22"></A>32.3.11 C++ namespaces</H3> +<P> SWIG is aware of C++ namespaces, but namespace names do not appear + in the module nor do namespaces result in a module that is broken up + into submodules or packages. For example, if you have a file like this,</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>namespace foo { +<BR> int fact(int n); +<BR> struct Vector { +<BR> double x,y,z; +<BR> }; +<BR>}; +<BR></PRE> +</DIV> +<P>it works in Ruby as follows:</P> +<DIV class="code targetlang"> +<PRE>irb(main):001:0> <B>require 'example'</B> +<BR>true +<BR>irb(main):002:0> <B>Example.fact(3)</B> +<BR>6 +<BR>irb(main):003:0> <B>v = Example::Vector.new</B> +<BR>#<Example::Vector:0x4016f4d4> +<BR>irb(main):004:0> <B>v.x = 3.4</B> +<BR>3.4 +<BR>irb(main):004:0> <B>v.y</B> +<BR>0.0 +<BR></PRE> +</DIV> +<P> If your program has more than one namespace, name conflicts (if any) + can be resolved using <TT>%rename</TT> For example:</P> +<DIV class="code"> +<PRE>%rename(Bar_spam) Bar::spam; +<BR> +<BR>namespace Foo { +<BR> int spam(); +<BR>} +<BR> +<BR>namespace Bar { +<BR> int spam(); +<BR>} +<BR></PRE> +</DIV> +<P> If you have more than one namespace and your want to keep their + symbols separate, consider wrapping them as separate SWIG modules. For + example, make the module name the same as the namespace and create + extension modules for each namespace separately. If your program + utilizes thousands of small deeply nested namespaces each with + identical symbol names, well, then you get what you deserve.</P> +<H3><A name="Ruby_nn23"></A>32.3.12 C++ templates</H3> +<P> C++ templates don't present a huge problem for SWIG. However, in + order to create wrappers, you have to tell SWIG to create wrappers for + a particular template instantiation. To do this, you use the <TT> +%template</TT> directive. For example:</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>%{ +<BR>#include "pair.h" +<BR>%} +<BR> +<BR>template<class T1, class T2> +<BR>struct pair { +<BR> typedef T1 first_type; +<BR> typedef T2 second_type; +<BR> T1 first; +<BR> T2 second; +<BR> pair(); +<BR> pair(const T1&, const T2&); +<BR> ~pair(); +<BR>}; +<BR> +<BR>%template(Pairii) pair<int,int>; +<BR></PRE> +</DIV> +<P>In Ruby:</P> +<DIV class="code targetlang"> +<PRE>irb(main):001:0> <B>require 'example'</B> +<BR>true +<BR>irb(main):002:0> <B>p = Example::Pairii.new(3, 4)</B> +<BR>#<Example:Pairii:0x4016f4df> +<BR>irb(main):003:0> <B>p.first</B> +<BR>3 +<BR>irb(main):004:0> <B>p.second</B> +<BR>4 +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn23_1"></A>32.3.13 C++ Standard Template Library + (STL)</H3> +<P> On a related note, the standard SWIG library contains a number of + modules that provide typemaps for standard C++ library classes (such as + <TT>std::pair</TT>, <TT>std::string</TT> and <TT>std::vector</TT>). + These library modules don't provide wrappers around the templates + themselves, but they do make it convenient for users of your extension + module to pass Ruby objects (such as arrays and strings) to wrapped C++ + code that expects instances of standard C++ templates. For example, + suppose the C++ library you're wrapping has a function that expects a + vector of floats:</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>float sum(const std::vector<float>& values); +<BR></PRE> +</DIV> +<P> Rather than go through the hassle of writing an "in" typemap to + convert an array of Ruby numbers into a std::vector<float>, you can + just use the <TT>std_vector.i</TT> module from the standard SWIG + library:</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR><B>%include std_vector.i</B> +<BR>float sum(const std::vector<float>& values); +<BR></PRE> +</DIV> +<P>Ruby's STL wrappings provide additional methods to make them behave + more similarly to Ruby's native classes.</P> +<P>Thus, you can do, for example:</P> +<DIV class="targetlang"> +<PRE>v = IntVector.new +<!--span class="targetlang"--> +<BR>v << 2 +<!--span class="targetlang"--> +<BR>v << 3 +<BR>v << 4 +<BR>v.each { |x| puts x } +<BR> +<!--span style="font-weight: bold;"--> +<BR>=> 2 +<BR style="font-weight: bold;"> +<!--span style="font-weight: bold;"--> +3 +<BR style="font-weight: bold;"> +<!--span style="font-weight: bold;"--> +4 +<BR>v.delete_if { |x| x == 3 } +<BR> +<!--span style="font-weight: bold;"--> +=> [2,4]</PRE> +</DIV> +<P>The SWIG Ruby module provides also the ability for all the STL + containers to carry around Ruby native objects (Fixnum, Classes, etc) + making them act almost like Ruby's own Array, Hash, etc. To do that, + you need to define a container that contains a swig::GC_VALUE, like:</P> +<DIV class="code" style="font-family: monospace;">%module nativevector +<BR> +<BR> %{ +<BR> std::vector< swig::GC_VALUE > NativeVector; +<BR> %} +<BR> +<BR> %template(NativeVector) std::vector< swig::GC_VALUE >; +<BR></DIV> +<BR> +<P>This vector can then contain any Ruby object, making them almost + identical to Ruby's own Array class.</P> +<DIV class="targetlang"> +<!--span style="font-family: monospace;"--> +require 'nativevector' +<BR style="font-family: monospace;"> +<!--span style="font-family: monospace;"--> + include NativeVector +<BR style="font-family: monospace;"> +<BR style="font-family: monospace;"> +<!--span style="font-family: monospace;"--> + v = NativeVector.new +<BR style="font-family: monospace;"> +<!--span style="font-family: monospace;"--> + v << 1 +<BR style="font-family: monospace;"> +<!--span style="font-family: monospace;"--> + v << [1,2] +<BR style="font-family: monospace;"> +<!--span style="font-family: monospace;"--> + v << 'hello' +<BR style="font-family: monospace;"> +<BR style="font-family: monospace;"> +<!--span style="font-family: monospace;"--> + class A; end +<BR style="font-family: monospace;"> +<BR style="font-family: monospace;"> +<!--span style="font-family: monospace;"--> + v << A.new +<BR style="font-family: monospace;"> +<BR style="font-family: monospace;"> +<!--span style="font-family: monospace;"--> + puts v +<BR style="font-family: monospace;"> +<!--span style="font-weight: bold; font-family: monospace;"--> + => [1, [1,2], 'hello', #<A:0x245325>]</DIV> +<BR> +<P>Obviously, there is a lot more to template wrapping than shown in + these examples. More details can be found in the <A href="#SWIGPlus"> +SWIG and C++</A> chapter.</P> +<H3><A name="C_STL_Functors"></A>32.3.14 C++ STL Functors</H3> +<P>Some containers in the STL allow you to modify their default behavior + by using so called functors or function objects. Functors are often + just a very simple struct with +<!--span style="font-family: monospace;"--> + operator() redefined or an actual C/C++ function. This allows you, for + example, to always keep the sort order of a STL container to your + liking.</P> +<P>The Ruby STL mappings allows you to modify those containers that + support functors using Ruby procs or methods, instead. Currently, this + includes +<!--span style="font-family: monospace;"--> + std::set, +<!--span style="font-family: monospace;"--> + set::map, +<!--span style="font-family: monospace;"--> + std::multiset and +<!--span style="font-family: monospace;"--> + std::multimap.</P> +<P>The functors in swig are called +<!--span style="font-family: monospace;"--> + swig::UnaryFunction and +<!--span style="font-family: monospace;"--> + swig::BinaryFunction. +<BR> For C++ predicates (ie. functors that must return bool as a result) +<!--span style="font-family: monospace;"--> + swig::UnaryPredicate and +<!--span style="font-family: monospace;"--> + swig::BinaryPredicate are provided.</P> +<P>As an example, if given this swig file:</P> +<DIV class="code" style="font-family: monospace;">%module intset; +<BR> +<BR> %include <std_set.i> +<BR> +<BR> %typemap(IntSet) std::set< int, swig::BinaryPredicate >;</DIV> +<P>You can then use the set from Ruby with or without a proc object as a + predicate:</P> +<DIV class="targetlang" style="font-family: monospace;">require 'intset' +<BR> include Intset +<BR> +<BR> # Default sorting behavior defined in C++ +<BR> a = IntSet.new +<BR> a << 1 +<BR> a << 2 +<BR> a << 3 +<BR> a +<BR> +<!--span style="font-weight: bold;"--> + => [1,2,3] +<BR> +<BR> # Custom sorting behavior defined by a Ruby proc<DIV> +<!--span class="targetlang"--> +b = IntSet.new( proc { |a,b| a > b } ) +<BR> b << 1 +<BR> b << 2 +<BR> b << 3 +<BR> b +<BR style="font-weight: bold;"> +<!--span style="font-weight: bold;"--> + => [3,2,1]</DIV></DIV> +<H3><A name="Ruby_C_Iterators"></A>32.3.15 C++ STL Iterators</H3> +<P>The STL is well known for the use of iterators. There are a number + of iterators possible with different properties, but in general there + are two main categories: const iterators and non-const iterators. The + const iterators can access and not modify the values they point at, + while the non-const iterators can both read and modify the values.</P> +<P>The Ruby STL wrappings support both type of iterators by using a + proxy class in-between. This proxy class is +<!--span style="font-family: monospace;"--> + swig::Iterator or swig::ConstIterator. Derived from them are template + classes that need to be initialized with the actual iterator for the + container you are wrapping and often times with the beginning and + ending points of the iteration range. </P> +<P>The SWIG STL library already provides typemaps to all the standard + containers to do this wrapping automatically for you, but if you have + your own STL-like iterator, you will need to write your own typemap for + them. For out typemaps, the special functions +<!--span style="font-family: monospace;"--> + make_const_iterator and +<!--span style="font-family: monospace;"--> + make_nonconst_iterator are provided.</P> +<P>These can be used either like:</P> +<DIV class="code" style="font-family: monospace;">make_const_iterator( + iterator, rubyclass ); +<BR> make_const_iterator( iterator, iterator_begin, iterator_end, + rubyclass );</DIV> +<P>The iterators support a +<!--span style="font-family: monospace;"--> + next() and +<!--span style="font-family: monospace;"--> + previous() member function to just change the iterator without + returning anything. +<!--span style="font-family: monospace;"--> +previous() should obviously only be used for bidirectional iterators. + You can also advance the iterator multiple steps by using standard + math operations like +<!--span style="font-family: monospace;"--> + +=.</P> +<P>The value the iterator points at can be accessed with +<!--span style="font-family: monospace;"--> + value() -- this is equivalent to dereferencing it with +<!--span style="font-family: monospace;"--> + *i. For non-const iterators, a +<!--span style="font-family: monospace;"--> + value=() function is also provided which allows you to change the value + pointed by the iterator. This is equivalent to the C++ construct of + dereferencing and assignment, like +<!--span style="font-family: monospace;"--> + *i = something. </P> +<P>Thus, given say a vector class of doubles defined as:</P> +<DIV class="code" style="font-family: monospace;"> +<!--span class="code"--> +%module doublevector +<BR class="code"> +<!--span class="code"--> +<BR> %include std_vector.i +<BR class="code"> +<!--span class="code"--> +<BR> %template(DoubleVector) std::vector<double>;</DIV> +<P>Its iterator can then be used from Ruby like:</P> +<DIV class="targetlang" style="font-family: monospace;">require + 'doublevector' +<BR> include Doublevector +<BR> +<BR> v = DoubleVector.new +<BR> v << 1 +<BR> v << 2 +<BR> v << 3 +<BR> +<BR> # +<BR> # an elaborate and less efficient way of doing v.map! { |x| x+2 } +<BR> # +<BR> i = v.begin +<BR> e = v.end +<BR> while i != e +<BR> val = i.value +<BR> val += 2 +<BR> i.value = val +<BR> i.next +<BR> end +<BR> i +<BR> +<!--span style="font-weight: bold;"--> + >> [3, 4, 5 ]</DIV> +<BR> +<P>If you'd rather have STL classes without any iterators, you should + define +<!--span style="font-family: monospace;"--> + -DSWIG_NO_EXPORT_ITERATOR_METHODS when running swig.</P> +<H3><A name="Ruby_nn24"></A>32.3.16 C++ Smart Pointers</H3> +<P> In certain C++ programs, it is common to use classes that have been + wrapped by so-called "smart pointers." Generally, this involves the use + of a template class that implements <TT>operator->()</TT> like this:</P> +<DIV class="code"> +<PRE>template<class T> class SmartPtr { +<BR> ... +<BR> T *operator->(); +<BR> ... +<BR>} +<BR></PRE> +</DIV> +<P>Then, if you have a class like this,</P> +<DIV class="code"> +<PRE>class Foo { +<BR>public: +<BR> int x; +<BR> int bar(); +<BR>}; +<BR></PRE> +</DIV> +<P>A smart pointer would be used in C++ as follows:</P> +<DIV class="code"> +<PRE>SmartPtr<Foo> p = CreateFoo(); // Created somehow (not shown) +<BR>... +<BR>p->x = 3; // Foo::x +<BR>int y = p->bar(); // Foo::bar +<BR></PRE> +</DIV> +<P> To wrap this in Ruby, simply tell SWIG about the <TT>SmartPtr</TT> + class and the low-level <TT>Foo</TT> object. Make sure you instantiate <TT> +SmartPtr</TT> using <TT>%template</TT> if necessary. For example:</P> +<DIV class="code"> +<PRE>%module example +<BR>... +<BR>%template(SmartPtrFoo) SmartPtr<Foo>; +<BR>... +<BR></PRE> +</DIV> +<P>Now, in Ruby, everything should just "work":</P> +<DIV class="code targetlang"> +<PRE>irb(main):001:0> <B>p = Example::CreateFoo()</B> # Create a smart-pointer somehow +<BR>#<Example::SmartPtrFoo:0x4016f4df> +<BR>irb(main):002:0> <B>p.x = 3</B> # Foo::x +<BR>3 +<BR>irb(main):003:0> <B>p.bar()</B> # Foo::bar +<BR></PRE> +</DIV> +<P> If you ever need to access the underlying pointer returned by <TT> +operator->()</TT> itself, simply use the <TT>__deref__()</TT> method. + For example:</P> +<DIV class="code targetlang"> +<PRE>irb(main):004:0> <B>f = p.__deref__()</B> # Returns underlying Foo * +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn25"></A>32.3.17 Cross-Language Polymorphism</H3> +<P> SWIG's Ruby module supports cross-language polymorphism (a.k.a. the + "directors" feature) similar to that for SWIG's Python module. Rather + than duplicate the information presented in the <A href="Ruby">Python</A> + chapter, this section just notes the differences that you need to be + aware of when using this feature with Ruby.</P> +<H4><A name="Ruby_nn26"></A>32.3.17.1 Exception Unrolling</H4> +<P> Whenever a C++ director class routes one of its virtual member + function calls to a Ruby instance method, there's always the + possibility that an exception will be raised in the Ruby code. By + default, those exceptions are ignored, which simply means that the + exception will be exposed to the Ruby interpreter. If you would like to + change this behavior, you can use the <TT>%feature("director:except")</TT> + directive to indicate what action should be taken when a Ruby exception + is raised. The following code should suffice in most cases:</P> +<DIV class="code"> +<PRE>%feature("director:except") { +<BR> throw Swig::DirectorMethodException($error); +<BR>} +<BR></PRE> +</DIV> +<P> When this feature is activated, the call to the Ruby instance method + is "wrapped" using the <TT>rb_rescue2()</TT> function from Ruby's C + API. If any Ruby exception is raised, it will be caught here and a C++ + exception is raised in its place.</P> +<H2><A name="Ruby_nn27"></A>32.4 Naming</H2> +<P>Ruby has several common naming conventions. Constants are generally + in upper case, module and class names are in camel case and methods are + in lower case with underscores. For example:</P> +<DIV class="code"> +<UL> +<LI><STRONG>MATH::PI</STRONG> is a constant name</LI> +<LI><STRONG>MyClass</STRONG> is a class name</LI> +<LI><STRONG>my_method</STRONG> is a method name</LI> +</UL> +</DIV> +<P>Prior to version 1.3.28, SWIG did not support these Ruby conventions. + The only modifications it made to names was to capitalize the first + letter of constants (which includes module and class names).</P> +<P>SWIG 1.3.28 introduces the new -autorename command line parameter. + When this parameter is specified, SWIG will automatically change + constant, class and method names to conform with the standard Ruby + naming conventions. For example:</P> +<DIV class="code shell"> +<PRE>$ <B>swig -ruby -autorename example.i</B> +</PRE> +</DIV> +<P>To disable renaming use the -noautorename command line option.</P> +<P>Since this change significantly changes the wrapper code generated by + SWIG, it is turned off by default in SWIG 1.3.28. However, it is + planned to become the default option in future releases.</P> +<H3><A name="Ruby_nn28"></A>32.4.1 Defining Aliases</H3> +<P> It's a fairly common practice in the Ruby built-ins and standard + library to provide aliases for method names. For example,<EM> + Array#size</EM> is an alias for<EM> Array#length</EM>. If you would + like to provide an alias for one of your class' instance methods, one + approach is to use SWIG's <TT>%extend</TT> directive to add a new + method of the aliased name that calls the original function. For + example:</P> +<DIV class="code"> +<PRE>class MyArray { +<BR>public: +<BR> // Construct an empty array +<BR> MyArray(); +<BR> +<BR> // Return the size of this array +<BR> size_t length() const; +<BR>}; +<BR> +<BR>%extend MyArray { +<BR> // MyArray#size is an alias for MyArray#length +<BR> size_t size() const { +<BR> return $self->length(); +<BR> } +<BR>} +<BR> </PRE> +</DIV> +<P> A better solution is to use the <TT>%alias</TT> directive (unique to + SWIG's Ruby module). The previous example could then be rewritten as:</P> +<DIV class="code"> +<PRE>// MyArray#size is an alias for MyArray#length +<BR>%alias MyArray::length "size"; +<BR> +<BR>class MyArray { +<BR>public: +<BR> // Construct an empty array +<BR> MyArray(); +<BR> +<BR> // Return the size of this array +<BR> size_t length() const; +<BR>}; +<BR> +<BR></PRE> +</DIV> +<P> Multiple aliases can be associated with a method by providing a + comma-separated list of aliases to the <TT>%alias</TT> directive, e.g.</P> +<DIV class="code"> +<PRE>%alias MyArray::length "amount,quantity,size";</PRE> +</DIV> +<P> From an end-user's standpoint, there's no functional difference + between these two approaches; i.e. they should get the same result from + calling either<EM> MyArray#size</EM> or<EM> MyArray#length</EM>. + However, when the <TT>%alias</TT> directive is used, SWIG doesn't need + to generate all of the wrapper code that's usually associated with + added methods like our<EM> MyArray::size()</EM> example.</P> +<P>Note that the <TT>%alias</TT> directive is implemented using SWIG's + "features" mechanism and so the same name matching rules used for other + kinds of features apply (see the chapter on <A href="#Customization"> +"Customization Features"</A>) for more details).</P> +<H3><A name="Ruby_nn29"></A>32.4.2 Predicate Methods</H3> +<P> Ruby methods that return a boolean value and end in a question mark + are known as predicate methods. Examples of predicate methods in + standard Ruby classes include<EM> Array#empty?</EM> (which returns <TT> +true</TT> for an array containing no elements) and<EM> + Object#instance_of?</EM> (which returns <TT>true</TT> if the object is + an instance of the specified class). For consistency with Ruby + conventions, methods that return boolean values should be marked as + predicate methods.</P> +<P>One cumbersome solution to this problem is to rename the method + (using SWIG's <TT>%rename</TT> directive) and provide a custom typemap + that converts the function's actual return type to Ruby's <TT>true</TT> + or <TT>false</TT>. For example:</P> +<DIV class="code"> +<PRE>%rename("is_it_safe?") is_it_safe(); +<BR> +<BR>%typemap(out) int is_it_safe +<BR> "$result = ($1 != 0) ? Qtrue : Qfalse;"; +<BR> +<BR>int is_it_safe(); +<BR> +<BR></PRE> +</DIV> +<P> A better solution is to use the <TT>%predicate</TT> directive + (unique to SWIG's Ruby module) to designate a method as a predicate + method. For the previous example, this would look like:</P> +<DIV class="code"> +<PRE>%predicate is_it_safe(); +<BR> +<BR>int is_it_safe(); +<BR> +<BR></PRE> +</DIV> +<P>This method would be invoked from Ruby code like this:</P> +<DIV class="code targetlang"> +<PRE>irb(main):001:0> <B>Example::is_it_safe?</B> +<BR>true +<BR> +<BR></PRE> +</DIV> +<P> The <TT>%predicate</TT> directive is implemented using SWIG's + "features" mechanism and so the same name matching rules used for other + kinds of features apply (see the chapter on <A href="#Customization"> +"Customization Features"</A>) for more details).</P> +<H3><A name="Ruby_nn30"></A>32.4.3 Bang Methods</H3> +<P> Ruby methods that modify an object in-place and end in an + exclamation mark are known as bang methods. An example of a bang method + is<EM> Array#sort!</EM> which changes the ordering of items in an + array. Contrast this with<EM> Array#sort</EM>, which returns a copy of + the array with the items sorted instead of modifying the original + array. For consistency with Ruby conventions, methods that modify + objects in place should be marked as bang methods.</P> +<P>Bang methods can be marked using the <TT>%bang</TT> directive which + is unique to the Ruby module and was introduced in SWIG 1.3.28. For + example:</P> +<DIV class="code"> +<PRE>%bang sort!(arr); +<BR> +<BR>int sort(int arr[]); </PRE> +</DIV> +<P>This method would be invoked from Ruby code like this:</P> +<DIV class="code"> +<PRE>irb(main):001:0> <B>Example::sort!(arr)</B></PRE> +</DIV> +<P> The <TT>%bang</TT> directive is implemented using SWIG's "features" + mechanism and so the same name matching rules used for other kinds of + features apply (see the chapter on <A href="#Customization"> +"Customization Features"</A>) for more details).</P> +<H3><A name="Ruby_nn31"></A>32.4.4 Getters and Setters</H3> +<P> Often times a C++ library will expose properties through getter and + setter methods. For example:</P> +<DIV class="code"> +<PRE>class Foo { +<BR> Foo() {} +<BR> +<BR> int getValue() { return value_; } +<BR> +<BR> void setValue(int value) { value_ = value; } +<BR> +<BR>private: +<BR> int value_; +<BR>};</PRE> +</DIV> +<P>By default, SWIG will expose these methods to Ruby as <TT>get_value</TT> + and <TT>set_value.</TT> However, it more natural for these methods to + be exposed in Ruby as <TT>value</TT> and <TT>value=.</TT> That allows + the methods to be used like this:</P> +<DIV class="code"> +<PRE>irb(main):001:0> <B>foo = Foo.new()</B> +<BR>irb(main):002:0> <B>foo.value = 5</B> +<BR>irb(main):003:0> <B>puts foo.value</B></PRE> +</DIV> +<P> This can be done by using the %rename directive:</P> +<DIV class="code"> +<PRE>%rename("value") Foo::getValue(); +<BR>%rename("value=") Foo::setValue(int value); +<BR></PRE> +</DIV> +<P> </P> +<H2><A name="Ruby_nn32"></A>32.5 Input and output parameters</H2> +<P> A common problem in some C programs is handling parameters passed as + simple pointers. For example:</P> +<DIV class="code"> +<PRE>void add(int x, int y, int *result) { +<BR> *result = x + y; +<BR>} +<BR>or +<BR>int sub(int *x, int *y) { +<BR> return *x-*y; +<BR>} +<BR></PRE> +</DIV> +<P> The easiest way to handle these situations is to use the <TT> +typemaps.i</TT> file. For example:</P> +<DIV class="code"> +<PRE>%module Example +<BR>%include "typemaps.i" +<BR> +<BR>void add(int, int, int *OUTPUT); +<BR>int sub(int *INPUT, int *INPUT); +<BR></PRE> +</DIV> +<P>In Ruby, this allows you to pass simple values. For example:</P> +<DIV class="code targetlang"> +<PRE>a = Example.add(3,4) +<BR>puts a +<BR>7 +<BR>b = Example.sub(7,4) +<BR>puts b +<BR>3 +<BR></PRE> +</DIV> +<P> Notice how the <TT>INPUT</TT> parameters allow integer values to be + passed instead of pointers and how the <TT>OUTPUT</TT> parameter + creates a return result.</P> +<P>If you don't want to use the names <TT>INPUT</TT> or <TT>OUTPUT</TT>, + use the <TT>%apply</TT> directive. For example:</P> +<DIV class="code"> +<PRE>%module Example +<BR>%include "typemaps.i" +<BR> +<BR>%apply int *OUTPUT { int *result }; +<BR>%apply int *INPUT { int *x, int *y}; +<BR> +<BR>void add(int x, int y, int *result); +<BR>int sub(int *x, int *y); +<BR></PRE> +</DIV> +<P> If a function mutates one of its parameters like this,</P> +<DIV class="code"> +<PRE>void negate(int *x) { +<BR> *x = -(*x); +<BR>} +<BR></PRE> +</DIV> +<P>you can use <TT>INOUT</TT> like this:</P> +<DIV class="code"> +<PRE>%include "typemaps.i" +<BR>... +<BR>void negate(int *INOUT); +<BR></PRE> +</DIV> +<P>In Ruby, a mutated parameter shows up as a return value. For example:</P> +<DIV class="code targetlang"> +<PRE>a = Example.negate(3) +<BR>print a +<BR>-3 +<BR> +<BR></PRE> +</DIV> +<P> The most common use of these special typemap rules is to handle + functions that return more than one value. For example, sometimes a + function returns a result as well as a special error code:</P> +<DIV class="code"> +<PRE>/* send message, return number of bytes sent, success code, and error_code */ +<BR>int send_message(char *text, int *success, int *error_code); +<BR></PRE> +</DIV> +<P> To wrap such a function, simply use the <TT>OUTPUT</TT> rule above. + For example:</P> +<DIV class="code"> +<PRE>%module example +<BR>%include "typemaps.i" +<BR>... +<BR>int send_message(char *, int *OUTPUT, int *OUTPUT); +<BR></PRE> +</DIV> +<P> When used in Ruby, the function will return an array of multiple + values.</P> +<DIV class="code targetlang"> +<PRE>bytes, success, error_code = send_message("Hello World") +<BR>if not success +<BR> print "error #{error_code} : in send_message" +<BR>else +<BR> print "Sent", bytes +<BR>end +<BR></PRE> +</DIV> +<P> Another way to access multiple return values is to use the <TT> +%apply</TT> rule. In the following example, the parameters rows and + columns are related to SWIG as <TT>OUTPUT</TT> values through the use + of <TT>%apply</TT></P> +<DIV class="code"> +<PRE>%module Example +<BR>%include "typemaps.i" +<BR>%apply int *OUTPUT { int *rows, int *columns }; +<BR>... +<BR>void get_dimensions(Matrix *m, int *rows, int*columns); +<BR></PRE> +</DIV> +<P>In Ruby:</P> +<DIV class="code targetlang"> +<PRE>r, c = Example.get_dimensions(m) +<BR></PRE> +</DIV> +<H2><A name="Ruby_nn33"></A>32.6 Exception handling</H2> +<H3><A name="Ruby_nn34"></A>32.6.1 Using the %exception directive</H3> +<P>The SWIG <TT>%exception</TT> directive can be used to define a + user-definable exception handler that can convert C/C++ errors into + Ruby exceptions. The chapter on <A href="#Customization">Customization + Features</A> contains more details, but suppose you have a C++ class + like the following :</P> +<DIV class="code"> +<PRE>class DoubleArray { +<BR> private: +<BR> int n; +<BR> double *ptr; +<BR> public: +<BR> // Create a new array of fixed size +<BR> DoubleArray(int size) { +<BR> ptr = new double[size]; +<BR> n = size; +<BR> } +<BR> +<BR> // Destroy an array +<BR> ~DoubleArray() { +<BR> delete ptr; +<BR> } +<BR> +<BR> // Return the length of the array +<BR> int length() { +<BR> return n; +<BR> } +<BR> +<BR> // Get an array item and perform bounds checking. +<BR> double getitem(int i) { +<BR> if ((i >= 0) && (i < n)) +<BR> return ptr[i]; +<BR> else +<BR> throw RangeError(); +<BR> } +<BR> +<BR> // Set an array item and perform bounds checking. +<BR> void setitem(int i, double val) { +<BR> if ((i >= 0) && (i < n)) +<BR> ptr[i] = val; +<BR> else { +<BR> throw RangeError(); +<BR> } +<BR> } +<BR> }; +<BR></PRE> +</DIV> +<P> Since several methods in this class can throw an exception for an + out-of-bounds access, you might want to catch this in the Ruby + extension by writing the following in an interface file:</P> +<DIV class="code"> +<PRE>%exception { +<BR> try { +<BR> $action +<BR> } +<BR> catch (const RangeError&) { +<BR> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError); +<BR> rb_raise(cpperror, "Range error."); +<BR> } +<BR>} +<BR> +<BR>class DoubleArray { +<BR> ... +<BR>}; +<BR></PRE> +</DIV> +<P> The exception handling code is inserted directly into generated + wrapper functions. When an exception handler is defined, errors can be + caught and used to gracefully raise a Ruby exception instead of forcing + the entire program to terminate with an uncaught error.</P> +<P>As shown, the exception handling code will be added to every wrapper + function. Because this is somewhat inefficient, you might consider + refining the exception handler to only apply to specific methods like + this:</P> +<DIV class="code"> +<PRE>%exception getitem { +<BR> try { +<BR> $action +<BR> } +<BR> catch (const RangeError&) { +<BR> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError); +<BR> rb_raise(cpperror, "Range error in getitem."); +<BR> } +<BR>} +<BR> +<BR>%exception setitem { +<BR> try { +<BR> $action +<BR> } +<BR> catch (const RangeError&) { +<BR> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError); +<BR> rb_raise(cpperror, "Range error in setitem."); +<BR> } +<BR>} +<BR></PRE> +</DIV> +<P> In this case, the exception handler is only attached to methods and + functions named <TT>getitem</TT> and <TT>setitem</TT>.</P> +<P>Since SWIG's exception handling is user-definable, you are not + limited to C++ exception handling. See the chapter on <A href="#Customization"> +Customization Features</A> for more examples.</P> +<H3><A name="Ruby_nn34_2"></A>32.6.2 Handling Ruby Blocks</H3> +<P>One of the highlights of Ruby and most of its standard library is the + use of blocks, which allow the easy creation of continuations and other + niceties. Blocks in ruby are also often used to simplify the passing + of many arguments to a class.</P> +<P>In order to make your class constructor support blocks, you can take + advantage of the %exception directive, which will get run after the C++ + class' constructor was called. </P> +<P>For example, this yields the class over after its construction: +<BR></P> +<DIV class="code"> +<PRE>class Window +<BR>{ +<BR>public: +<BR> Window(int x, int y, int w, int h); +<BR>// .... other methods here .... +<BR>}; +<BR> +<BR>// Add support for yielding self in the Class' constructor. +<BR>%exception Window::Window { +<BR> $action +<BR> if (rb_block_given_p()) { +<BR> rb_yield(self); +<BR> } +<BR>}</PRE> +</DIV> +<P> Then, in ruby, it can be used like:</P> +<DIV class="targetlang" style="font-family: monospace;"> +Window.new(0,0,360,480) { |w| +<BR> w.color = Fltk::RED +<BR> w.border = false +<BR> +<!--span class="targetlang"--> + }</DIV> +<BR> +<P>For other methods, you can usually use a dummy parameter with a + special in typemap, like:</P> +<DIV class="code" style="font-family: monospace;">// +<BR> // original function was: +<BR> // +<BR> // void func(int x); +<BR> +<BR> %typemap(in,numinputs=0) int RUBY_YIELD_SELF { +<BR> if ( !rb_block_given_p() ) +<BR> rb_raise("No block given"); +<BR> return rb_yield(self); +<BR> } +<BR> +<BR> %extend { +<BR> void func(int x, int RUBY_YIELD_SELF ); +<BR> }</DIV> +<P>For more information on typemaps, see <A href="#Ruby_nn37">Typemaps</A> +.</P> +<H3><A name="Ruby_nn35"></A>32.6.3 Raising exceptions</H3> +<P>There are three ways to raise exceptions from C++ code to Ruby.</P> +<P>The first way is to use <TT>SWIG_exception(int code, const char *msg)</TT> +. The following table shows the mappings from SWIG error codes to Ruby + exceptions:</P> +<DIV class="diagram"> +<TABLE border="1" class="diagram" summary="Mapping between SWIG error codes and Ruby exceptions." +width="80%"><TBODY></TBODY> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_MemoryError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eNoMemError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_IOError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eIOError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_RuntimeError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eRuntimeError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_IndexError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eIndexError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_TypeError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eTypeError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_DivisionByZero</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eZeroDivError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_OverflowError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eRangeError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_SyntaxError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eSyntaxError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_ValueError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eArgError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_SystemError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eFatal</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_AttributeError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eRuntimeError</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_NullReferenceError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eNullReferenceError*</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_ObjectPreviouslyDeletedError</DIV></TD><TD style="font-family: monospace;"> +<DIV>rb_eObjectPreviouslyDeleted*</DIV></TD></TR> +<TR><TD class="diagram" style="font-family: monospace;"><DIV> +SWIG_UnknownError</DIV></TD><TD style="font-family: monospace;"><DIV> +rb_eRuntimeError</DIV></TD></TR> +<TR class="diagram" style="font-family: monospace;"><TD colspan="2"><DIV> +* These error classes are created by SWIG and are not built-in Ruby + exception classes</DIV></TD></TR> +</TABLE> +</DIV> +<P>The second way to raise errors is to use <TT>SWIG_Raise(obj, type, + desc)</TT>. Obj is a C++ instance of an exception class, type is a + string specifying the type of exception (for example, "MyError") and + desc is the SWIG description of the exception class. For example:</P> +<DIV class="code" style="font-family: monospace;"> + %raise(SWIG_NewPointerObj(e, SWIGTYPE_p_AssertionFailedException, 0), + ":AssertionFailedException", SWIGTYPE_p_AssertionFailedException);</DIV> +<P>This is useful when you want to pass the current exception object + directly to Ruby, particularly when the object is an instance of class + marked as an <TT>%exceptionclass</TT> (see the next section for more + information).</P> +<P>Last, you can raise an exception by directly calling Ruby's C api. + This is done by invoking the <TT>rb_raise()</TT> function. The first + argument passed to <TT>rb_raise()</TT> is the exception type. You can + raise a custom exception type or one of the built-in Ruby exception + types.</P> +<H3><A name="Ruby_nn36"></A>32.6.4 Exception classes</H3> +<P>Starting with SWIG 1.3.28, the Ruby module supports the <TT> +%exceptionclass</TT> directive, which is used to identify C++ classes + that are used as exceptions. Classes that are marked with the <TT> +%exceptionclass</TT> directive are exposed in Ruby as child classes of <TT> +rb_eRuntimeError</TT>. This allows C++ exceptions to be directly mapped + to Ruby exceptions, providing for a more natural integration between + C++ code and Ruby code.</P> +<DIV class="code"> +<PRE> %exceptionclass CustomError; +<BR> +<BR> %inline %{ +<BR> class CustomError { }; +<BR> +<BR> class Foo { +<BR> public: +<BR> void test() { throw CustomError; } +<BR> }; +<BR> } +<BR></PRE> +</DIV> +<P>From Ruby you can now call this method like this:</P> +<DIV class="code targetlang"> +<PRE>foo = Foo.new +<BR>begin +<BR> foo.test() +<BR>rescue CustomError => e +<BR> puts "Caught custom error" +<BR>end </PRE> +</DIV> +<P>For another example look at swig/Examples/ruby/exception_class. +<BR></P> +<H2><A name="Ruby_nn37"></A>32.7 Typemaps</H2> +<P> This section describes how you can modify SWIG's default wrapping + behavior for various C/C++ datatypes using the <TT>%typemap</TT> + directive. This is an advanced topic that assumes familiarity with the + Ruby C API as well as the material in the "<A href="#Typemaps">Typemaps</A> +" chapter. </P> +<P>Before proceeding, it should be stressed that typemaps are not a + required part of using SWIG---the default wrapping behavior is enough + in most cases. Typemaps are only used if you want to change some aspect + of the primitive C-Ruby interface.</P> +<H3><A name="Ruby_nn38"></A>32.7.1 What is a typemap?</H3> +<P> A typemap is nothing more than a code generation rule that is + attached to a specific C datatype. The general form of this declaration + is as follows ( parts enclosed in [...] are optional ): </P> +<DIV class="code"> +<!--span style="font-family: monospace;" class="code"--> +%typemap( method [, modifiers...] ) typelist code;</DIV> +<P><EM> method</EM> is a simply a name that specifies what kind of + typemap is being defined. It is usually a name like <TT>"in"</TT>, <TT> +"out"</TT>, or <TT>"argout"</TT> (or its director variations). The + purpose of these methods is described later.</P> +<P><EM> modifiers</EM> is an optional comma separated list of <TT> +name="value"</TT> values. These are sometimes to attach extra + information to a typemap and is often target-language dependent.</P> +<P><EM> typelist</EM> is a list of the C++ type patterns that the + typemap will match. The general form of this list is as follows:</P> +<DIV class="diagram"> +<PRE>typelist : typepattern [, typepattern, typepattern, ... ] ; +<BR> +<BR>typepattern : type [ (parms) ] +<BR> | type name [ (parms) ] +<BR> | ( typelist ) [ (parms) ] +<BR></PRE> +</DIV> +<P> Each type pattern is either a simple type, a simple type and + argument name, or a list of types in the case of multi-argument + typemaps. In addition, each type pattern can be parameterized with a + list of temporary variables (parms). The purpose of these variables + will be explained shortly.</P> +<P><EM>code</EM> specifies the C code used in the typemap. It can take + any one of the following forms:</P> +<DIV class="diagram"> +<PRE>code : { ... } +<BR> | " ... " +<BR> | %{ ... %} +<BR></PRE> +</DIV> +<P>For example, to convert integers from Ruby to C, you might define a + typemap like this:</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>%typemap(in) int { +<BR> $1 = (int) NUM2INT($input); +<BR> printf("Received an integer : %d\n",$1); +<BR>} +<BR> +<BR>%inline %{ +<BR>extern int fact(int n); +<BR>%} +<BR></PRE> +</DIV> +<P> Typemaps are always associated with some specific aspect of code + generation. In this case, the "in" method refers to the conversion of + input arguments to C/C++. The datatype <TT>int</TT> is the datatype to + which the typemap will be applied. The supplied C code is used to + convert values. In this code a number of special variables prefaced by + a <TT>$</TT> are used. The <TT>$1</TT> variable is placeholder for a + local variable of type <TT>int</TT>. The <TT>$input</TT> variable is + the input Ruby object.</P> +<P>When this example is compiled into a Ruby module, the following + sample code:</P> +<DIV class="code targetlang"> +<PRE>require 'example' +<BR> +<BR>puts Example.fact(6) +<BR></PRE> +</DIV> +<P>prints the result:</P> +<DIV class="code shell"> +<PRE>Received an integer : 6 +<BR>720 +<BR></PRE> +</DIV> +<P> In this example, the typemap is applied to all occurrences of the <TT> +int</TT> datatype. You can refine this by supplying an optional + parameter name. For example:</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>%typemap(in) int n { +<BR> $1 = (int) NUM2INT($input); +<BR> printf("n = %d\n",$1); +<BR>} +<BR> +<BR>%inline %{ +<BR>extern int fact(int n); +<BR>%} +<BR></PRE> +</DIV> +<P> In this case, the typemap code is only attached to arguments that + exactly match "<TT>int n</TT>".</P> +<P>The application of a typemap to specific datatypes and argument names + involves more than simple text-matching--typemaps are fully integrated + into the SWIG type-system. When you define a typemap for <TT>int</TT>, + that typemap applies to <TT>int</TT> and qualified variations such as <TT> +const int</TT>. In addition, the typemap system follows <TT>typedef</TT> + declarations. For example:</P> +<DIV class="code"> +<PRE>%typemap(in) int n { +<BR> $1 = (int) NUM2INT($input); +<BR> printf("n = %d\n",$1); +<BR>} +<BR> +<BR>typedef int Integer; +<BR>extern int fact(Integer n); // Above typemap is applied +<BR></PRE> +</DIV> +<P> However, the matching of <TT>typedef</TT> only occurs in one + direction. If you defined a typemap for <TT>Integer</TT>, it is not + applied to arguments of type <TT>int</TT>.</P> +<P>Typemaps can also be defined for groups of consecutive arguments. For + example:</P> +<DIV class="code"> +<PRE>%typemap(in) (char *str, int len) { +<BR> $1 = STR2CSTR($input); +<BR> $2 = (int) RSTRING($input)->len; +<BR>}; +<BR> +<BR>int count(char c, char *str, int len); +<BR></PRE> +</DIV> +<P> When a multi-argument typemap is defined, the arguments are always + handled as a single Ruby object. This allows the function <TT>count</TT> + to be used as follows (notice how the length parameter is omitted):</P> +<DIV class="code targetlang"> +<PRE>puts Example.count('o','Hello World') +<BR>2 +<BR></PRE> +</DIV> +<H3><A name="Ruby_Typemap_scope"></A>32.7.2 Typemap scope</H3> +<P> Once defined, a typemap remains in effect for all of the + declarations that follow. A typemap may be redefined for different + sections of an input file. For example:</P> +<DIV class="code"> +<PRE>// typemap1 +<BR>%typemap(in) int { +<BR>... +<BR>} +<BR> +<BR>int fact(int); // typemap1 +<BR>int gcd(int x, int y); // typemap1 +<BR> +<BR>// typemap2 +<BR>%typemap(in) int { +<BR>... +<BR>} +<BR> +<BR>int isprime(int); // typemap2 +<BR></PRE> +</DIV> +<P> One exception to the typemap scoping rules pertains to the <TT> +%extend</TT> declaration. <TT>%extend</TT> is used to attach new + declarations to a class or structure definition. Because of this, all + of the declarations in an <TT>%extend</TT> block are subject to the + typemap rules that are in effect at the point where the class itself is + defined. For example:</P> +<DIV class="code"> +<PRE>class Foo { +<BR> ... +<BR>}; +<BR> +<BR>%typemap(in) int { +<BR> ... +<BR>} +<BR> +<BR>%extend Foo { +<BR> int blah(int x); // typemap has no effect. Declaration is attached to Foo which +<BR> // appears before the %typemap declaration. +<BR>}; +<BR></PRE> +</DIV> +<H3><A name="Ruby_Copying_a_typemap"></A>32.7.3 Copying a typemap</H3> +<P> A typemap is copied by using assignment. For example:</P> +<DIV class="code"> +<PRE>%typemap(in) Integer = int; +<BR></PRE> +</DIV> +<P> or this:</P> +<DIV class="code"> +<PRE>%typemap(in) Integer, Number, int32_t = int; +<BR></PRE> +</DIV> +<P> Types are often managed by a collection of different typemaps. For + example:</P> +<DIV class="code"> +<PRE>%typemap(in) int { ... } +<BR>%typemap(out) int { ... } +<BR>%typemap(varin) int { ... } +<BR>%typemap(varout) int { ... } +<BR></PRE> +</DIV> +<P> To copy all of these typemaps to a new type, use <TT>%apply</TT>. + For example:</P> +<DIV class="code"> +<PRE>%apply int { Integer }; // Copy all int typemaps to Integer +<BR>%apply int { Integer, Number }; // Copy all int typemaps to both Integer and Number +<BR></PRE> +</DIV> +<P> The patterns for <TT>%apply</TT> follow the same rules as for <TT> +%typemap</TT>. For example:</P> +<DIV class="code"> +<PRE>%apply int *output { Integer *output }; // Typemap with name +<BR>%apply (char *buf, int len) { (char *buffer, int size) }; // Multiple arguments +<BR></PRE> +</DIV> +<H3><A name="Ruby_Deleting_a_typemap"></A>32.7.4 Deleting a typemap</H3> +<P> A typemap can be deleted by simply defining no code. For example:</P> +<DIV class="code"> +<PRE>%typemap(in) int; // Clears typemap for int +<BR>%typemap(in) int, long, short; // Clears typemap for int, long, short +<BR>%typemap(in) int *output; +<BR></PRE> +</DIV> +<P> The <TT>%clear</TT> directive clears all typemaps for a given type. + For example:</P> +<DIV class="code"> +<PRE>%clear int; // Removes all types for int +<BR>%clear int *output, long *output; +<BR></PRE> +</DIV> +<P><B> Note:</B> Since SWIG's default behavior is defined by typemaps, + clearing a fundamental type like <TT>int</TT> will make that type + unusable unless you also define a new set of typemaps immediately after + the clear operation.</P> +<H3><A name="Ruby_Placement_of_typemaps"></A>32.7.5 Placement of + typemaps</H3> +<P> Typemap declarations can be declared in the global scope, within a + C++ namespace, and within a C++ class. For example:</P> +<DIV class="code"> +<PRE>%typemap(in) int { +<BR> ... +<BR>} +<BR> +<BR>namespace std { +<BR> class string; +<BR> %typemap(in) string { +<BR> ... +<BR> } +<BR>} +<BR> +<BR>class Bar { +<BR>public: +<BR> typedef const int & const_reference; +<BR> %typemap(out) const_reference { +<BR> ... +<BR> } +<BR>}; +<BR></PRE> +</DIV> +<P> When a typemap appears inside a namespace or class, it stays in + effect until the end of the SWIG input (just like before). However, the + typemap takes the local scope into account. Therefore, this code</P> +<DIV class="code"> +<PRE>namespace std { +<BR> class string; +<BR> %typemap(in) string { +<BR> ... +<BR> } +<BR>} +<BR></PRE> +</DIV> +<P> is really defining a typemap for the type <TT>std::string</TT>. You + could have code like this:</P> +<DIV class="code"> +<PRE>namespace std { +<BR> class string; +<BR> %typemap(in) string { /* std::string */ +<BR> ... +<BR> } +<BR>} +<BR> +<BR>namespace Foo { +<BR> class string; +<BR> %typemap(in) string { /* Foo::string */ +<BR> ... +<BR> } +<BR>} +<BR></PRE> +</DIV> +<P> In this case, there are two completely distinct typemaps that apply + to two completely different types (<TT>std::string</TT> and <TT> +Foo::string</TT>).</P> +<P> It should be noted that for scoping to work, SWIG has to know that <TT> +string</TT> is a typename defined within a particular namespace. In this + example, this is done using the class declaration <TT>class string</TT> + .</P> +<H3><A name="Ruby_nn39"></A>32.7.6 Ruby typemaps</H3> +<P>The following list details all of the typemap methods that can be + used by the Ruby module:</P> +<H4><A name="Ruby_in_typemap"></A>32.7.6.1 "in" typemap</H4> +<P>Converts Ruby objects to input function arguments. For example:</P> +<DIV class="code"> +<PRE>%typemap(in) int { +<BR> $1 = NUM2INT($input); +<BR>} +<BR></PRE> +</DIV> +<P> The following special variables are available:</P> +<DIV class="diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" summary="Special variables - in typemap" +width="100%"><TBODY></TBODY> +<TR><TD style="font-family: monospace;">$input</TD><TD style="font-family: monospace;"> + Input object holding value to be converted.</TD></TR> +<TR><TD style="font-family: monospace;">$symname</TD><TD style="font-family: monospace;"> + Name of function/method being wrapped</TD></TR> +<TR><TD style="font-family: monospace;">$1...n</TD><TD style="font-family: monospace;"> + Argument being sent to the function</TD></TR> +<TR><TD style="font-family: monospace;">$1_name</TD><TD style="font-family: monospace;"> + Name of the argument (if provided)</TD></TR> +<TR><TD style="font-family: monospace;">$1_type</TD><TD style="font-family: monospace;"> + The actual C datatype matched by the typemap.</TD></TR> +<TR><TD style="font-family: monospace;">$1_ltype</TD><TD style="font-family: monospace;"> + The assignable version of the C datatype matched by the typemap.</TD></TR> +</TABLE> +</DIV> +<P> This is probably the most commonly redefined typemap because it can + be used to implement customized conversions.</P> +<P> In addition, the "in" typemap allows the number of converted + arguments to be specified. For example:</P> +<DIV class="code"> +<PRE>// Ignored argument. +<BR>%typemap(in, numinputs=0) int *out (int temp) { +<BR> $1 = &temp; +<BR>} +<BR></PRE> +</DIV> +<P> At this time, only zero or one arguments may be converted.</P> +<H4><A name="Ruby_typecheck_typemap"></A>32.7.6.2 "typecheck" typemap</H4> +<P> The "typecheck" typemap is used to support overloaded functions and + methods. It merely checks an argument to see whether or not it matches + a specific type. For example:</P> +<DIV class="code"> +<PRE>%typemap(typecheck,precedence=SWIG_TYPECHECK_INTEGER) int { +<BR> $1 = FIXNUM_P($input) ? 1 : 0; +<BR>} +<BR></PRE> +</DIV> +<P> For typechecking, the $1 variable is always a simple integer that is + set to 1 or 0 depending on whether or not the input argument is the + correct type.</P> +<P> If you define new "in" typemaps<EM> and</EM> your program uses + overloaded methods, you should also define a collection of "typecheck" + typemaps. More details about this follow in a later section on + "Typemaps and Overloading."</P> +<H4><A name="Ruby_out_typemap"></A>32.7.6.3 "out" typemap</H4> +<P>Converts return value of a C function to a Ruby object.</P> +<DIV class="code"><TT> +<BR> %typemap(out) int { +<BR> $result = INT2NUM( $1 ); +<BR> } +<BR></TT></DIV> +<P> The following special variables are available.</P> +<DIV class="diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" summary="Special variables - out typemap" +width="100%"><TBODY></TBODY> +<TR><TD style="font-family: monospace;">$result</TD><TD style="font-family: monospace;"> + Result object returned to target language.</TD></TR> +<TR><TD style="font-family: monospace;">$symname</TD><TD style="font-family: monospace;"> + Name of function/method being wrapped</TD></TR> +<TR><TD style="font-family: monospace;">$1...n</TD><TD style="font-family: monospace;"> + Argument being wrapped</TD></TR> +<TR><TD style="font-family: monospace;">$1_name</TD><TD style="font-family: monospace;"> + Name of the argument (if provided)</TD></TR> +<TR><TD style="font-family: monospace;">$1_type</TD><TD style="font-family: monospace;"> + The actual C datatype matched by the typemap.</TD></TR> +<TR><TD style="font-family: monospace;">$1_ltype</TD><TD style="font-family: monospace;"> + The assignable version of the C datatype matched by the typemap.</TD></TR> +</TABLE> +</DIV> +<BR> +<H4><A name="Ruby_arginit_typemap"></A>32.7.6.4 "arginit" typemap</H4> +<P> The "arginit" typemap is used to set the initial value of a function + argument--before any conversion has occurred. This is not normally + necessary, but might be useful in highly specialized applications. For + example:</P> +<DIV class="code"> +<PRE>// Set argument to NULL before any conversion occurs +<BR>%typemap(arginit) int *data { +<BR> $1 = NULL; +<BR>} +<BR></PRE> +</DIV> +<H4><A name="Ruby_default_typemap"></A>32.7.6.5 "default" typemap</H4> +<P> The "default" typemap is used to turn an argument into a default + argument. For example:</P> +<DIV class="code"> +<PRE>%typemap(default) int flags { +<BR> $1 = DEFAULT_FLAGS; +<BR>} +<BR>... +<BR>int foo(int x, int y, int flags); +<BR></PRE> +</DIV> +<P> The primary use of this typemap is to either change the wrapping of + default arguments or specify a default argument in a language where + they aren't supported (like C). Target languages that do not support + optional arguments, such as Java and C#, effectively ignore the value + specified by this typemap as all arguments must be given.</P> +<P> Once a default typemap has been applied to an argument, all + arguments that follow must have default values. See the <A href="http://www.swig.org/Doc1.3/SWIGDocumentation.html#SWIG_default_args"> + Default/optional arguments</A> section for further information on + default argument wrapping.</P> +<H4><A name="Ruby_check_typemap"></A>32.7.6.6 "check" typemap</H4> +<P> The "check" typemap is used to supply value checking code during + argument conversion. The typemap is applied<EM> after</EM> arguments + have been converted. For example:</P> +<DIV class="code"> +<PRE>%typemap(check) int positive { +<BR> if ($1 <= 0) { +<BR> SWIG_exception(SWIG_ValueError,"Expected positive value."); +<BR> } +<BR>} +<BR></PRE> +</DIV> +<H4><A name="Ruby_argout_typemap_"></A>32.7.6.7 "argout" typemap</H4> +<P> The "argout" typemap is used to return values from arguments. This + is most commonly used to write wrappers for C/C++ functions that need + to return multiple values. The "argout" typemap is almost always + combined with an "in" typemap---possibly to ignore the input value. For + example:</P> +<DIV class="code"> +<PRE>/* Set the input argument to point to a temporary variable */ +<BR>%typemap(in, numinputs=0) int *out (int temp) { +<BR> $1 = &temp; +<BR>} +<BR> +<BR>%typemap(argout, fragment="output_helper") int *out { +<BR> // Append output value $1 to $result (assuming a single integer in this case) +<BR> $result = output_helper( $result, INT2NUM(*$1) ); +<BR>} +<BR></PRE> +</DIV> +<P> The following special variables are available.</P> +<DIV class="diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" summary="Special variables - argout typemap" +width="100%"><TBODY></TBODY> +<TR><TD style="font-family: monospace;">$result</TD><TD style="font-family: monospace;"> + Result object returned to target language.</TD></TR> +<TR><TD style="font-family: monospace;">$input</TD><TD style="font-family: monospace;"> + The original input object passed.</TD></TR> +<TR><TD style="font-family: monospace;">$symname</TD><TD style="font-family: monospace;"> + Name of function/method being wrapped.</TD></TR> +</TABLE> +</DIV> +<P> The code supplied to the "argout" typemap is always placed after the + "out" typemap. If multiple return values are used, the extra return + values are often appended to return value of the function.</P> +<P>Output helper is a fragment that usually defines a macro to some + function like SWIG_Ruby_AppendOutput.</P> +<P> See the <TT>typemaps.i</TT> library for examples.</P> +<H4><A name="Ruby_freearg_typemap_"></A>32.7.6.8 "freearg" typemap</H4> +<P> The "freearg" typemap is used to cleanup argument data. It is only + used when an argument might have allocated resources that need to be + cleaned up when the wrapper function exits. The "freearg" typemap + usually cleans up argument resources allocated by the "in" typemap. For + example:</P> +<DIV class="code"> +<PRE>// Get a list of integers +<BR>%typemap(in) int *items { +<BR> int nitems = Length($input); +<BR> $1 = (int *) malloc(sizeof(int)*nitems); +<BR>} +<BR>// Free the list +<BR>%typemap(freearg) int *items { +<BR> free($1); +<BR>} +<BR></PRE> +</DIV> +<P> The "freearg" typemap inserted at the end of the wrapper function, + just before control is returned back to the target language. This code + is also placed into a special variable <TT>$cleanup</TT> that may be + used in other typemaps whenever a wrapper function needs to abort + prematurely.</P> +<H4><A name="Ruby_newfree_typemap"></A>32.7.6.9 "newfree" typemap</H4> +<P> The "newfree" typemap is used in conjunction with the <TT>%newobject</TT> + directive and is used to deallocate memory used by the return result of + a function. For example:</P> +<DIV class="code"> +<PRE>%typemap(newfree) string * { +<BR> delete $1; +<BR>} +<BR>%typemap(out) string * { +<BR> $result = PyString_FromString($1->c_str()); +<BR>} +<BR>... +<BR> +<BR>%newobject foo; +<BR>... +<BR>string *foo(); +<BR></PRE> +</DIV> +<P> See <A href="http://www.swig.org/Doc1.3/SWIGDocumentation.html#ownership"> +Object ownership and %newobject</A> for further details.</P> +<H4><A name="Ruby_memberin_typemap"></A>32.7.6.10 "memberin" typemap</H4> +<P> The "memberin" typemap is used to copy data from<EM> an already + converted input value</EM> into a structure member. It is typically + used to handle array members and other special cases. For example:</P> +<DIV class="code"> +<PRE>%typemap(memberin) int [4] { +<BR> memmove($1, $input, 4*sizeof(int)); +<BR>} +<BR></PRE> +</DIV> +<P> It is rarely necessary to write "memberin" typemaps---SWIG already + provides a default implementation for arrays, strings, and other + objects.</P> +<H4><A name="Ruby_varin_typemap"></A>32.7.6.11 "varin" typemap</H4> +<P> The "varin" typemap is used to convert objects in the target + language to C for the purposes of assigning to a C/C++ global variable. + This is implementation specific.</P> +<H4><A name="Ruby_varout_typemap_"></A>32.7.6.12 "varout" typemap</H4> +<P> The "varout" typemap is used to convert a C/C++ object to an object + in the target language when reading a C/C++ global variable. This is + implementation specific.</P> +<H4><A name="Ruby_throws_typemap"></A>32.7.6.13 "throws" typemap</H4> +<P> The "throws" typemap is only used when SWIG parses a C++ method with + an exception specification or has the <TT>%catches</TT> feature + attached to the method. It provides a default mechanism for handling + C++ methods that have declared the exceptions they will throw. The + purpose of this typemap is to convert a C++ exception into an error or + exception in the target language. It is slightly different to the other + typemaps as it is based around the exception type rather than the type + of a parameter or variable. For example:</P> +<DIV class="code"> +<PRE>%typemap(throws) const char * %{ +<BR> rb_raise(rb_eRuntimeError, $1); +<BR> SWIG_fail; +<BR>%} +<BR>void bar() throw (const char *); +<BR></PRE> +</DIV> +<P> As can be seen from the generated code below, SWIG generates an + exception handler with the catch block comprising the "throws" typemap + content.</P> +<DIV class="code"> +<PRE>... +<BR>try { +<BR> bar(); +<BR>} +<BR>catch(char const *_e) { +<BR> rb_raise(rb_eRuntimeError, _e); +<BR> SWIG_fail; +<BR>} +<BR>... +<BR></PRE> +</DIV> +<P> Note that if your methods do not have an exception specification yet + they do throw exceptions, SWIG cannot know how to deal with them. For a + neat way to handle these, see the <A href="http://www.swig.org/Doc1.3/SWIGDocumentation.html#exception"> +Exception handling with %exception</A> section.</P> +<H4><A name="Ruby_directorin_typemap"></A>32.7.6.14 directorin typemap</H4> +<P>Converts C++ objects in director member functions to ruby objects. It + is roughly the opposite of the "in" typemap, making its typemap rule + often similar to the "out" typemap.</P> +<DIV class="code"><TT> +<BR> %typemap(directorin) int { +<BR> $result = INT2NUM($1); +<BR> } +<BR></TT></DIV> +<P> The following special variables are available.</P> +<DIV class="diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" summary="Special variables - directorin typemap" +width="100%"><TBODY></TBODY> +<TR><TD style="font-family: monospace;">$result</TD><TD style="font-family: monospace;"> + Result object returned to target language.</TD></TR> +<TR><TD style="font-family: monospace;">$symname</TD><TD style="font-family: monospace;"> + Name of function/method being wrapped</TD></TR> +<TR><TD style="font-family: monospace;">$1...n</TD><TD style="font-family: monospace;"> + Argument being wrapped</TD></TR> +<TR><TD style="font-family: monospace;">$1_name</TD><TD style="font-family: monospace;"> + Name of the argument (if provided)</TD></TR> +<TR><TD style="font-family: monospace;">$1_type</TD><TD style="font-family: monospace;"> + The actual C datatype matched by the typemap.</TD></TR> +<TR><TD style="font-family: monospace;">$1_ltype</TD><TD style="font-family: monospace;"> + The assignable version of the C datatype matched by the typemap.</TD></TR> +<TR><TD style="font-family: monospace;">this</TD><TD style="font-family: monospace;"> + C++ this, referring to the class itself.</TD></TR> +</TABLE> +</DIV> +<H4><A name="Ruby_directorout_typemap"></A>32.7.6.15 directorout typemap</H4> +<P>Converts Ruby objects in director member functions to C++ objects. + It is roughly the opposite of the "out" typemap, making its rule often + similar to the "in" typemap.</P> +<DIV class="code"><TT style="font-family: monospace;"> +<BR> %typemap(directorout) int {</TT><TT> +<BR> $result = NUM2INT($1);</TT> +<BR> <TT style="font-family: monospace;">} +<BR></TT></DIV> +<P> The following special variables are available:</P> +<DIV class="diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" summary="Special variables - directorout typemap" +width="100%"><TBODY></TBODY> +<TR><TD style="font-family: monospace;">$symname</TD><TD style="font-family: monospace;"> + Name of function/method being wrapped</TD></TR> +<TR><TD style="font-family: monospace;">$1...n</TD><TD style="font-family: monospace;"> + Argument being sent to the function</TD></TR> +<TR><TD style="font-family: monospace;">$1_name</TD><TD style="font-family: monospace;"> + Name of the argument (if provided)</TD></TR> +<TR><TD style="font-family: monospace;">$1_type</TD><TD style="font-family: monospace;"> + The actual C datatype matched by the typemap.</TD></TR> +<TR><TD style="font-family: monospace;">$1_ltype</TD><TD style="font-family: monospace;"> + The assignable version of the C datatype matched by the typemap.</TD></TR> +<TR><TD style="font-family: monospace;">this</TD><TD style="font-family: monospace;"> + C++ this, referring to the class itself.</TD></TR> +</TABLE> +</DIV> +<P>Currently, the directorout nor the out typemap support the option +<!--span style="font-family: monospace;"--> +numoutputs, but the Ruby module provides that functionality through a + %feature directive. Thus, a function can be made to return "nothing" + if you do:</P> +<DIV class="code" style="font-family: monospace;"> +%feature("numoutputs","0") MyClass::function;</DIV> +<P>This feature can be useful if a function returns a status code, which + you want to discard but still use the typemap to raise an exception. +<BR></P> +<H4><A name="Ruby_directorargout_typemap"></A>32.7.6.16 directorargout + typemap</H4> +<P>Output argument processing in director member functions.</P> +<DIV class="code"><TT style="font-family: monospace;"> +%typemap(directorargout, fragment="output_helper") int {</TT><TT> +<BR> $result = output_helper( $result, NUM2INT($1) );</TT> +<BR> <TT style="font-family: monospace;">}</TT></DIV> +<P> The following special variables are available:</P> +<DIV class="diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" style="text-align: left; width: 100%;" +summary="Special variables - directorargout typemap"><TBODY></TBODY> +<TR><TD style="font-family: monospace;">$result</TD><TD style="font-family: monospace;"> +Result that the director function returns</TD></TR> +<TR><TD style="font-family: monospace;">$symname</TD><TD style="font-family: monospace;"> +name of the function/method being wrapped</TD></TR> +<TR><TD style="font-family: monospace;">$1...n</TD><TD style="font-family: monospace;"> +Argument being sent to the function</TD></TR> +<TR><TD style="font-family: monospace;">$1_name</TD><TD style="font-family: monospace;"> +Name of the argument (if provided)</TD></TR> +<TR><TD style="font-family: monospace;">$1_type</TD><TD style="font-family: monospace;"> +The actual C datatype matched by the typemap</TD></TR> +<TR><TD style="font-family: monospace;">$1_ltype</TD><TD style="font-family: monospace;"> +The assignable version of the C datatype matched by the typemap</TD></TR> +<TR><TD style="font-family: monospace;">this</TD><TD style="font-family: monospace;"> +C++ this, referring to the instance of the class itself</TD></TR> +</TABLE> +</DIV> +<H4><A name="Ruby_ret_typemap"></A>32.7.6.17 ret typemap</H4> +<P>Cleanup of function return values</P> +<H4><A name="Ruby_globalin_typemap"></A>32.7.6.18 globalin typemap</H4> +<P>Setting of C global variables</P> +<H3><A name="Ruby_nn40"></A>32.7.7 Typemap variables</H3> +<P> Within a typemap, a number of special variables prefaced with a <TT> +$</TT> may appear. A full list of variables can be found in the "<A href="#Typemaps"> +Typemaps</A>" chapter. This is a list of the most common variables:</P> +<P><TT>$1</TT></P> +<DIV class="indent">A C local variable corresponding to the actual type + specified in the <TT>%typemap</TT> directive. For input values, this is + a C local variable that is supposed to hold an argument value. For + output values, this is the raw result that is supposed to be returned + to Ruby.</DIV> +<P><TT>$input</TT></P> +<DIV class="indent">A <TT>VALUE</TT> holding a raw Ruby object with an + argument or variable value.</DIV> +<P><TT>$result</TT></P> +<DIV class="indent">A <TT>VALUE</TT> that holds the result to be + returned to Ruby.</DIV> +<P><TT>$1_name</TT></P> +<DIV class="indent">The parameter name that was matched.</DIV> +<P><TT>$1_type</TT></P> +<DIV class="indent">The actual C datatype matched by the typemap.</DIV> +<P><TT>$1_ltype</TT></P> +<DIV class="indent">An assignable version of the datatype matched by the + typemap (a type that can appear on the left-hand-side of a C assignment + operation). This type is stripped of qualifiers and may be an altered + version of <TT>$1_type</TT>. All arguments and local variables in + wrapper functions are declared using this type so that their values can + be properly assigned.</DIV> +<P><TT>$symname</TT></P> +<DIV class="indent">The Ruby name of the wrapper function being created.</DIV> +<H3><A name="Ruby_nn41"></A>32.7.8 Useful Functions</H3> +<P> When you write a typemap, you usually have to work directly with + Ruby objects. The following functions may prove to be useful. (These + functions plus many more can be found in <A href="http://www.rubycentral.com/book"> +<EM>Programming Ruby</EM></A>, by David Thomas and Andrew Hunt.) </P> +<P>In addition, we list equivalent functions that Swig defines, which + provide a language neutral conversion (these functions are defined for + each swig language supported). If you are trying to create a swig file + that will work under multiple languages, it is recommended you stick to + the swig functions instead of the native Ruby functions. That should + help you avoid having to rewrite a lot of typemaps across multiple + languages.</P> +<H4><A name="Ruby_nn42"></A>32.7.8.1 C Datatypes to Ruby Objects</H4> +<DIV class="diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" style="width: 100%;" summary="Datatypes"> +<TBODY></TBODY> +<TR><TH style="font-weight: bold;">RUBY</TH><TH style="font-weight: bold;"> +Swig</TH><TD></TD></TR> +<TR><TD style="font-family: monospace;">INT2NUM(long or int)</TD><TD style="font-family: monospace;"> +SWIG_From_int(int x)</TD><TD> int to Fixnum or Bignum</TD></TR> +<TR><TD style="font-family: monospace;">INT2FIX(long or int)</TD><TD style="font-family: monospace;"> +</TD><TD> int to Fixnum (faster than INT2NUM)</TD></TR> +<TR><TD style="font-family: monospace;">CHR2FIX(char)</TD><TD style="font-family: monospace;"> +SWIG_From_char(char x)</TD><TD> char to Fixnum</TD></TR> +<TR><TD style="font-family: monospace;">rb_str_new2(char*)</TD><TD style="font-family: monospace;"> +SWIG_FromCharPtrAndSize(char*, size_t)</TD><TD> char* to String</TD></TR> +<TR><TD style="font-family: monospace;">rb_float_new(double)</TD><TD style="font-family: monospace;"> +SWIG_From_double(double), +<BR> SWIG_From_float(float)</TD><TD>float/double to Float</TD></TR> +</TABLE> +</DIV> +<H4><A name="Ruby_nn43"></A>32.7.8.2 Ruby Objects to C Datatypes</H4> +<P>Here, while the Ruby versions return the value directly, the SWIG + versions do not, but return a status value to indicate success ( +<!--span style="font-family: monospace;"--> +SWIG_OK). While more akward to use, this allows you to write typemaps + that report more helpful error messages, like:</P> +<DIV class="code" style="font-family: monospace;"> +<BR> %typemap(in) size_t (int ok) +<BR> +<BR> ok = SWIG_AsVal_size_t($input, &$1); +<BR> if (!SWIG_IsOK(ok)) { +<BR> SWIG_exception_fail(SWIG_ArgError(ok), Ruby_Format_TypeError( + "$1_name", "$1_type","$symname", $argnum, $input )); +<BR> } +<BR> +<BR> }</DIV><DIV style="font-family: monospace;"> </DIV><DIV class="diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" summary="Ruby objects" width="100%"> +<TBODY></TBODY> +<TR><TD style="font-family: monospace;">int NUM2INT(Numeric)</TD><TD style="font-family: monospace;"> +SWIG_AsVal_int(VALUE, int*)</TD></TR> +<TR><TD style="font-family: monospace;">int FIX2INT(Numeric)</TD><TD style="font-family: monospace;"> +SWIG_AsVal_int(VALUE, int*)</TD></TR> +<TR><TD style="font-family: monospace;">unsigned int NUM2UINT(Numeric)</TD><TD +style="font-family: monospace;">SWIG_AsVal_unsigned_SS_int(VALUE, int*)</TD> +</TR> +<TR><TD style="font-family: monospace;">unsigned int FIX2UINT(Numeric)</TD><TD +style="font-family: monospace;">SWIG_AsVal_unsigned_SS_int(VALUE, int*)</TD> +</TR> +<TR><TD style="font-family: monospace;">long NUM2LONG(Numeric)</TD><TD style="font-family: monospace;"> +SWIG_AsVal_long(VALUE, long*)</TD></TR> +<TR><TD style="font-family: monospace;">long FIX2LONG(Numeric)</TD><TD style="font-family: monospace;"> +SWIG_AsVal_long(VALUE, long*)</TD></TR> +<TR><TD style="font-family: monospace;">unsigned long FIX2ULONG(Numeric)</TD><TD +style="font-family: monospace;">SWIG_AsVal_unsigned_SS_long(VALUE, + unsigned long*)</TD></TR> +<TR><TD style="font-family: monospace;">char NUM2CHR(Numeric or String)</TD><TD +style="font-family: monospace;">SWIG_AsVal_char(VALUE, int*)</TD></TR> +<TR><TD style="font-family: monospace;">char * STR2CSTR(String)</TD><TD style="font-family: monospace;"> +SWIG_AsCharPtrAndSize(VALUE, char*, size_t, int* alloc)</TD></TR> +<TR><TD style="font-family: monospace;">char * rb_str2cstr(String, + int*length)</TD><TD style="font-family: monospace;"></TD></TR> +<TR><TD style="font-family: monospace;">double NUM2DBL(Numeric)</TD><TD style="font-family: monospace;"> +(double) SWIG_AsVal_int(VALUE) or similar</TD></TR> +</TABLE> +</DIV> +<H4><A name="Ruby_nn44"></A>32.7.8.3 Macros for VALUE</H4> +<P> <TT>RSTRING_LEN(str)</TT></P> +<DIV class="indent">length of the Ruby string</DIV> +<P><TT>RSTRING_PTR(str)</TT></P> +<DIV class="indent">pointer to string storage</DIV> +<P><TT>RARRAY_LEN(arr)</TT></P> +<DIV class="indent">length of the Ruby array</DIV> +<P><TT>RARRAY(arr)->capa</TT></P> +<DIV class="indent">capacity of the Ruby array</DIV> +<P><TT>RARRAY_PTR(arr)</TT></P> +<DIV class="indent">pointer to array storage</DIV> +<H4><A name="Ruby_nn45"></A>32.7.8.4 Exceptions</H4> +<P> <TT>void rb_raise(VALUE exception, const char *fmt, ...)</TT></P> +<DIV class="indent"> Raises an exception. The given format string<I> fmt</I> + and remaining arguments are interpreted as with <TT>printf()</TT>.</DIV> +<P><TT>void rb_fatal(const char *fmt, ...)</TT></P> +<DIV class="indent"> Raises a fatal exception, terminating the process. + No rescue blocks are called, but ensure blocks will be called. The + given format string<I> fmt</I> and remaining arguments are interpreted + as with <TT>printf()</TT>.</DIV> +<P><TT>void rb_bug(const char *fmt, ...)</TT></P> +<DIV class="indent"> Terminates the process immediately -- no handlers + of any sort will be called. The given format string<I> fmt</I> and + remaining arguments are interpreted as with <TT>printf()</TT>. You + should call this function only if a fatal bug has been exposed.</DIV> +<P><TT>void rb_sys_fail(const char *msg)</TT></P> +<DIV class="indent"> Raises a platform-specific exception corresponding + to the last known system error, with the given string<I> msg</I>.</DIV> +<P><TT>VALUE rb_rescue(VALUE (*body)(VALUE), VALUE args, + VALUE(*rescue)(VALUE, VALUE), VALUE rargs)</TT></P> +<DIV class="indent"> Executes<I> body</I> with the given<I> args</I>. If + a <TT>StandardError</TT> exception is raised, then execute<I> rescue</I> + with the given<I> rargs</I>.</DIV> +<P><TT>VALUE rb_ensure(VALUE(*body)(VALUE), VALUE args, + VALUE(*ensure)(VALUE), VALUE eargs)</TT></P> +<DIV class="indent"> Executes<I> body</I> with the given<I> args</I>. + Whether or not an exception is raised, execute<I> ensure</I> with the + given<I> rargs</I> after<I> body</I> has completed.</DIV> +<P><TT>VALUE rb_protect(VALUE (*body)(VALUE), VALUE args, int *result)</TT> +</P> +<DIV class="indent"> Executes<I> body</I> with the given<I> args</I> and + returns nonzero in result if any exception was raised.</DIV> +<P><TT>void rb_notimplement()</TT></P> +<DIV class="indent"> Raises a <TT>NotImpError</TT> exception to indicate + that the enclosed function is not implemented yet, or not available on + this platform.</DIV> +<P><TT>void rb_exit(int status)</TT></P> +<DIV class="indent"> Exits Ruby with the given<I> status</I>. Raises a <TT> +SystemExit</TT> exception and calls registered exit functions and + finalizers.</DIV> +<P><TT>void rb_warn(const char *fmt, ...)</TT></P> +<DIV class="indent"> Unconditionally issues a warning message to + standard error. The given format string<I> fmt</I> and remaining + arguments are interpreted as with <TT>printf()</TT>.</DIV> +<P><TT>void rb_warning(const char *fmt, ...)</TT></P> +<DIV class="indent"> Conditionally issues a warning message to standard + error if Ruby was invoked with the <TT>-w</TT> flag. The given format + string<I> fmt</I> and remaining arguments are interpreted as with <TT> +printf()</TT>.</DIV> +<H4><A name="Ruby_nn46"></A>32.7.8.5 Iterators</H4> +<P> <TT>void rb_iter_break()</TT></P> +<DIV class="indent"> Breaks out of the enclosing iterator block.</DIV> +<P><TT>VALUE rb_each(VALUE obj)</TT></P> +<DIV class="indent"> Invokes the <TT>each</TT> method of the given<I> + obj</I>.</DIV> +<P><TT>VALUE rb_yield(VALUE arg)</TT></P> +<DIV class="indent"> Transfers execution to the iterator block in the + current context, passing<I> arg</I> as an argument. Multiple values may + be passed in an array.</DIV> +<P><TT>int rb_block_given_p()</TT></P> +<DIV class="indent"> Returns <TT>true</TT> if <TT>yield</TT> would + execute a block in the current context; that is, if a code block was + passed to the current method and is available to be called.</DIV> +<P><TT>VALUE rb_iterate(VALUE (*method)(VALUE), VALUE args, VALUE + (*block)(VALUE, VALUE), VALUE arg2)</TT></P> +<DIV class="indent"> Invokes<I> method</I> with argument<I> args</I> and + block<I> block</I>. A <TT>yield</TT> from that method will invoke<I> + block</I> with the argument given to <TT>yield</TT>, and a second + argument<I> arg2</I>.</DIV> +<P><TT>VALUE rb_catch(const char *tag, VALUE (*proc)(VALUE, VALUE), + VALUE value)</TT></P> +<DIV class="indent"> Equivalent to Ruby's <TT>catch</TT>.</DIV> +<P><TT>void rb_throw(const char *tag, VALUE value)</TT></P> +<DIV class="indent"> Equivalent to Ruby's <TT>throw</TT>.</DIV> +<H3><A name="Ruby_nn47"></A>32.7.9 Typemap Examples</H3> +<P> This section includes a few examples of typemaps. For more examples, + you might look at the examples in the <TT>Example/ruby</TT> directory.</P> +<H3><A name="Ruby_nn48"></A>32.7.10 Converting a Ruby array to a char **</H3> +<P> A common problem in many C programs is the processing of command + line arguments, which are usually passed in an array of <TT>NULL</TT> + terminated strings. The following SWIG interface file allows a Ruby + Array instance to be used as a <TT>char **</TT> object.</P> +<DIV class="code"> +<PRE>%module argv +<BR> +<BR>// This tells SWIG to treat char ** as a special case +<BR>%typemap(in) char ** { +<BR> /* Get the length of the array */ +<BR> int size = RARRAY($input)->len; +<BR> int i; +<BR> $1 = (char **) malloc((size+1)*sizeof(char *)); +<BR> /* Get the first element in memory */ +<BR> VALUE *ptr = RARRAY($input)->ptr; +<BR> for (i=0; i < size; i++, ptr++) +<BR> /* Convert Ruby Object String to char* */ +<BR> $1[i]= STR2CSTR(*ptr); +<BR> $1[i]=NULL; /* End of list */ +<BR>} +<BR> +<BR>// This cleans up the char ** array created before +<BR>// the function call +<BR> +<BR>%typemap(freearg) char ** { +<BR> free((char *) $1); +<BR>} +<BR> +<BR>// Now a test function +<BR>%inline %{ +<BR>int print_args(char **argv) { +<BR> int i = 0; +<BR> while (argv[i]) { +<BR> printf("argv[%d] = %s\n", i,argv[i]); +<BR> i++; +<BR> } +<BR> return i; +<BR>} +<BR>%} +<BR> +<BR></PRE> +</DIV> +<P> When this module is compiled, the wrapped C function now operates as + follows :</P> +<DIV class="code targetlang"> +<PRE>require 'Argv' +<BR>Argv.print_args(["Dave","Mike","Mary","Jane","John"]) +<BR>argv[0] = Dave +<BR>argv[1] = Mike +<BR>argv[2] = Mary +<BR>argv[3] = Jane +<BR>argv[4] = John +<BR></PRE> +</DIV> +<P> In the example, two different typemaps are used. The "in" typemap is + used to receive an input argument and convert it to a C array. Since + dynamic memory allocation is used to allocate memory for the array, the + "freearg" typemap is used to later release this memory after the + execution of the C function.</P> +<H3><A name="Ruby_nn49"></A>32.7.11 Collecting arguments in a hash</H3> +<P> Ruby's solution to the "keyword arguments" capability of some other + languages is to allow the programmer to pass in one or more key-value + pairs as arguments to a function. All of those key-value pairs are + collected in a single <TT>Hash</TT> argument that's presented to the + function. If it makes sense, you might want to provide similar + functionality for your Ruby interface. For example, suppose you'd like + to wrap this C function that collects information about people's vital + statistics:</P> +<DIV class="code"> +<PRE>void setVitalStats(const char *person, int nattributes, const char **names, int *values); +<BR></PRE> +</DIV> +<P> and you'd like to be able to call it from Ruby by passing in an + arbitrary number of key-value pairs as inputs, e.g.</P> +<DIV class="code targetlang"> +<PRE>setVitalStats("Fred", +<BR> 'weight' => 270, +<BR> 'age' => 42 +<BR> ) +<BR></PRE> +</DIV> +<P> To make this work, you need to write a typemap that expects a Ruby <TT> +Hash</TT> as its input and somehow extracts the last three arguments (<I> +nattributes</I>,<I> names</I> and<I> values</I>) needed by your C + function. Let's start with the basics:</P> +<DIV class="code"> +<PRE>%typemap(in) (int nattributes, const char **names, const int *values) +<BR> (VALUE keys_arr, int i, VALUE key, VALUE val) { +<BR>} +<BR> </PRE> +</DIV> +<P> This <TT>%typemap</TT> directive tells SWIG that we want to match + any function declaration that has the specified types and names of + arguments somewhere in the argument list. The fact that we specified + the argument names (<I>nattributes</I>,<I> names</I> and<I> values</I>) + in our typemap is significant; this ensures that SWIG won't try to + apply this typemap to<I> other</I> functions it sees that happen to + have a similar declaration with different argument names. The arguments + that appear in the second set of parentheses (<I>keys_arr</I>,<I> i</I> +,<I> key</I> and<I> val</I>) define local variables that our typemap + will need.</P> +<P>Since we expect the input argument to be a <TT>Hash</TT>, let's next + add a check for that:</P> +<DIV class="code"> +<PRE>%typemap(in) (int nattributes, const char **names, const int *values) +<BR> (VALUE keys_arr, int i, VALUE key, VALUE val) { +<BR> <B>Check_Type($input, T_HASH);</B> +<BR>} +<BR></PRE> +</DIV> +<P> <TT>Check_Type()</TT> is just a macro (defined in the Ruby header + files) that confirms that the input argument is of the correct type; if + it isn't, an exception will be raised.</P> +<P>The next task is to determine how many key-value pairs are present in + the hash; we'll assign this number to the first typemap argument (<TT> +$1</TT>). This is a little tricky since the Ruby/C API doesn't provide a + public function for querying the size of a hash, but we can get around + that by calling the hash's<I> size</I> method directly and converting + its result to a C <TT>int</TT> value:</P> +<DIV class="code"> +<PRE>%typemap(in) (int nattributes, const char **names, const int *values) +<BR> (VALUE keys_arr, int i, VALUE key, VALUE val) { +<BR> Check_Type($input, T_HASH); +<BR> <B>$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));</B> +<BR>} +<BR></PRE> +</DIV> +<P> So now we know the number of attributes. Next we need to initialize + the second and third typemap arguments (i.e. the two C arrays) to <TT> +NULL</TT> and set the stage for extracting the keys and values from the + hash:</P> +<DIV class="code"> +<PRE>%typemap(in) (int nattributes, const char **names, const int *values) +<BR> (VALUE keys_arr, int i, VALUE key, VALUE val) { +<BR> Check_Type($input, T_HASH); +<BR> $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL)); +<BR> <B>$2 = NULL; +<BR> $3 = NULL; +<BR> if ($1 > 0) { +<BR> $2 = (char **) malloc($1*sizeof(char *)); +<BR> $3 = (int *) malloc($1*sizeof(int)); +<BR> }</B> +<BR>} +<BR></PRE> +</DIV> +<P> There are a number of ways we could extract the keys and values from + the input hash, but the simplest approach is to first call the hash's<I> + keys</I> method (which returns a Ruby array of the keys) and then start + looping over the elements in that array:</P> +<DIV class="code"> +<PRE>%typemap(in) (int nattributes, const char **names, const int *values) +<BR> (VALUE keys_arr, int i, VALUE key, VALUE val) { +<BR> Check_Type($input, T_HASH); +<BR> $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL)); +<BR> $2 = NULL; +<BR> $3 = NULL; +<BR> if ($1 > 0) { +<BR> $2 = (char **) malloc($1*sizeof(char *)); +<BR> $3 = (int *) malloc($1*sizeof(int)); +<BR> <B>keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL); +<BR> for (i = 0; i < $1; i++) { +<BR> }</B> +<BR>} +<BR>} +<BR></PRE> +</DIV> +<P> Recall that<I> keys_arr</I> and<I> i</I> are local variables for + this typemap. For each element in the<I> keys_arr</I> array, we want to + get the key itself, as well as the value corresponding to that key in + the hash:</P> +<DIV class="code"> +<PRE>%typemap(in) (int nattributes, const char **names, const int *values) +<BR> (VALUE keys_arr, int i, VALUE key, VALUE val) { +<BR> Check_Type($input, T_HASH); +<BR> $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL)); +<BR> $2 = NULL; +<BR> $3 = NULL; +<BR> if ($1 > 0) { +<BR> $2 = (char **) malloc($1*sizeof(char *)); +<BR> $3 = (int *) malloc($1*sizeof(int)); +<BR> keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL); +<BR> for (i = 0; i < $1; i++) { +<BR> <B>key = rb_ary_entry(keys_arr, i); +<BR> val = rb_hash_aref($input, key);</B> +<BR>} +<BR>} +<BR>} +<BR></PRE> +</DIV> +<P> To be safe, we should again use the <TT>Check_Type()</TT> macro to + confirm that the key is a <TT>String</TT> and the value is a <TT>Fixnum</TT> +:</P> +<DIV class="code"> +<PRE>%typemap(in) (int nattributes, const char **names, const int *values) +<BR> (VALUE keys_arr, int i, VALUE key, VALUE val) { +<BR> Check_Type($input, T_HASH); +<BR> $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL)); +<BR> $2 = NULL; +<BR> $3 = NULL; +<BR> if ($1 > 0) { +<BR> $2 = (char **) malloc($1*sizeof(char *)); +<BR> $3 = (int *) malloc($1*sizeof(int)); +<BR> keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL); +<BR> for (i = 0; i < $1; i++) { +<BR> key = rb_ary_entry(keys_arr, i); +<BR> val = rb_hash_aref($input, key); +<BR> <B>Check_Type(key, T_STRING); +<BR> Check_Type(val, T_FIXNUM);</B> +<BR>} +<BR>} +<BR>} +<BR></PRE> +</DIV> +<P> Finally, we can convert these Ruby objects into their C equivalents + and store them in our local C arrays:</P> +<DIV class="code"> +<PRE>%typemap(in) (int nattributes, const char **names, const int *values) +<BR> (VALUE keys_arr, int i, VALUE key, VALUE val) { +<BR> Check_Type($input, T_HASH); +<BR> $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL)); +<BR> $2 = NULL; +<BR> $3 = NULL; +<BR> if ($1 > 0) { +<BR> $2 = (char **) malloc($1*sizeof(char *)); +<BR> $3 = (int *) malloc($1*sizeof(int)); +<BR> keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL); +<BR> for (i = 0; i < $1; i++) { +<BR> key = rb_ary_entry(keys_arr, i); +<BR> val = rb_hash_aref($input, key); +<BR> Check_Type(key, T_STRING); +<BR> Check_Type(val, T_FIXNUM); +<BR> <B>$2[i] = STR2CSTR(key); +<BR> $3[i] = NUM2INT(val);</B> +<BR>} +<BR>} +<BR>} +<BR></PRE> +</DIV> +<P> We're not done yet. Since we used <TT>malloc()</TT> to dynamically + allocate the memory used for the<I> names</I> and<I> values</I> + arguments, we need to provide a corresponding "freearg" typemap to free + that memory so that there is no memory leak. Fortunately, this typemap + is a lot easier to write:</P> +<DIV class="code"> +<PRE>%typemap(freearg) (int nattributes, const char **names, const int *values) { +<BR> free((void *) $2); +<BR> free((void *) $3); +<BR>} +<BR></PRE> +</DIV> +<P> All of the code for this example, as well as a sample Ruby program + that uses the extension, can be found in the <TT>Examples/ruby/hashargs</TT> + directory of the SWIG distribution.</P> +<H3><A name="Ruby_nn50"></A>32.7.12 Pointer handling</H3> +<P> Occasionally, it might be necessary to convert pointer values that + have been stored using the SWIG typed-pointer representation. Since + there are several ways in which pointers can be represented, the + following two functions are used to safely perform this conversion:</P> +<P><TT>int SWIG_ConvertPtr(VALUE obj, void **ptr, swig_type_info *ty, + int flags)</TT></P> +<DIV class="indent">Converts a Ruby object<I> obj</I> to a C pointer + whose address is<I> ptr</I> (i.e.<I> ptr</I> is a pointer to a + pointer). The third argument,<I> ty</I>, is a pointer to a SWIG type + descriptor structure. If<I> ty</I> is not <TT>NULL</TT>, that type + information is used to validate type compatibility and other aspects of + the type conversion. If<I> flags</I> is non-zero, any type errors + encountered during this validation result in a Ruby <TT>TypeError</TT> + exception being raised; if<I> flags</I> is zero, such type errors will + cause <TT>SWIG_ConvertPtr()</TT> to return -1 but not raise an + exception. If<I> ty</I> is <TT>NULL</TT>, no type-checking is + performed.</DIV> +<P> <TT>VALUE SWIG_NewPointerObj(void *ptr, swig_type_info *ty, int own)</TT> +</P> +<DIV class="indent">Creates a new Ruby pointer object. Here,<I> ptr</I> + is the pointer to convert,<I> ty</I> is the SWIG type descriptor + structure that describes the type, and<I> own</I> is a flag that + indicates whether or not Ruby should take ownership of the pointer + (i.e. whether Ruby should free this data when the corresponding Ruby + instance is garbage-collected).</DIV> +<P> Both of these functions require the use of a special SWIG + type-descriptor structure. This structure contains information about + the mangled name of the datatype, type-equivalence information, as well + as information about converting pointer values under C++ inheritance. + For a type of <TT>Foo *</TT>, the type descriptor structure is usually + accessed as follows:</P> +<DIV class="indent code"> +<PRE>Foo *foo; +<BR>SWIG_ConvertPtr($input, (void **) &foo, SWIGTYPE_p_Foo, 1); +<BR> +<BR>VALUE obj; +<BR>obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0); +<BR></PRE> +</DIV> +<P> In a typemap, the type descriptor should always be accessed using + the special typemap variable <TT>$1_descriptor</TT>. For example:</P> +<DIV class="indent code"> +<PRE>%typemap(in) Foo * { +<BR> SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); +<BR>} +<BR></PRE> +</DIV> +<H4><A name="Ruby_nn51"></A>32.7.12.1 Ruby Datatype Wrapping</H4> +<P> <TT>VALUE Data_Wrap_Struct(VALUE class, void (*mark)(void *), void + (*free)(void *), void *ptr)</TT></P> +<DIV class="indent">Given a pointer<I> ptr</I> to some C data, and the + two garbage collection routines for this data (<I>mark</I> and<I> free</I> +), return a <TT>VALUE</TT> for the Ruby object.</DIV> +<P><TT>VALUE Data_Make_Struct(VALUE class,<I> c-type</I>, void + (*mark)(void *), void (*free)(void *),<I> c-type</I> *ptr)</TT></P> +<DIV class="indent">Allocates a new instance of a C data type<I> c-type</I> +, assigns it to the pointer<I> ptr</I>, then wraps that pointer with <TT> +Data_Wrap_Struct()</TT> as above.</DIV> +<P><TT>Data_Get_Struct(VALUE obj,<I> c-type</I>,<I> c-type</I> *ptr)</TT> +</P> +<DIV class="indent">Retrieves the original C pointer of type<I> c-type</I> + from the data object<I> obj</I> and assigns that pointer to<I> ptr</I>.</DIV> +<H3><A name="Ruby_nn52"></A>32.7.13 Example: STL Vector to Ruby Array</H3> +<P>Another use for macros and type maps is to create a Ruby array from a + STL vector of pointers. In essence, copy of all the pointers in the + vector into a Ruby array. The use of the macro is to make the typemap + so generic that any vector with pointers can use the type map. The + following is an example of how to construct this type of macro/typemap + and should give insight into constructing similar typemaps for other + STL structures:</P> +<DIV class="code"> +<PRE>%define PTR_VECTOR_TO_RUBY_ARRAY(vectorclassname, classname) +<BR>%typemap(out) vectorclassname &, const vectorclassname & { +<BR> VALUE arr = rb_ary_new2($1->size()); +<BR> vectorclassname::iterator i = $1->begin(), iend = $1->end(); +<BR> for ( ; i!=iend; i++ ) +<BR> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i)); +<BR> $result = arr; +<BR>} +<BR>%typemap(out) vectorclassname, const vectorclassname { +<BR> VALUE arr = rb_ary_new2($1.size()); +<BR> vectorclassname::iterator i = $1.begin(), iend = $1.end(); +<BR> for ( ; i!=iend; i++ ) +<BR> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i)); +<BR> $result = arr; +<BR>} +<BR>%enddef +<BR></PRE> +</DIV> +<P> Note, that the "<TT>c ## classname.klass"</TT> is used in the + preprocessor step to determine the actual object from the class name.</P> +<P>To use the macro with a class Foo, the following is used:</P> +<DIV class="code"> +<PRE>PTR_VECTOR_TO_RUBY_ARRAY(vector<foo *="">, Foo) +<BR></PRE> +</DIV> +<P> It is also possible to create a STL vector of Ruby objects:</P> +<DIV class="code"> +<PRE>%define RUBY_ARRAY_TO_PTR_VECTOR(vectorclassname, classname) +<BR>%typemap(in) vectorclassname &, const vectorclassname & { +<BR> Check_Type($input, T_ARRAY); +<BR> vectorclassname *vec = new vectorclassname; +<BR> int len = RARRAY($input)->len; +<BR> for (int i=0; i!=len; i++) { +<BR> VALUE inst = rb_ary_entry($input, i); +<BR> //The following _should_ work but doesn't on HPUX +<BR> // Check_Type(inst, T_DATA); +<BR> classname *element = NULL; +<BR> Data_Get_Struct(inst, classname, element); +<BR> vec->push_back(element); +<BR> } +<BR> $1 = vec; +<BR>} +<BR> +<BR>%typemap(freearg) vectorclassname &, const vectorclassname & { +<BR> delete $1; +<BR>} +<BR>%enddef +<BR></PRE> +</DIV> +<P> It is also possible to create a Ruby array from a vector of static + data types:</P> +<DIV class="code"> +<PRE>%define VECTOR_TO_RUBY_ARRAY(vectorclassname, classname) +<BR>%typemap(out) vectorclassname &, const vectorclassname & { +<BR> VALUE arr = rb_ary_new2($1->size()); +<BR> vectorclassname::iterator i = $1->begin(), iend = $1->end(); +<BR> for ( ; i!=iend; i++ ) +<BR> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i))); +<BR> $result = arr; +<BR>} +<BR>%typemap(out) vectorclassname, const vectorclassname { +<BR> VALUE arr = rb_ary_new2($1.size()); +<BR> vectorclassname::iterator i = $1.begin(), iend = $1.end(); +<BR> for ( ; i!=iend; i++ ) +<BR> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i))); +<BR> $result = arr; +<BR>} +<BR>%enddef +<BR></PRE> +</DIV> +<BR> Note that this is mostly an example of typemaps. If you want to use + the STL with ruby, you are advised to use the standard swig STL + library, which does much more than this. Refer to the section called + the<A href="#Ruby_nn23_1"> C++ Standard Template Library</A>. +<BR> +<H2><A name="Ruby_nn65"></A>32.8 Docstring Features</H2> +<P> Using ri and rdoc web pages in Ruby libraries is a common practice. + Given the way that SWIG generates the extensions by default, your users + will normally not get any documentation for it, even if they run 'rdoc' + on the resulting .c or .cxx file.</P> +<P>The features described in this section make it easy for you to add + rdoc strings to your modules, functions and methods that can then be + read by Ruby's rdoc tool to generate html web pages, ri documentation, + Windows chm file and an .xml description.</P> +<P>rdoc can then be run from a console or shell window on a swig + generated file. </P> +<P>For example, to generate html web pages from a C++ file, you'd do: </P> +<DIV class="code shell"> +<!--span style="font-family: monospace; font-weight: bold;"--> + $ rdoc -E cxx=c -f html file_wrap.cxx</DIV> +<P>To generate ri documentation from a c wrap file, you could do:</P> +<DIV class="code shell"> +<!--span style="font-family: monospace; font-weight: bold;"--> +$ rdoc -r file_wrap.c</DIV> +<H3><A name="Ruby_nn66"></A>32.8.1 Module docstring</H3> +<P> Ruby allows a docstring at the beginning of the file before any + other statements, and it is typically used to give a general + description of the entire module. SWIG supports this by setting an + option of the <TT>%module</TT> directive. For example:</P> +<DIV class="code"> +<PRE>%module(docstring="This is the example module's docstring") example +<BR></PRE> +</DIV> +<P> When you have more than just a line or so then you can retain the + easy readability of the <TT>%module</TT> directive by using a macro. + For example:</P> +<DIV class="code"> +<PRE>%define DOCSTRING +<BR>"The `XmlResource` class allows program resources defining menus, +<BR>layout of controls on a panel, etc. to be loaded from an XML file." +<BR>%enddef +<BR> +<BR>%module(docstring=DOCSTRING) xrc +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn67"></A>32.8.2 %feature("autodoc")</H3> +<P>Since SWIG does know everything about the function it wraps, it is + possible to generate an rdoc containing the parameter types, names and + default values. Since Ruby ships with one of the best documentation + systems of any language, it makes sense to take advantage of it.</P> +<P>SWIG's Ruby module provides support for the "autodoc" feature, which + when attached to a node in the parse tree will cause an rdoc comment to + be generated in the wrapper file that includes the name of the + function, parameter names, default values if any, and return type if + any. There are also several options for autodoc controlled by the value + given to the feature, described below.</P> +<H4><A name="Ruby_nn68"></A>32.8.2.1 %feature("autodoc", "0")</H4> +<P> When the "0" option is given then the types of the parameters will<EM> + not</EM> be included in the autodoc string. For example, given this + function prototype:</P> +<DIV class="code"> +<PRE>%feature("autodoc", "0"); +<BR>bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL); +<BR></PRE> +</DIV> +<P> Then Ruby code like this will be generated:</P> +<DIV class="targetlang"> +<PRE>function_name(x, y, foo=nil, bar=nil) -> bool +<BR> ... +<BR></PRE> +</DIV> +<H4><A name="Ruby_autodoc1"></A>32.8.2.2 %feature("autodoc", "1")</H4> +<P> When the "1" option is used then the parameter types<EM> will</EM> + be used in the rdoc string. In addition, an attempt is made to simplify + the type name such that it makes more sense to the Ruby user. Pointer, + reference and const info is removed, <TT>%rename</TT>'s are evaluated, + etc. (This is not always successful, but works most of the time. See + the next section for what to do when it doesn't.) Given the example + above, then turning on the parameter types with the "1" option will + result in rdoc code like this:</P> +<DIV class="targetlang"> +<PRE>function_name(int x, int y, Foo foo=nil, Bar bar=nil) -> bool +<BR> ... +<BR></PRE> +</DIV> +<H4><A name="Ruby_autodoc2"></A>32.8.2.3 %feature("autodoc", "2")</H4> +<P> When the "2" option is used then the parameter types will not be + used in the rdoc string. However, they will be listed in full after the + function. Given the example above, then turning on the parameter types + with the "2" option will result in Ruby code like this:</P> +<H4><A name="Ruby_feature_autodoc3"></A>32.8.2.4 %feature("autodoc", + "3")</H4> +<P> When the "3" option is used then the function will be documented + using a combination of "1" and "2" above. Given the example above, + then turning on the parameter types with the "2" option will result in + Ruby code like this:</P> +<DIV class="targetlang"> +<PRE>function_name(int x, int y, Foo foo=nil, Bar bar=nil) -> bool +<BR> +<BR>Parameters: +<BR> x - int +<BR> y - int +<BR> foo - Foo +<BR> bar - Bar +<BR></PRE> +</DIV> +<H4><A name="Ruby_nn70"></A>32.8.2.5 %feature("autodoc", "docstring")</H4> +<P> Finally, there are times when the automatically generated autodoc + string will make no sense for a Ruby programmer, particularly when a + typemap is involved. So if you give an explicit value for the autodoc + feature then that string will be used in place of the automatically + generated string. For example:</P> +<DIV class="code"> +<PRE>%feature("autodoc", "GetPosition() -> (x, y)") GetPosition; +<BR>void GetPosition(int* OUTPUT, int* OUTPUT); +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn71"></A>32.8.3 %feature("docstring")</H3> +<P> In addition to the autodoc strings described above, you can also + attach any arbitrary descriptive text to a node in the parse tree with + the "docstring" feature. When the proxy module is generated then any + docstring associated with classes, function or methods are output. If + an item already has an autodoc string then it is combined with the + docstring and they are output together.</P> +<H2><A name="Ruby_nn53"></A>32.9 Advanced Topics</H2> +<H3><A name="Ruby_nn54"></A>32.9.1 Operator overloading</H3> +<P> SWIG allows operator overloading with, by using the <TT>%extend</TT> + or <TT>%rename</TT> commands in SWIG and the following operator names + (derived from Python):</P> +<DIV class="code diagram"> +<TABLE border="1" cellpadding="2" cellspacing="2" style="width: 100%; font-family: monospace;" +summary="operator names"><TBODY></TBODY> +<TR><TD><B> General</B></TD></TR> +<TR><TD>__repr__</TD><TD> inspect</TD></TR> +<TR><TD>__str__</TD><TD> to_s</TD></TR> +<TR><TD>__cmp__</TD><TD> <=></TD></TR> +<TR><TD>__hash__</TD><TD> hash</TD></TR> +<TR><TD>__nonzero__</TD><TD> nonzero?</TD></TR> +<TR><TD></TD></TR> +<TR><TD><B> Callable</B></TD></TR> +<TR><TD>__call__</TD><TD> call</TD></TR> +<TR><TD></TD></TR> +<TR><TD><B> Collection</B></TD></TR> +<TR><TD>__len__</TD><TD> length</TD></TR> +<TR><TD>__getitem__</TD><TD> []</TD></TR> +<TR><TD>__setitem__</TD><TD> []=</TD></TR> +<TR><TD></TD></TR> +<TR><TD><B> Numeric</B></TD></TR> +<TR><TD>__add__</TD><TD> +</TD></TR> +<TR><TD>__sub__</TD><TD> -</TD><TD></TD></TR> +<TR><TD>__mul__</TD><TD> *</TD></TR> +<TR><TD>__div__</TD><TD> /</TD></TR> +<TR><TD>__mod__</TD><TD> %</TD></TR> +<TR><TD>__divmod__</TD><TD> divmod</TD></TR> +<TR><TD>__pow__</TD><TD> **</TD></TR> +<TR><TD>__lshift__</TD><TD> <<</TD></TR> +<TR><TD>__rshift__</TD><TD> >></TD></TR> +<TR><TD>__and__</TD><TD> &</TD></TR> +<TR><TD>__xor__</TD><TD> ^</TD></TR> +<TR><TD>__or__</TD><TD> |</TD></TR> +<TR><TD>__neg__</TD><TD> -@</TD><TD></TD></TR> +<TR><TD>__pos__</TD><TD> +@</TD></TR> +<TR><TD>__abs__</TD><TD> abs</TD></TR> +<TR><TD>__invert__</TD><TD> ~</TD></TR> +<TR><TD>__int__</TD><TD> to_i</TD></TR> +<TR><TD>__float__</TD><TD> to_f</TD></TR> +<TR><TD>__coerce__</TD><TD> coerce</TD></TR> +<TR><TD></TD></TR> +<TR><TD><B>Additions in 1.3.13</B></TD></TR> +<TR><TD>__lt__</TD><TD> <</TD></TR> +<TR><TD>__le__</TD><TD> <=</TD></TR> +<TR><TD>__eq__</TD><TD> ==</TD></TR> +<TR><TD>__gt__</TD><TD> ></TD></TR> +<TR><TD>__ge__</TD><TD> >=</TD></TR> +</TABLE> +</DIV> +<P> Note that although SWIG supports the <TT>__eq__</TT> magic method + name for defining an equivalence operator, there is no separate method + for handling<I> inequality</I> since Ruby parses the expression<I> a != + b</I> as<I> !(a == b)</I>.</P> +<H3><A name="Ruby_nn55"></A>32.9.2 Creating Multi-Module Packages</H3> +<P> The chapter on <A href="Modules.html">Working with Modules</A> + discusses the basics of creating multi-module extensions with SWIG, and + in particular the considerations for sharing runtime type information + among the different modules.</P> +<P>As an example, consider one module's interface file (<TT>shape.i</TT> +) that defines our base class:</P> +<DIV class="code"> +<PRE>%module shape +<BR> +<BR>%{ +<BR>#include "Shape.h" +<BR>%} +<BR> +<BR>class Shape { +<BR>protected: +<BR> double xpos; +<BR> double ypos; +<BR>protected: +<BR> Shape(double x, double y); +<BR>public: +<BR> double getX() const; +<BR> double getY() const; +<BR>}; +<BR></PRE> +</DIV> +<P> We also have a separate interface file (<TT>circle.i</TT>) that + defines a derived class:</P> +<DIV class="code"> +<PRE>%module circle +<BR> +<BR>%{ +<BR>#include "Shape.h" +<BR>#include "Circle.h" +<BR>%} +<BR> +<BR>// Import the base class definition from Shape module +<BR>%import shape.i +<BR> +<BR>class Circle : public Shape { +<BR>protected: +<BR> double radius; +<BR>public: +<BR> Circle(double x, double y, double r); +<BR> double getRadius() const; +<BR>}; +<BR></PRE> +</DIV> +<P> We'll start by building the<B> Shape</B> extension module:</P> +<DIV class="code shell"> +<PRE>$ <B>swig -c++ -ruby shape.i</B> +</PRE> +</DIV> +<P> SWIG generates a wrapper file named <TT>shape_wrap.cxx</TT>. To + compile this into a dynamically loadable extension for Ruby, prepare an + <TT>extconf.rb</TT> script using this template:</P> +<DIV class="code targetlang"> +<PRE>require 'mkmf' +<BR> +<BR># Since the SWIG runtime support library for Ruby +<BR># depends on the Ruby library, make sure it's in the list +<BR># of libraries. +<BR>$libs = append_library($libs, Config::CONFIG['RUBY_INSTALL_NAME']) +<BR> +<BR># Create the makefile +<BR>create_makefile('shape') +<BR></PRE> +</DIV> +<P> Run this script to create a <TT>Makefile</TT> and then type <TT>make</TT> + to build the shared library:</P> +<DIV class="code targetlang"> +<PRE>$ <B>ruby extconf.rb</B> +<BR>creating Makefile +<BR>$ <B>make</B> +<BR>g++ -fPIC -g -O2 -I. -I/usr/local/lib/ruby/1.7/i686-linux \ +<BR>-I. -c shape_wrap.cxx +<BR>gcc -shared -L/usr/local/lib -o shape.so shape_wrap.o -L. \ +<BR>-lruby -lruby -lc +<BR></PRE> +</DIV> +<P> Note that depending on your installation, the outputs may be + slightly different; these outputs are those for a Linux-based + development environment. The end result should be a shared library + (here, <TT>shape.so</TT>) containing the extension module code. Now + repeat this process in a separate directory for the<B> Circle</B> + module:</P> +<OL> +<LI> Run SWIG to generate the wrapper code (<TT>circle_wrap.cxx</TT>);</LI> +<LI> Write an <TT>extconf.rb</TT> script that your end-users can use to + create a platform-specific <TT>Makefile</TT> for the extension;</LI> +<LI> Build the shared library for this extension by typing <TT>make</TT> +.</LI> +</OL> +<P> Once you've built both of these extension modules, you can test them + interactively in IRB to confirm that the <TT>Shape</TT> and <TT>Circle</TT> + modules are properly loaded and initialized:</P> +<DIV class="code targetlang"> +<PRE>$ <B>irb</B> +<BR>irb(main):001:0> <B>require 'shape'</B> +<BR>true +<BR>irb(main):002:0> <B>require 'circle'</B> +<BR>true +<BR>irb(main):003:0> <B>c = Circle::Circle.new(5, 5, 20)</B> +<BR>#<Circle::Circle:0xa097208> +<BR>irb(main):004:0> <B>c.kind_of? Shape::Shape</B> +<BR>true +<BR>irb(main):005:0> <B>c.getX()</B> +<BR>5.0 +<BR></PRE> +</DIV> +<H3><A name="Ruby_nn56"></A>32.9.3 Specifying Mixin Modules</H3> +<P> The Ruby language doesn't support multiple inheritance, but it does + allow you to mix one or more modules into a class using Ruby's <TT> +include</TT> method. For example, if you have a Ruby class that defines + an<EM> each</EM> instance method, e.g.</P> +<DIV class="code targetlang"> +<PRE>class Set +<BR> def initialize +<BR> @members = [] +<BR> end +<BR> +<BR> def each +<BR> @members.each { |m| yield m } +<BR> end +<BR>end +<BR></PRE> +</DIV> +<P> then you can mix-in Ruby's <TT>Enumerable</TT> module to easily add + a lot of functionality to your class:</P> +<DIV class="code targetlang"> +<PRE>class Set +<BR> <B>include Enumerable</B> +<BR>def initialize +<BR>@members = [] +<BR>end +<BR>def each +<BR>@members.each { |m| yield m } +<BR>end +<BR>end +<BR></PRE> +</DIV> +<P> To get the same benefit for your SWIG-wrapped classes, you can use + the <TT>%mixin</TT> directive to specify the names of one or more + modules that should be mixed-in to a class. For the above example, the + SWIG interface specification might look like this:</P> +<DIV class="code"> +<PRE>%mixin Set "Enumerable"; +<BR> +<BR>class Set { +<BR>public: +<BR> // Constructor +<BR> Set(); +<BR> +<BR> // Iterates through set members +<BR> void each(); +<BR>}; +<BR></PRE> +</DIV> +<P> Multiple modules can be mixed into a class by providing a + comma-separated list of module names to the <TT>%mixin</TT> directive, + e.g.</P> +<DIV class="code"> +<PRE>%mixin Set "Fee,Fi,Fo,Fum";</PRE> +</DIV> +<P> Note that the <TT>%mixin</TT> directive is implemented using SWIG's + "features" mechanism and so the same name matching rules used for other + kinds of features apply (see the chapter on <A href="#Customization"> +"Customization Features"</A>) for more details).</P> +<H2><A name="Ruby_nn57"></A>32.10 Memory Management</H2> +<P>One of the most common issues in generating SWIG bindings for Ruby is + proper memory management. The key to proper memory management is + clearly defining whether a wrapper Ruby object owns the underlying C + struct or C++ class. There are two possibilities:</P> +<UL> +<LI> The Ruby object is responsible for freeing the C struct or C++ + object</LI> +<LI> The Ruby object should not free the C struct or C++ object because + it will be freed by the underlying C or C++ code</LI> +</UL> +<P>To complicate matters, object ownership may transfer from Ruby to C++ + (or vice versa) depending on what function or methods are invoked. + Clearly, developing a SWIG wrapper requires a thorough understanding of + how the underlying library manages memory.</P> +<H3><A name="Ruby_nn58"></A>32.10.1 Mark and Sweep Garbage Collector</H3> +<P>Ruby uses a mark and sweep garbage collector. When the garbage + collector runs, it finds all the "root" objects, including local + variables, global variables, global constants, hardware registers and + the C stack. For each root object, the garbage collector sets its mark + flag to true and calls <TT>rb_gc_mark</TT> on the object. The job of <TT> +rb_gc_mark</TT> is to recursively mark all the objects that a Ruby + object has a reference to (ignoring those objects that have already + been marked). Those objects, in turn, may reference other objects. This + process will continue until all active objects have been "marked." + After the mark phase comes the sweep phase. In the sweep phase, all + objects that have not been marked will be garbage collected. For more + information about the Ruby garbage collector please refer to <A href="http://rubygarden.org/ruby/ruby?GCAndExtensions"> + +<!--span style="text-decoration: underline;"--> + http://rubygarden.org/ruby/ruby?GCAndExtensions</A>.</P> +<P>The Ruby C/API provides extension developers two hooks into the + garbage collector - a "mark" function and a "sweep" function. By + default these functions are set to NULL.</P> +<P>If a C struct or C++ class references any other Ruby objects, then it + must provide a "mark" function. The "mark" function should identify any + referenced Ruby objects by calling the rb_gc_mark function for each + one. Unsurprisingly, this function will be called by the Ruby garbage + during the "mark" phase.</P> +<P>During the sweep phase, Ruby destroys any unused objects. If any + memory has been allocated in creating the underlying C struct or C++ + struct, then a "free" function must be defined that deallocates this + memory.</P> +<H3><A name="Ruby_nn59"></A>32.10.2 Object Ownership</H3> +<P>As described above, memory management depends on clearly defining who + is responsible for freeing the underlying C struct or C++ class. If the + Ruby object is responsible for freeing the C++ object, then a "free" + function must be registered for the object. If the Ruby object is not + responsible for freeing the underlying memory, then a "free" function + must not be registered for the object.</P> +<P>For the most part, SWIG takes care of memory management issues. The + rules it uses are:</P> +<UL> +<LI> When calling a C++ object's constructor from Ruby, SWIG will assign + a "free" function thereby making the Ruby object responsible for + freeing the C++ object</LI> +<LI> When calling a C++ member function that returns a pointer, SWIG + will not assign a "free" function thereby making the underlying library + responsible for freeing the object.</LI> +</UL> +<P>To make this clearer, let's look at an example. Assume we have a Foo + and a Bar class.</P> +<DIV class="code"> +<PRE>/* File "RubyOwernshipExample.h" */ +<BR> +<BR>class Foo +<BR>{ +<BR>public: +<BR> Foo() {} +<BR> ~Foo() {} +<BR>}; +<BR> +<BR>class Bar +<BR>{ +<BR> Foo *foo_; +<BR>public: +<BR> Bar(): foo_(new Foo) {} +<BR> ~Bar() { delete foo_; } +<BR> Foo* get_foo() { return foo_; } +<BR> Foo* get_new_foo() { return new Foo; } +<BR> void set_foo(Foo *foo) { delete foo_; foo_ = foo; } +<BR>}; +<BR> +<BR></PRE> +</DIV> +<P>First, consider this Ruby code:</P> +<DIV class="code targetlang"> +<PRE>foo = Foo.new</PRE> +</DIV> +<P>In this case, the Ruby code calls the underlying <TT>Foo</TT> C++ + constructor, thus creating a new <TT>foo</TT> object. By default, SWIG + will assign the new Ruby object a "free" function. When the Ruby object + is garbage collected, the "free" function will be called. It in turn + will call <TT>Foo's</TT> destructor.</P> +<P>Next, consider this code:</P> +<DIV class="code targetlang"> +<PRE>bar = Bar.new +<BR>foo = bar.get_foo()</PRE> +</DIV> +<P>In this case, the Ruby code calls a C++ member function, <TT>get_foo</TT> +. By default, SWIG will not assign the Ruby object a "free" function. + Thus, when the Ruby object is garbage collected the underlying C++ <TT> +foo</TT> object is not affected.</P> +<P>Unfortunately, the real world is not as simple as the examples above. + For example:</P> +<DIV class="code targetlang"> +<PRE>bar = Bar.new +<BR>foo = bar.get_new_foo()</PRE> +</DIV> +<P>In this case, the default SWIG behavior for calling member functions + is incorrect. The Ruby object should assume ownership of the returned + object. This can be done by using the %newobject directive. See <A href="#ownership"> + Object ownership and %newobject</A> for more information.</P> +<P>The SWIG default mappings are also incorrect in this case:</P> +<DIV class="code targetlang"> +<PRE>foo = Foo.new +<BR>bar = Bar.new +<BR>bar.set_foo(foo)</PRE> +</DIV> +<P>Without modification, this code will cause a segmentation fault. When + the Ruby <TT>foo</TT> object goes out of scope, it will free the + underlying C++ <TT>foo</TT> object. However, when the Ruby bar object + goes out of scope, it will call the C++ bar destructor which will also + free the C++ <TT>foo</TT> object. The problem is that object ownership + is transferred from the Ruby object to the C++ object when the <TT> +set_foo</TT> method is called. This can be done by using the special + DISOWN type map, which was added to the Ruby bindings in SWIG-1.3.26.</P> +<P>Thus, a correct SWIG interface file correct mapping for these classes + is:</P> +<DIV class="code"> +<PRE>/* File RubyOwnershipExample.i */ +<BR> +<BR>%module RubyOwnershipExample +<BR> +<BR>%{ +<BR>#include "RubyOwnershipExample.h" +<BR>%} +<BR> +<BR>class Foo +<BR>{ +<BR>public: +<BR> Foo(); +<BR> ~Foo(); +<BR>}; +<BR> +<BR>class Bar +<BR>{ +<BR> Foo *foo_; +<BR>public: +<BR> Bar(); +<BR> ~Bar(); +<BR> Foo* get_foo(); +<BR> +<BR> +<!--span style="font-weight: bold;"--> + %newobject get_new_foo; +<BR> Foo* get_new_foo(); +<BR> +<BR> +<!--span style="font-weight: bold;"--> + %apply SWIGTYPE *DISOWN {Foo *foo}; +<BR> void set_foo(Foo *foo); +<BR> +<!--span style="font-weight: bold;"--> + %clear Foo *foo; +<BR>}; +<BR> +<BR></PRE> +</DIV> +<BR> +<P> This code can be seen in swig/examples/ruby/tracking.</P> +<BR> +<H3><A name="Ruby_nn60"></A>32.10.3 Object Tracking</H3> +<P>The remaining parts of this section will use the class library shown + below to illustrate different memory management techniques. The class + library models a zoo and the animals it contains.</P> +<DIV class="code"> +<PRE>%module zoo +<BR> +<BR>%{ +<BR>#include <string> +<BR>#include <vector> +<BR> +<BR>#include "zoo.h" +<BR>%} +<BR> +<BR>class Animal +<BR>{ +<BR>private: +<BR> typedef std::vector<Animal*> AnimalsType; +<BR> typedef AnimalsType::iterator IterType; +<BR>protected: +<BR> AnimalsType animals; +<BR>protected: +<BR> std::string name_; +<BR>public: +<BR> // Construct an animal with this name +<BR> Animal(const char* name) : name_(name) {} +<BR> +<BR> // Return the animal's name +<BR> const char* get_name() const { return name.c_str(); } +<BR>}; +<BR> +<BR>class Zoo +<BR>{ +<BR>protected: +<BR> std::vector<animal *=""> animals; +<BR> +<BR>public: +<BR> // Construct an empty zoo +<BR> Zoo() {} +<BR> +<BR> /* Create a new animal. */ +<BR> static Animal* Zoo::create_animal(const char* name) +<BR> { +<BR> return new Animal(name); +<BR> } +<BR> +<BR> // Add a new animal to the zoo +<BR> void add_animal(Animal* animal) { +<BR> animals.push_back(animal); +<BR> } +<BR> +<BR> Animal* remove_animal(size_t i) { +<BR> Animal* result = this->animals[i]; +<BR> IterType iter = this->animals.begin(); +<BR> std::advance(iter, i); +<BR> this->animals.erase(iter); +<BR> +<BR> return result; +<BR> } +<BR> +<BR> // Return the number of animals in the zoo +<BR> size_t get_num_animals() const { +<BR> return animals.size(); +<BR> } +<BR> +<BR> // Return a pointer to the ith animal +<BR> Animal* get_animal(size_t i) const { +<BR> return animals[i]; +<BR> } +<BR>}; +<BR> +<BR></PRE> +</DIV> +<P>Let's say you SWIG this code and then run IRB: +<BR></P> +<DIV class="code targetlang"> +<PRE>$ +<!--span style="font-weight: bold;"--> +irb +<BR>irb(main):001:0> +<!--span style="font-weight: bold;"--> +require 'example' +<BR>=> true +<BR> +<BR>irb(main):002:0> +<!--span style="font-weight: bold;"--> +tiger1 = Example::Animal.new("tiger1") +<BR>=> #<Example::Animal:0x2be3820> +<BR> +<BR>irb(main):004:0> +<!--span style="font-weight: bold;"--> +tiger1.get_name() +<BR>=> "tiger1" +<BR> +<BR>irb(main):003:0> +<!--span style="font-weight: bold;"--> +zoo = Example::Zoo.new() +<BR>=> #<Example::Zoo:0x2be0a60> +<BR> +<BR>irb(main):006:0> +<!--span style="font-weight: bold;"--> +zoo.add_animal(tiger) +<BR>=> nil +<BR> +<BR>irb(main):007:0> +<!--span style="font-weight: bold;"--> +zoo.get_num_animals() +<BR>=> 1 +<BR> +<BR>irb(main):007:0> +<!--span style="font-weight: bold;"--> +tiger2 = zoo.remove_animal(0) +<BR>=> #<Example::Animal:0x2bd4a18> +<BR> +<BR>irb(main):008:0> +<!--span style="font-weight: bold;"--> +tiger2.get_name() +<BR>=> "tiger1" +<BR> +<BR>irb(main):009:0> +<!--span style="font-weight: bold;"--> +tiger1.equal?(tiger2) +<BR>=> false +<BR> +<BR></PRE> +</DIV> +<P>Pay particular attention to the code <TT>tiger1.equal?(tiger2)</TT>. + Note that the two Ruby objects are not the same - but they reference + the same underlying C++ object. This can cause problems. For example: +<BR></P> +<DIV class="code targetlang"> +<PRE>irb(main):010:0> +<!--span style="font-weight: bold;"--> +tiger1 = nil +<BR>=> nil +<BR> +<BR>irb(main):011:0> +<!--span style="font-weight: bold;"--> +GC.start +<BR>=> nil +<BR> +<BR>irb(main):012:0> +<!--span style="font-weight: bold;"--> +tiger2.get_name() +<BR>(irb):12: [BUG] Segmentation fault +<BR> +<BR></PRE> +</DIV> +<P>After the the garbage collector runs, as a result of our call to <TT> +GC.start</TT>, calling<TT>tiger2.get_name()</TT> causes a segmentation + fault. The problem is that when <TT>tiger1</TT> is garbage collected, + it frees the underlying C++ object. Thus, when <TT>tiger2</TT> calls + the <TT>get_name()</TT> method it invokes it on a destroyed object.</P> +<P>This problem can be avoided if SWIG enforces a one-to-one mapping + between Ruby objects and C++ classes. This can be done via the use of + the <TT>%trackobjects</TT> functionality available in SWIG-1.3.26. and + later.</P> +<P>When the <TT>%trackobjects</TT> is turned on, SWIG automatically + keeps track of mappings between C++ objects and Ruby objects. Note that + enabling object tracking causes a slight performance degradation. Test + results show this degradation to be about 3% to 5% when creating and + destroying 100,000 animals in a row.</P> +<P>Since <TT>%trackobjects</TT> is implemented as a <TT>%feature</TT>, + it uses the same name matching rules as other kinds of features (see + the chapter on <A href="#Customization"> "Customization Features"</A>) + . Thus it can be applied on a class-by-class basis if needed. To fix + the example above:</P> +<BR><DIV class="code"> +<PRE>%module example +<BR> +<BR>%{ +<BR>#include "example.h" +<BR>%} +<BR> +<BR> +<!--span style="font-weight: bold;"--> +/* Tell SWIG that create_animal creates a new object */ +<BR> +<!--span style="font-weight: bold;"--> +%newobject Zoo::create_animal; +<BR> +<BR> +<!--span style="font-weight: bold;"--> +/* Tell SWIG to keep track of mappings between C/C++ structs/classes. */ +<BR style="font-weight: bold;"> +<!--span style="font-weight: bold;"--> +%trackobjects; +<BR> +<BR>%include "example.h"</PRE> +</DIV> +<P>When this code runs we see: +<BR> +<BR></P> +<DIV class="code targetlang"> +<PRE>$ +<!--span style="font-weight: bold;"--> +irb +<BR>irb(main):001:0> +<!--span style="font-weight: bold;"--> +require 'example' +<BR>=> true +<BR> +<BR>irb(main):002:0> +<!--span style="font-weight: bold;"--> +tiger1 = Example::Animal.new("tiger1") +<BR>=> #<Example::Animal:0x2be37d8> +<BR> +<BR>irb(main):003:0> +<!--span style="font-weight: bold;"--> +zoo = Example::Zoo.new() +<BR>=> #<Example::Zoo:0x2be0a18> +<BR> +<BR>irb(main):004:0> +<!--span style="font-weight: bold;"--> +zoo.add_animal(tiger1) +<BR>=> nil +<BR> +<BR>irb(main):006:0> +<!--span style="font-weight: bold;"--> +tiger2 = zoo.remove_animal(0) +<BR>=> #<Example::Animal:0x2be37d8> +<BR> +<BR>irb(main):007:0> +<!--span style="font-weight: bold;"--> +tiger1.equal?(tiger2) +<BR>=> true +<BR> +<BR>irb(main):008:0> +<!--span style="font-weight: bold;"--> +tiger1 = nil +<BR>=> nil +<BR> +<BR>irb(main):009:0> +<!--span style="font-weight: bold;"--> +GC.start +<BR>=> nil +<BR> +<BR>irb(main):010:0> +<!--span style="font-weight: bold;"--> +tiger.get_name() +<BR>=> "tiger1" +<BR>irb(main):011:0> +<BR> +<BR></PRE> +</DIV> +<P>For those who are interested, object tracking is implemented by + storing Ruby objects in a hash table and keying them on C++ pointers. + The underlying API is: +<BR></P> +<DIV class="code"> +<PRE>static void SWIG_RubyAddTracking(void* ptr, VALUE object); +<BR>static VALUE SWIG_RubyInstanceFor(void* ptr) ; +<BR>static void SWIG_RubyRemoveTracking(void* ptr); +<BR>static void SWIG_RubyUnlinkObjects(void* ptr);</PRE> +</DIV> +<P>When an object is created, SWIG will automatically call the <TT> +SWIG_RubyAddTracking</TT> method. Similarly, when an object is deleted, + SWIG will call the <TT>SWIG_RubyRemoveTracking</TT>. When an object is + returned to Ruby from C++, SWIG will use the <TT>SWIG_RubyInstanceFor</TT> + method to ensure a one-to-one mapping from Ruby to C++ objects. Last, + the <TT>RubyUnlinkObjects</TT> method unlinks a Ruby object from its + underlying C++ object.</P> +<P>In general, you will only need to use the <TT>SWIG_RubyInstanceFor</TT> +, which is required for implementing mark functions as shown below. + However, if you implement your own free functions (see below) you may + also have to call the <TT>SWIG_RubyRemoveTracking</TT> and <TT> +RubyUnlinkObjects</TT> methods.</P> +<H3><A name="Ruby_nn61"></A>32.10.4 Mark Functions</H3> +<P>With a bit more testing, we see that our class library still has + problems. For example: +<BR></P> +<DIV class="targetlang"> +<PRE>$ <B>irb</B> +<BR>irb(main):001:0> +<!--span style="font-weight: bold;"--> +require 'example' +<BR>=> true +<BR> +<BR>irb(main):002:0> tiger1 = +<!--span style="font-weight: bold;"--> +Example::Animal.new("tiger1") +<BR>=> #<Example::Animal:0x2bea6a8> +<BR> +<BR>irb(main):003:0> zoo = +<!--span style="font-weight: bold;"--> +Example::Zoo.new() +<BR>=> #<Example::Zoo:0x2be7960> +<BR> +<BR>irb(main):004:0> +<!--span style="font-weight: bold;"--> +zoo.add_animal(tiger1) +<BR>=> nil +<BR> +<BR>irb(main):007:0> +<!--span style="font-weight: bold;"--> +tiger1 = nil +<BR>=> nil +<BR> +<BR>irb(main):007:0> +<!--span style="font-weight: bold;"--> +GC.start +<BR>=> nil +<BR> +<BR>irb(main):005:0> +<!--span style="font-weight: bold;"--> +tiger2 = zoo.get_animal(0) +<BR>(irb):12: [BUG] Segmentation fault</PRE> +</DIV> +<P>The problem is that Ruby does not know that the <TT>zoo</TT> object + contains a reference to a Ruby object. Thus, when Ruby garbage collects +<!--span style="font-family: monospace;"--> + tiger1 it frees the underlying C++ object.</P> +<P>This can be fixed by implementing a <TT>mark</TT> function as + described above in the <A href="#Ruby_nn52">Mark and Sweep Garbage + Collector</A> section. You can specify a mark function by using the <TT> +%markfunc</TT> directive. Since the <TT>%markfunc</TT> directive is + implemented using SWIG's' "features" mechanism it uses the same name + matching rules as other kinds of features (see the chapter on <A href="#Customization"> +"Customization Features"</A> for more details).</P> +<P>A <TT>mark</TT> function takes a single argument, which is a pointer + to the C++ object being marked; it should, in turn, call <TT> +rb_gc_mark()</TT> for any instances that are reachable from the current + object. The mark function for our <TT>Zoo</TT> class should therefore + loop over all of the C++ animal objects in the zoo object, look up + their Ruby object equivalent, and then call <TT>rb_gc_mark()</TT>. One + possible implementation is:</P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>%{ +<BR>#include "example.h" +<BR>%} +<BR> +<BR>/* Keep track of mappings between C/C++ structs/classes +<BR> and Ruby objects so we can implement a mark function. */ +<BR> +<!--span style="font-weight: bold;"--> +%trackobjects; +<BR> +<BR>/* Specify the mark function */ +<BR> +<!--span style="font-weight: bold;"--> +%markfunc Zoo "mark_Zoo"; +<BR> +<BR>%include "example.h" +<BR> +<BR>%header %{ +<BR> +<BR>static void mark_Zoo(void* ptr) { +<BR> Zoo* zoo = (Zoo*) ptr; +<BR> +<BR> /* Loop over each object and tell the garbage collector +<BR> that we are holding a reference to them. */ +<BR> int count = zoo->get_num_animals(); +<BR> +<BR> for(int i = 0; i < count; ++i) { +<BR> Animal* animal = zoo->get_animal(i); +<BR> VALUE object = SWIG_RubyInstanceFor(animal); +<BR> +<BR> if (object != Qnil) { +<BR> rb_gc_mark(object); +<BR> } +<BR> } +<BR>} +<BR>%} +<BR> +<BR></PRE> +</DIV> +<P> Note the <TT>mark</TT> function is dependent on the <TT> +SWIG_RUBY_InstanceFor</TT> method, and thus requires that <TT> +%trackobjects</TT> is enabled. For more information, please refer to the + track_object.i test case in the SWIG test suite.</P> +<P>When this code is compiled we now see:</P> +<DIV class="targetlang"> +<PRE>$ <B>irb +<BR></B>irb(main):002:0> +<!--span style="font-weight: bold;"--> +tiger1=Example::Animal.new("tiger1") +<BR>=> #<Example::Animal:0x2be3bf8> +<BR> +<BR>irb(main):003:0> +<!--span style="font-weight: bold;"--> +Example::Zoo.new() +<BR>=> #<Example::Zoo:0x2be1780> +<BR> +<BR>irb(main):004:0> +<!--span style="font-weight: bold;"--> +zoo = Example::Zoo.new() +<BR>=> #<Example::Zoo:0x2bde9c0> +<BR> +<BR>irb(main):005:0> +<!--span style="font-weight: bold;"--> +zoo.add_animal(tiger1) +<BR>=> nil +<BR> +<BR>irb(main):009:0> +<!--span style="font-weight: bold;"--> +tiger1 = nil +<BR>=> nil +<BR> +<BR>irb(main):010:0> +<!--span style="font-weight: bold;"--> +GC.start +<BR>=> nil +<BR>irb(main):014:0> +<!--span style="font-weight: bold;"--> +tiger2 = zoo.get_animal(0) +<BR>=> #<Example::Animal:0x2be3bf8> +<BR> +<BR>irb(main):015:0> +<!--span style="font-weight: bold;"--> +tiger2.get_name() +<BR>=> "tiger1" +<BR>irb(main):016:0> +<BR> +<BR></PRE> +</DIV> +<BR> +<P>This code can be seen in swig/examples/ruby/mark_function.</P> +<H3><A name="Ruby_nn62"></A>32.10.5 Free Functions</H3> +<P>By default, SWIG creates a "free" function that is called when a Ruby + object is garbage collected. The free function simply calls the C++ + object's destructor.</P> +<P>However, sometimes an appropriate destructor does not exist or + special processing needs to be performed before the destructor is + called. Therefore, SWIG allows you to manually specify a "free" + function via the use of the <TT>%freefunc</TT> directive. The <TT> +%freefunc</TT> directive is implemented using SWIG's' "features" + mechanism and so the same name matching rules used for other kinds of + features apply (see the chapter on <A href="#Customization"> +"Customization Features"</A>) for more details).</P> +<P>IMPORTANT ! - If you define your own free function, then you must + ensure that you call the underlying C++ object's destructor. In + addition, if object tracking is activated for the object's class, you + must also call the <TT>SWIG_RubyRemoveTracking</TT> function (of course + call this before you destroy the C++ object). Note that it is harmless + to call this method if object tracking if off so it is advised to + always call it.</P> +<P>Note there is a subtle interaction between object ownership and free + functions. A custom defined free function will only be called if the + Ruby object owns the underlying C++ object. This also to Ruby objects + which are created, but then transfer ownership to C++ objects via the + use of the <TT>disown</TT> typemap described above.</P> +<P>To show how to use the <TT>%freefunc</TT> directive, let's slightly + change our example. Assume that the zoo object is responsible for + freeing animal that it contains. This means that the +<!--span style="font-family: monospace;"--> + Zoo::add_animal function should be marked with a +<!--span style="font-family: monospace;"--> + DISOWN typemap and the destructor should be updated as below::</P> +<DIV class="code"> +<PRE>Zoo::~Zoo() { +<BR> IterType iter = this->animals.begin(); +<BR> IterType end = this->animals.end(); +<BR> +<BR> for(iter; iter != end; ++iter) { +<BR> Animal* animal = *iter; +<BR> delete animal; +<BR> } +<BR>}</PRE> +</DIV> +<P>When we use these objects in IRB we see:</P> +<DIV class="code targetlang"> +<PRE class="targetlang"> +<!--span style="font-weight: bold;"--> +$irb +<BR>irb(main):002:0> +<!--span style="font-weight: bold;"--> +require 'example' +<BR>=> true +<BR> +<BR>irb(main):003:0> +<!--span style="font-weight: bold;"--> +zoo = Example::Zoo.new() +<BR>=> #<Example::Zoo:0x2be0fe8> +<BR> +<BR>irb(main):005:0> +<!--span style="font-weight: bold;"--> +tiger1 = Example::Animal.new("tiger1") +<BR>=> #<Example::Animal:0x2bda760> +<BR> +<BR>irb(main):006:0> +<!--span style="font-weight: bold;"--> +zoo.add_animal(tiger1) +<BR>=> nil +<BR> +<BR>irb(main):007:0> +<!--span style="font-weight: bold;"--> +zoo = nil +<BR>=> nil +<BR> +<BR>irb(main):008:0> +<!--span style="font-weight: bold;"--> +GC.start +<BR>=> nil +<BR> +<BR>irb(main):009:0> +<!--span style="font-weight: bold;"--> +tiger1.get_name() +<BR>(irb):12: [BUG] Segmentation fault +<BR> +<BR></PRE> +</DIV> +<P>The error happens because the C++ <TT>animal</TT> object is freed + when the <TT>zoo</TT> object is freed. Although this error is + unavoidable, we can at least prevent the segmentation fault. To do this + requires enabling object tracking and implementing a custom free + function that calls the <TT>SWIG_RubyUnlinkObjects</TT> function for + each animal object that is destroyed. The <TT>SWIG_RubyUnlinkObjects</TT> + function notifies SWIG that a Ruby object's underlying C++ object is no + longer valid. Once notified, SWIG will intercept any calls from the + existing Ruby object to the destroyed C++ object and raise an + exception. +<BR></P> +<DIV class="code"> +<PRE>%module example +<BR> +<BR>%{ +<BR>#include "example.h" +<BR>%} +<BR> +<BR>/* Specify that ownership is transferred to the zoo +<BR> when calling add_animal */ +<BR>%apply SWIGTYPE *DISOWN { Animal* animal }; +<BR> +<BR>/* Track objects */ +<BR>%trackobjects; +<BR> +<BR>/* Specify the mark function */ +<BR>%freefunc Zoo "free_Zoo"; +<BR> +<BR>%include "example.h" +<BR> +<BR>%header %{ +<BR> static void free_Zoo(void* ptr) { +<BR> Zoo* zoo = (Zoo*) ptr; +<BR> +<BR> /* Loop over each animal */ +<BR> int count = zoo->get_num_animals(); +<BR> +<BR> for(int i = 0; i < count; ++i) { +<BR> /* Get an animal */ +<BR> Animal* animal = zoo->get_animal(i); +<BR> +<BR> /* Unlink the Ruby object from the C++ object */ +<BR> SWIG_RubyUnlinkObjects(animal); +<BR> +<BR> /* Now remove the tracking for this animal */ +<BR> SWIG_RubyRemoveTracking(animal); +<BR> } +<BR> +<BR> /* Now call SWIG_RubyRemoveTracking for the zoo */ +<BR> SWIG_RubyRemoveTracking(ptr); +<BR> +<BR> /* Now free the zoo which will free the animals it contains */ +<BR> delete zoo; +<BR> } +<BR>%} </PRE> +</DIV> +<P>Now when we use these objects in IRB we see:</P> +<DIV class="code targetlang"> +<PRE> +<!--span style="font-weight: bold;"--> +$irb +<BR>irb(main):002:0> +<!--span style="font-weight: bold;"--> +require 'example' +<BR>=> true +<BR> +<BR>irb(main):003:0> +<!--span style="font-weight: bold;"--> +zoo = Example::Zoo.new() +<BR>=> #<Example::Zoo:0x2be0fe8> +<BR> +<BR>irb(main):005:0> +<!--span style="font-weight: bold;"--> +tiger1 = Example::Animal.new("tiger1") +<BR>=> #<Example::Animal:0x2bda760> +<BR> +<BR>irb(main):006:0> +<!--span style="font-weight: bold;"--> +zoo.add_animal(tiger1) +<BR>=> nil +<BR> +<BR>irb(main):007:0> +<!--span style="font-weight: bold;"--> +zoo = nil +<BR>=> nil +<BR> +<BR>irb(main):008:0> +<!--span style="font-weight: bold;"--> +GC.start +<BR>=> nil +<BR> +<BR>irb(main):009:0> +<!--span style="font-weight: bold;"--> +tiger1.get_name() +<BR>RuntimeError: This Animal * already released +<BR> from (irb):10:in `get_name' +<BR> from (irb):10 +<BR>irb(main):011:0></PRE> +</DIV> +<P>Notice that SWIG can now detect the underlying C++ object has been + freed, and thus raises a runtime exception.</P> +<P>This code can be seen in swig/examples/ruby/free_function.</P> +<H3><A name="Ruby_nn63"></A>32.10.6 Embedded Ruby and the C++ Stack</H3> +<P>As has been said, the Ruby GC runs and marks objects before its sweep + phase. When the garbage collector is called, it will also try to mark + any Ruby objects (VALUE) it finds in the machine registers and in the + C++ stack.</P> +<P>The stack is basically the history of the functions that have been + called and also contains local variables, such as the ones you define + whenever you do inside a function:</P> +<DIV class="diagram">VALUE obj;</DIV> +<P>For ruby to determine where its stack space begins, during + initialization a normal Ruby interpreter will call the ruby_init() + function which in turn will call a function called Init_stack or + similar. This function will store a pointer to the location where the + stack points at at that point in time.</P> +<P>ruby_init() is presumed to always be called within the main() + function of your program and whenever the GC is called, ruby will + assume that the memory between the current location in memory and the + pointer that was stored previously represents the stack, which may + contain local (and temporary) VALUE ruby objects. Ruby will then be + careful not to remove any of those objects in that location.</P> +<P>So far so good. For a normal Ruby session, all the above is + completely transparent and magic to the extensions developer. </P> +<P>However, with an embedded Ruby, it may not always be possible to + modify main() to make sure ruby_init() is called there. As such, + ruby_init() will likely end up being called from within some other + function. This can lead Ruby to measure incorrectly where the stack + begins and can result in Ruby incorrectly collecting those temporary + VALUE objects that are created once another function is called. The + end result: random crashes and segmentation faults.</P> +<P>This problem will often be seen in director functions that are used + for callbacks, for example. </P> +<P>To solve the problem, SWIG can now generate code with director + functions containing the optional macros SWIG_INIT_STACK and + SWIG_RELEASE_STACK. These macros will try to force Ruby to + reinitiliaze the beginning of the stack the first time a director + function is called. This will lead Ruby to measure and not collect any + VALUE objects defined from that point on. </P> +<P>To mark functions to either reset the ruby stack or not, you can use:</P> +<DIV class="indent code" style="font-family: monospace;">%initstack + Class::memberfunction; // only re-init the stack in this director + method +<BR> %ignorestack Class::memberfunction; // do not re-init the stack in + this director method +<BR> %initstack Class; // init the stack on all the + methods of this class +<BR> %initstack; // all director functions will re-init the stack</DIV> +<HR NOSHADE> +<H1><A name="Tcl"></A>33 SWIG and Tcl</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Tcl_nn2">Preliminaries</A> +<UL> +<LI><A href="#Tcl_nn3">Getting the right header files</A></LI> +<LI><A href="#Tcl_nn4">Compiling a dynamic module</A></LI> +<LI><A href="#Tcl_nn5">Static linking</A></LI> +<LI><A href="#Tcl_nn6">Using your module</A></LI> +<LI><A href="#Tcl_nn7">Compilation of C++ extensions</A></LI> +<LI><A href="#Tcl_nn8">Compiling for 64-bit platforms</A></LI> +<LI><A href="#Tcl_nn9">Setting a package prefix</A></LI> +<LI><A href="#Tcl_nn10">Using namespaces</A></LI> +</UL> +</LI> +<LI><A href="#Tcl_nn11">Building Tcl/Tk Extensions under Windows 95/NT</A> +<UL> +<LI><A href="#Tcl_nn12">Running SWIG from Developer Studio</A></LI> +<LI><A href="#Tcl_nn13">Using NMAKE</A></LI> +</UL> +</LI> +<LI><A href="#Tcl_nn14">A tour of basic C/C++ wrapping</A> +<UL> +<LI><A href="#Tcl_nn15">Modules</A></LI> +<LI><A href="#Tcl_nn16">Functions</A></LI> +<LI><A href="#Tcl_nn17">Global variables</A></LI> +<LI><A href="#Tcl_nn18">Constants and enums</A></LI> +<LI><A href="#Tcl_nn19">Pointers</A></LI> +<LI><A href="#Tcl_nn20">Structures</A></LI> +<LI><A href="#Tcl_nn21">C++ classes</A></LI> +<LI><A href="#Tcl_nn22">C++ inheritance</A></LI> +<LI><A href="#Tcl_nn23">Pointers, references, values, and arrays</A></LI> +<LI><A href="#Tcl_nn24">C++ overloaded functions</A></LI> +<LI><A href="#Tcl_nn25">C++ operators</A></LI> +<LI><A href="#Tcl_nn26">C++ namespaces</A></LI> +<LI><A href="#Tcl_nn27">C++ templates</A></LI> +<LI><A href="#Tcl_nn28">C++ Smart Pointers</A></LI> +</UL> +</LI> +<LI><A href="#Tcl_nn29">Further details on the Tcl class interface</A> +<UL> +<LI><A href="#Tcl_nn30">Proxy classes</A></LI> +<LI><A href="#Tcl_nn31">Memory management</A></LI> +</UL> +</LI> +<LI><A href="#Tcl_nn32">Input and output parameters</A></LI> +<LI><A href="#Tcl_nn33">Exception handling</A></LI> +<LI><A href="#Tcl_nn34">Typemaps</A> +<UL> +<LI><A href="#Tcl_nn35">What is a typemap?</A></LI> +<LI><A href="#Tcl_nn36">Tcl typemaps</A></LI> +<LI><A href="#Tcl_nn37">Typemap variables</A></LI> +<LI><A href="#Tcl_nn38">Converting a Tcl list to a char **</A></LI> +<LI><A href="#Tcl_nn39">Returning values in arguments</A></LI> +<LI><A href="#Tcl_nn40">Useful functions</A></LI> +<LI><A href="#Tcl_nn41">Standard typemaps</A></LI> +<LI><A href="#Tcl_nn42">Pointer handling</A></LI> +</UL> +</LI> +<LI><A href="#Tcl_nn43">Turning a SWIG module into a Tcl Package.</A></LI> +<LI><A href="#Tcl_nn44">Building new kinds of Tcl interfaces (in Tcl)</A> +<UL> +<LI><A href="#Tcl_nn45">Proxy classes</A></LI> +</UL> +</LI> +<LI><A href="#Tcl_nn46">Tcl/Tk Stubs</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P><B> Caution: This chapter is under repair!</B></P> +<P> This chapter discusses SWIG's support of Tcl. SWIG currently + requires Tcl 8.0 or a later release. Earlier releases of SWIG supported + Tcl 7.x, but this is no longer supported.</P> +<H2><A name="Tcl_nn2"></A>33.1 Preliminaries</H2> +<P> To build a Tcl module, run SWIG using the <TT>-tcl</TT> option :</P> +<DIV class="code"> +<PRE> +$ swig -tcl example.i +</PRE> +</DIV> +<P> If building a C++ extension, add the <TT>-c++</TT> option:</P> +<DIV class="code"> +<PRE> +$ swig -c++ -tcl example.i +</PRE> +</DIV> +<P> This creates a file <TT>example_wrap.c</TT> or <TT>example_wrap.cxx</TT> + that contains all of the code needed to build a Tcl extension module. + To finish building the module, you need to compile this file and link + it with the rest of your program.</P> +<H3><A name="Tcl_nn3"></A>33.1.1 Getting the right header files</H3> +<P> In order to compile the wrapper code, the compiler needs the <TT> +tcl.h</TT> header file. This file is usually contained in the directory</P> +<DIV class="code"> +<PRE> +/usr/local/include +</PRE> +</DIV> +<P> Be aware that some Tcl versions install this header file with a + version number attached to it. If this is the case, you should probably + make a symbolic link so that <TT>tcl.h</TT> points to the correct + header file.</P> +<H3><A name="Tcl_nn4"></A>33.1.2 Compiling a dynamic module</H3> +<P> The preferred approach to building an extension module is to compile + it into a shared object file or DLL. To do this, you will need to + compile your program using commands like this (shown for Linux):</P> +<DIV class="code"> +<PRE> +$ swig -tcl example.i +$ gcc -c example.c +$ gcc -c example_wrap.c -I/usr/local/include +$ gcc -shared example.o example_wrap.o -o example.so +</PRE> +</DIV> +<P> The exact commands for doing this vary from platform to platform. + SWIG tries to guess the right options when it is installed. Therefore, + you may want to start with one of the examples in the <TT> +SWIG/Examples/tcl</TT> directory. If that doesn't work, you will need to + read the man-pages for your compiler and linker to get the right set of + options. You might also check the <A href="http://www.dabeaz.com/cgi-bin/wiki.pl"> +SWIG Wiki</A> for additional information.</P> +<P> When linking the module, the name of the output file has to match + the name of the module. If the name of your SWIG module is "<TT>example</TT> +", the name of the corresponding object file should be "<TT>example.so</TT> +". The name of the module is specified using the <TT>%module</TT> + directive or the <TT>-module</TT> command line option.</P> +<H3><A name="Tcl_nn5"></A>33.1.3 Static linking</H3> +<P> An alternative approach to dynamic linking is to rebuild the Tcl + interpreter with your extension module added to it. In the past, this + approach was sometimes necessary due to limitations in dynamic loading + support on certain machines. However, the situation has improved + greatly over the last few years and you should not consider this + approach unless there is really no other option.</P> +<P> The usual procedure for adding a new module to Tcl involves writing + a special function <TT>Tcl_AppInit()</TT> and using it to initialize + the interpreter and your module. With SWIG, the <TT>tclsh.i</TT> and <TT> +wish.i</TT> library files can be used to rebuild the <TT>tclsh</TT> and <TT> +wish</TT> interpreters respectively. For example:</P> +<DIV class="code"> +<PRE> +%module example + +%inline %{ +extern int fact(int); +extern int mod(int, int); +extern double My_variable; +%} + +%include "tclsh.i" // Include code for rebuilding tclsh + +</PRE> +</DIV> +<P> The <TT>tclsh.i</TT> library file includes supporting code that + contains everything needed to rebuild tclsh. To rebuild the + interpreter, you simply do something like this:</P> +<DIV class="code"> +<PRE> +$ swig -tcl example.i +$ gcc example.c example_wrap.c \ + -Xlinker -export-dynamic \ + -DHAVE_CONFIG_H -I/usr/local/include/ \ + -L/usr/local/lib -ltcl -lm -ldl \ + -o mytclsh + +</PRE> +</DIV> +<P> You will need to supply the same libraries that were used to build + Tcl the first time. This may include system libraries such as <TT> +-lsocket</TT>, <TT>-lnsl</TT>, and <TT>-lpthread</TT>. If this actually + works, the new version of Tcl should be identical to the default + version except that your extension module will be a built-in part of + the interpreter.</P> +<P><B> Comment:</B> In practice, you should probably try to avoid static + linking if possible. Some programmers may be inclined to use static + linking in the interest of getting better performance. However, the + performance gained by static linking tends to be rather minimal in most + situations (and quite frankly not worth the extra hassle in the opinion + of this author).</P> +<H3><A name="Tcl_nn6"></A>33.1.4 Using your module</H3> +<P> To use your module, simply use the Tcl <TT>load</TT> command. If all + goes well, you will be able to this:</P> +<DIV class="code"> +<PRE> +$ tclsh +% load ./example.so +% fact 4 +24 +% +</PRE> +</DIV> +<P> A common error received by first-time users is the following:</P> +<DIV class="code"> +<PRE> +% load ./example.so +couldn't find procedure Example_Init +% +</PRE> +</DIV> +<P> This error is almost always caused when the name of the shared + object file doesn't match the name of the module supplied using the + SWIG <TT>%module</TT> directive. Double-check the interface to make + sure the module name and the shared object file match. Another possible + cause of this error is forgetting to link the SWIG-generated wrapper + code with the rest of your application when creating the extension + module.</P> +<P> Another common error is something similar to the following:</P> +<DIV class="code"> +<PRE> +% load ./example.so +couldn't load file "./example.so": ./example.so: undefined symbol: fact +% +</PRE> +</DIV> +<P> This error usually indicates that you forgot to include some object + files or libraries in the linking of the shared library file. Make sure + you compile both the SWIG wrapper file and your original program into a + shared library file. Make sure you pass all of the required libraries + to the linker.</P> +<P> Sometimes unresolved symbols occur because a wrapper has been + created for a function that doesn't actually exist in a library. This + usually occurs when a header file includes a declaration for a function + that was never actually implemented or it was removed from a library + without updating the header file. To fix this, you can either edit the + SWIG input file to remove the offending declaration or you can use the <TT> +%ignore</TT> directive to ignore the declaration.</P> +<P> Finally, suppose that your extension module is linked with another + library like this:</P> +<DIV class="code"> +<PRE> +$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \ + -o example.so +</PRE> +</DIV> +<P> If the <TT>foo</TT> library is compiled as a shared library, you + might get the following problem when you try to use your module:</P> +<DIV class="code"> +<PRE> +% load ./example.so +couldn't load file "./example.so": libfoo.so: cannot open shared object file: +No such file or directory +% +</PRE> +</DIV> +<P> This error is generated because the dynamic linker can't locate the <TT> +libfoo.so</TT> library. When shared libraries are loaded, the system + normally only checks a few standard locations such as <TT>/usr/lib</TT> + and <TT>/usr/local/lib</TT>. To fix this problem, there are several + things you can do. First, you can recompile your extension module with + extra path information. For example, on Linux you can do this:</P> +<DIV class="code"> +<PRE> +$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \ + -Xlinker -rpath /home/beazley/projects/lib \ + -o example.so +</PRE> +</DIV> +<P> Alternatively, you can set the <TT>LD_LIBRARY_PATH</TT> environment + variable to include the directory with your shared libraries. If + setting <TT>LD_LIBRARY_PATH</TT>, be aware that setting this variable + can introduce a noticeable performance impact on all other applications + that you run. To set it only for Tcl, you might want to do this + instead:</P> +<DIV class="code"> +<PRE> +$ env LD_LIBRARY_PATH=/home/beazley/projects/lib tclsh +</PRE> +</DIV> +<P> Finally, you can use a command such as <TT>ldconfig</TT> to add + additional search paths to the default system configuration (this + requires root access and you will need to read the man pages).</P> +<H3><A name="Tcl_nn7"></A>33.1.5 Compilation of C++ extensions</H3> +<P> Compilation of C++ extensions has traditionally been a tricky + problem. Since the Tcl interpreter is written in C, you need to take + steps to make sure C++ is properly initialized and that modules are + compiled correctly.</P> +<P> On most machines, C++ extension modules should be linked using the + C++ compiler. For example:</P> +<DIV class="code"> +<PRE> +% swig -c++ -tcl example.i +% g++ -c example.cxx +% g++ -c example_wrap.cxx -I/usr/local/include +% g++ -shared example.o example_wrap.o -o example.so +</PRE> +</DIV> +<P> In addition to this, you may need to include additional library + files to make it work. For example, if you are using the Sun C++ + compiler on Solaris, you often need to add an extra library <TT>-lCrun</TT> + like this:</P> +<DIV class="code"> +<PRE> +% swig -c++ -tcl example.i +% CC -c example.cxx +% CC -c example_wrap.cxx -I/usr/local/include +% CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o example.so -lCrun +</PRE> +</DIV> +<P> Of course, the extra libraries to use are completely + non-portable---you will probably need to do some experimentation.</P> +<P> Sometimes people have suggested that it is necessary to relink the + Tcl interpreter using the C++ compiler to make C++ extension modules + work. In the experience of this author, this has never actually + appeared to be necessary. Relinking the interpreter with C++ really + only includes the special run-time libraries described above---as long + as you link your extension modules with these libraries, it should not + be necessary to rebuild Tcl.</P> +<P> If you aren't entirely sure about the linking of a C++ extension, + you might look at an existing C++ program. On many Unix machines, the <TT> +ldd</TT> command will list library dependencies. This should give you + some clues about what you might have to include when you link your + extension module. For example:</P> +<DIV class="code"> +<PRE> +$ ldd swig + libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000) + libm.so.6 => /lib/libm.so.6 (0x4005b000) + libc.so.6 => /lib/libc.so.6 (0x40077000) + /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) +$ +</PRE> +</DIV> +<P> As a final complication, a major weakness of C++ is that it does not + define any sort of standard for binary linking of libraries. This means + that C++ code compiled by different compilers will not link together + properly as libraries nor is the memory layout of classes and data + structures implemented in any kind of portable manner. In a monolithic + C++ program, this problem may be unnoticed. However, in Tcl, it is + possible for different extension modules to be compiled with different + C++ compilers. As long as these modules are self-contained, this + probably won't matter. However, if these modules start sharing data, + you will need to take steps to avoid segmentation faults and other + erratic program behavior. If working with lots of software components, + you might want to investigate using a more formal standard such as COM.</P> +<H3><A name="Tcl_nn8"></A>33.1.6 Compiling for 64-bit platforms</H3> +<P> On platforms that support 64-bit applications (Solaris, Irix, etc.), + special care is required when building extension modules. On these + machines, 64-bit applications are compiled and linked using a different + set of compiler/linker options. In addition, it is not generally + possible to mix 32-bit and 64-bit code together in the same + application.</P> +<P> To utilize 64-bits, the Tcl executable will need to be recompiled as + a 64-bit application. In addition, all libraries, wrapper code, and + every other part of your application will need to be compiled for + 64-bits. If you plan to use other third-party extension modules, they + will also have to be recompiled as 64-bit extensions.</P> +<P> If you are wrapping commercial software for which you have no source + code, you will be forced to use the same linking standard as used by + that software. This may prevent the use of 64-bit extensions. It may + also introduce problems on platforms that support more than one linking + standard (e.g., -o32 and -n32 on Irix).</P> +<H3><A name="Tcl_nn9"></A>33.1.7 Setting a package prefix</H3> +<P> To avoid namespace problems, you can instruct SWIG to append a + package prefix to all of your functions and variables. This is done + using the -prefix option as follows :</P> +<DIV class="code"> +<PRE> +swig -tcl -prefix Foo example.i +</PRE> +</DIV> +<P> If you have a function "<TT>bar</TT>" in the SWIG file, the prefix + option will append the prefix to the name when creating a command and + call it "<TT>Foo_bar</TT>".</P> +<H3><A name="Tcl_nn10"></A>33.1.8 Using namespaces</H3> +<P> Alternatively, you can have SWIG install your module into a Tcl + namespace by specifying the <TT>-namespace</TT> option :</P> +<DIV class="code"> +<PRE> +swig -tcl -namespace example.i +</PRE> +</DIV> +<P> By default, the name of the namespace will be the same as the module + name, but you can override it using the <TT>-prefix</TT> option.</P> +<P> When the <TT>-namespace</TT> option is used, objects in the module + are always accessed with the namespace name such as <TT>Foo::bar</TT>.</P> +<H2><A name="Tcl_nn11"></A>33.2 Building Tcl/Tk Extensions under Windows + 95/NT</H2> +<P> Building a SWIG extension to Tcl/Tk under Windows 95/NT is roughly + similar to the process used with Unix. Normally, you will want to + produce a DLL that can be loaded into tclsh or wish. This section + covers the process of using SWIG with Microsoft Visual C++. although + the procedure may be similar with other compilers.</P> +<H3><A name="Tcl_nn12"></A>33.2.1 Running SWIG from Developer Studio</H3> +<P> If you are developing your application within Microsoft developer + studio, SWIG can be invoked as a custom build option. The process + roughly follows these steps :</P> +<UL> +<LI>Open up a new workspace and use the AppWizard to select a DLL + project.</LI> +<LI>Add both the SWIG interface file (the .i file), any supporting C + files, and the name of the wrapper file that will be created by SWIG + (ie. <TT>example_wrap.c</TT>). Note : If using C++, choose a different + suffix for the wrapper file such as <TT>example_wrap.cxx</TT>. Don't + worry if the wrapper file doesn't exist yet--Developer studio will keep + a reference to it around.</LI> +<LI>Select the SWIG interface file and go to the settings menu. Under + settings, select the "Custom Build" option.</LI> +<LI>Enter "SWIG" in the description field.</LI> +<LI>Enter "<TT>swig -tcl -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)</TT> +" in the "Build command(s) field"</LI> +<LI>Enter "<TT>$(ProjDir)\$(InputName)_wrap.c</TT>" in the "Output + files(s) field".</LI> +<LI>Next, select the settings for the entire project and go to + "C++:Preprocessor". Add the include directories for your Tcl + installation under "Additional include directories".</LI> +<LI>Finally, select the settings for the entire project and go to "Link + Options". Add the Tcl library file to your link libraries. For example + "<TT>tcl80.lib</TT>". Also, set the name of the output file to match + the name of your Tcl module (ie. example.dll).</LI> +<LI>Build your project.</LI> +</UL> +<P> Now, assuming all went well, SWIG will be automatically invoked when + you build your project. Any changes made to the interface file will + result in SWIG being automatically invoked to produce a new version of + the wrapper file. To run your new Tcl extension, simply run <TT>tclsh</TT> + or <TT>wish</TT> and use the <TT>load</TT> command. For example :</P> +<DIV class="code"> +<PRE> +MSDOS > tclsh80 +% load example.dll +% fact 4 +24 +% +</PRE> +</DIV> +<H3><A name="Tcl_nn13"></A>33.2.2 Using NMAKE</H3> +<P> Alternatively, SWIG extensions can be built by writing a Makefile + for NMAKE. To do this, make sure the environment variables for MSVC++ + are available and the MSVC++ tools are in your path. Now, just write a + short Makefile like this :</P> +<DIV class="code"> +<PRE> +# Makefile for building various SWIG generated extensions + +SRCS = example.c +IFILE = example +INTERFACE = $(IFILE).i +WRAPFILE = $(IFILE)_wrap.c + +# Location of the Visual C++ tools (32 bit assumed) + +TOOLS = c:\msdev +TARGET = example.dll +CC = $(TOOLS)\bin\cl.exe +LINK = $(TOOLS)\bin\link.exe +INCLUDE32 = -I$(TOOLS)\include +MACHINE = IX86 + +# C Library needed to build a DLL + +DLLIBC = msvcrt.lib oldnames.lib + +# Windows libraries that are apparently needed +WINLIB = kernel32.lib advapi32.lib user32.lib gdi32.lib comdlg32.lib +winspool.lib + +# Libraries common to all DLLs +LIBS = $(DLLIBC) $(WINLIB) + +# Linker options +LOPT = -debug:full -debugtype:cv /NODEFAULTLIB /RELEASE /NOLOGO / +MACHINE:$(MACHINE) -entry:_DllMainCRTStartup@12 -dll + +# C compiler flags + +CFLAGS = /Z7 /Od /c /nologo +TCL_INCLUDES = -Id:\tcl8.0a2\generic -Id:\tcl8.0a2\win +TCLLIB = d:\tcl8.0a2\win\tcl80.lib + +tcl:: + ..\..\swig -tcl -o $(WRAPFILE) $(INTERFACE) + $(CC) $(CFLAGS) $(TCL_INCLUDES) $(SRCS) $(WRAPFILE) + set LIB=$(TOOLS)\lib + $(LINK) $(LOPT) -out:example.dll $(LIBS) $(TCLLIB) example.obj example_wrap.obj + +</PRE> +</DIV> +<P> To build the extension, run NMAKE (you may need to run vcvars32 + first). This is a pretty minimal Makefile, but hopefully its enough to + get you started. With a little practice, you'll be making lots of Tcl + extensions.</P> +<H2><A name="Tcl_nn14"></A>33.3 A tour of basic C/C++ wrapping</H2> +<P> By default, SWIG tries to build a very natural Tcl interface to your + C/C++ code. Functions are wrapped as functions, classes are wrapped in + an interface that mimics the style of Tk widgets and [incr Tcl] + classes. This section briefly covers the essential aspects of this + wrapping.</P> +<H3><A name="Tcl_nn15"></A>33.3.1 Modules</H3> +<P> The SWIG <TT>%module</TT> directive specifies the name of the Tcl + module. If you specify `<TT>%module example</TT>', then everything is + compiled into an extension module <TT>example.so</TT>. When choosing a + module name, make sure you don't use the same name as a built-in Tcl + command.</P> +<P> One pitfall to watch out for is module names involving numbers. If + you specify a module name like <TT>%module md5</TT>, you'll find that + the load command no longer seems to work:</P> +<DIV class="code"> +<PRE> +% load ./md5.so +couldn't find procedure Md_Init +</PRE> +</DIV> +<P> To fix this, supply an extra argument to <TT>load</TT> like this:</P> +<DIV class="code"> +<PRE> +% load ./md5.so md5 +</PRE> +</DIV> +<H3><A name="Tcl_nn16"></A>33.3.2 Functions</H3> +<P> Global functions are wrapped as new Tcl built-in commands. For + example,</P> +<DIV class="code"> +<PRE> +%module example +int fact(int n); +</PRE> +</DIV> +<P> creates a built-in function <TT>fact</TT> that works exactly like + you think it does:</P> +<DIV class="code"> +<PRE> +% load ./example.so +% fact 4 +24 +% set x [fact 6] +% +</PRE> +</DIV> +<H3><A name="Tcl_nn17"></A>33.3.3 Global variables</H3> +<P> C/C++ global variables are wrapped by Tcl global variables. For + example:</P> +<DIV class="code"> +<PRE> +// SWIG interface file with global variables +%module example +... +%inline %{ +extern double density; +%} +... +</PRE> +</DIV> +<P> Now look at the Tcl interface:</P> +<DIV class="code"> +<PRE> +% puts $density # Output value of C global variable +1.0 +% set density 0.95 # Change value +</PRE> +</DIV> +<P> If you make an error in variable assignment, you will get an error + message. For example:</P> +<DIV class="code"> +<PRE> +% set density "hello" +can't set "density": Type error. expected a double. +% +</PRE> +</DIV> +<P> If a variable is declared as <TT>const</TT>, it is wrapped as a + read-only variable. Attempts to modify its value will result in an + error.</P> +<P> To make ordinary variables read-only, you can use the <TT>%immutable</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +%{ +extern char *path; +%} +%immutable; +extern char *path; +%mutable; +</PRE> +</DIV> +<P> The <TT>%immutable</TT> directive stays in effect until it is + explicitly disabled or cleared using <TT>%mutable</TT>. See the <A href="#SWIG_readonly_variables"> +Creating read-only variables</A> section for further details.</P> +<P> If you just want to make a specific variable immutable, supply a + declaration name. For example:</P> +<DIV class="code"> +<PRE> +%{ +extern char *path; +%} +%immutable path; +... +extern char *path; // Read-only (due to %immutable) +</PRE> +</DIV> +<H3><A name="Tcl_nn18"></A>33.3.4 Constants and enums</H3> +<P> C/C++ constants are installed as global Tcl variables containing the + appropriate value. To create a constant, use <TT>#define</TT>, <TT>enum</TT> +, or the <TT>%constant</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +#define PI 3.14159 +#define VERSION "1.0" + +enum Beverage { ALE, LAGER, STOUT, PILSNER }; + +%constant int FOO = 42; +%constant const char *path = "/usr/local"; +</PRE> +</DIV> +<P> For enums, make sure that the definition of the enumeration actually + appears in a header file or in the wrapper file somehow---if you just + stick an enum in a SWIG interface without also telling the C compiler + about it, the wrapper code won't compile.</P> +<P> Note: declarations declared as <TT>const</TT> are wrapped as + read-only variables and will be accessed using the <TT>cvar</TT> object + described in the previous section. They are not wrapped as constants. + For further discussion about this, see the <A href="#SWIG">SWIG Basics</A> + chapter.</P> +<P> Constants are not guaranteed to remain constant in Tcl---the value + of the constant could be accidentally reassigned.You will just have to + be careful.</P> +<P> A peculiarity of installing constants as variables is that it is + necessary to use the Tcl <TT>global</TT> statement to access constants + in procedure bodies. For example:</P> +<DIV class="code"> +<PRE> +proc blah {} { + global FOO + bar $FOO +} +</PRE> +</DIV> +<P> If a program relies on a lot of constants, this can be extremely + annoying. To fix the problem, consider using the following typemap + rule:</P> +<DIV class="code"> +<PRE> +%apply int CONSTANT { int x }; +#define FOO 42 +... +void bar(int x); +</PRE> +</DIV> +<P> When applied to an input argument, the <TT>CONSTANT</TT> rule allows + a constant to be passed to a function using its actual value or a + symbolic identifier name. For example:</P> +<DIV class="code"> +<PRE> +proc blah {} { + bar FOO +} +</PRE> +</DIV> +<P> When an identifier name is given, it is used to perform an implicit + hash-table lookup of the value during argument conversion. This allows + the <TT>global</TT> statement to be omitted.</P> +<H3><A name="Tcl_nn19"></A>33.3.5 Pointers</H3> +<P> C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no + problem working with incomplete type information. Here is a rather + simple interface:</P> +<DIV class="code"> +<PRE> +%module example + +FILE *fopen(const char *filename, const char *mode); +int fputs(const char *, FILE *); +int fclose(FILE *); +</PRE> +</DIV> +<P> When wrapped, you will be able to use the functions in a natural way + from Tcl. For example:</P> +<DIV class="code"> +<PRE> +% load ./example.so +% set f [fopen junk w] +% fputs "Hello World\n" $f +% fclose $f +</PRE> +</DIV> +<P> If this makes you uneasy, rest assured that there is no deep magic + involved. Underneath the covers, pointers to C/C++ objects are simply + represented as opaque values--normally an encoded character string like + this:</P> +<DIV class="code"> +<PRE> +% puts $f +_c0671108_p_FILE +% +</PRE> +</DIV> +<P> This pointer value can be freely passed around to different C + functions that expect to receive an object of type <TT>FILE *</TT>. The + only thing you can't do is dereference the pointer from Tcl.</P> +<P> The NULL pointer is represented by the string <TT>NULL</TT>.</P> +<P> As much as you might be inclined to modify a pointer value directly + from Tcl, don't. The hexadecimal encoding is not necessarily the same + as the logical memory address of the underlying object. Instead it is + the raw byte encoding of the pointer value. The encoding will vary + depending on the native byte-ordering of the platform (i.e., big-endian + vs. little-endian). Similarly, don't try to manually cast a pointer to + a new type by simply replacing the type-string. This may not work like + you expect and it is particularly dangerous when casting C++ objects. + If you need to cast a pointer or change its value, consider writing + some helper functions instead. For example:</P> +<DIV class="code"> +<PRE> +%inline %{ +/* C-style cast */ +Bar *FooToBar(Foo *f) { + return (Bar *) f; +} + +/* C++-style cast */ +Foo *BarToFoo(Bar *b) { + return dynamic_cast<Foo*>(b); +} + +Foo *IncrFoo(Foo *f, int i) { + return f+i; +} +%} +</PRE> +</DIV> +<P> Also, if working with C++, you should always try to use the new C++ + style casts. For example, in the above code, the C-style cast may + return a bogus result whereas as the C++-style cast will return <TT> +None</TT> if the conversion can't be performed.</P> +<H3><A name="Tcl_nn20"></A>33.3.6 Structures</H3> +<P> If you wrap a C structure, it is wrapped by a Tcl interface that + somewhat resembles a Tk widget. This provides a very natural interface. + For example,</P> +<DIV class="code"> +<PRE> +struct Vector { + double x,y,z; +}; + +</PRE> +</DIV> +<P> is used as follows:</P> +<DIV class="code"> +<PRE> +% Vector v +% v configure -x 3.5 -y 7.2 +% puts "[v cget -x] [v cget -y] [v cget -z]" +3.5 7.2 0.0 +% +</PRE> +</DIV> +<P> Similar access is provided for unions and the data members of C++ + classes.</P> +<P> In the above example, <TT>v</TT> is a name that's used for the + object. However, underneath the covers, there's a pointer to a raw C + structure. This can be obtained by looking at the <TT>-this</TT> + attribute. For example:</P> +<DIV class="code"> +<PRE> +% puts [v cget -this] +_88e31408_p_Vector +</PRE> +</DIV> +<P> Further details about the relationship between the Tcl and the + underlying C structure are covered a little later.</P> +<P> <TT>const</TT> members of a structure are read-only. Data members + can also be forced to be read-only using the <TT>%immutable</TT> + directive. For example:</P> +<DIV class="code"> +<PRE> +struct Foo { + ... + %immutable; + int x; /* Read-only members */ + char *name; + %mutable; + ... +}; +</PRE> +</DIV> +<P> When <TT>char *</TT> members of a structure are wrapped, the + contents are assumed to be dynamically allocated using <TT>malloc</TT> + or <TT>new</TT> (depending on whether or not SWIG is run with the -c++ + option). When the structure member is set, the old contents will be + released and a new value created. If this is not the behavior you want, + you will have to use a typemap (described later).</P> +<P> If a structure contains arrays, access to those arrays is managed + through pointers. For example, consider this:</P> +<DIV class="code"> +<PRE> +struct Bar { + int x[16]; +}; +</PRE> +</DIV> +<P> If accessed in Tcl, you will see behavior like this:</P> +<DIV class="code"> +<PRE> +% Bar b +% puts [b cget -x] +_801861a4_p_int +% +</PRE> +</DIV> +<P> This pointer can be passed around to functions that expect to + receive an <TT>int *</TT> (just like C). You can also set the value of + an array member using another pointer. For example:</P> +<DIV class="code"> +<PRE> +% Bar c +% c configure -x [b cget -x] # Copy contents of b.x to c.x +</PRE> +</DIV> +<P> For array assignment, SWIG copies the entire contents of the array + starting with the data pointed to by <TT>b.x</TT>. In this example, 16 + integers would be copied. Like C, SWIG makes no assumptions about + bounds checking---if you pass a bad pointer, you may get a segmentation + fault or access violation.</P> +<P> When a member of a structure is itself a structure, it is handled as + a pointer. For example, suppose you have two structures like this:</P> +<DIV class="code"> +<PRE> +struct Foo { + int a; +}; + +struct Bar { + Foo f; +}; +</PRE> +</DIV> +<P> Now, suppose that you access the <TT>f</TT> attribute of <TT>Bar</TT> + like this:</P> +<DIV class="code"> +<PRE> +% Bar b +% set x [b cget -f] +</PRE> +</DIV> +<P> In this case, <TT>x</TT> is a pointer that points to the <TT>Foo</TT> + that is inside <TT>b</TT>. This is the same value as generated by this + C code:</P> +<DIV class="code"> +<PRE> +Bar b; +Foo *x = &b->f; /* Points inside b */ +</PRE> +</DIV> +<P> However, one peculiarity of accessing a substructure like this is + that the returned value does work quite like you might expect. For + example:</P> +<DIV class="code"> +<PRE> +% Bar b +% set x [b cget -f] +% x cget -a +invalid command name "x" +</PRE> +</DIV> +<P> This is because the returned value was not created in a normal way + from the interpreter (x is not a command object). To make it function + normally, just evaluate the variable like this:</P> +<DIV class="code"> +<PRE> +% Bar b +% set x [b cget -f] +% $x cget -a +0 +% +</PRE> +</DIV> +<P> In this example, <TT>x</TT> points inside the original structure. + This means that modifications work just like you would expect. For + example:</P> +<DIV class="code"> +<PRE> + +% Bar b +% set x [b cget -f] +% $x configure -a 3 # Modifies contents of f (inside b) +% [b cget -f] -configure -a 3 # Same thing +</PRE> +</DIV> +<P> In many of these structure examples, a simple name like "v" or "b" + has been given to wrapped structures. If necessary, this name can be + passed to functions that expect to receive an object. For example, if + you have a function like this,</P> +<DIV class="code"> +<PRE> +void blah(Foo *f); +</PRE> +</DIV> +<P> you can call the function in Tcl as follows:</P> +<DIV class="code"> +<PRE> +% Foo x # Create a Foo object +% blah x # Pass the object to a function +</PRE> +</DIV> +<P> It is also possible to call the function using the raw pointer + value. For instance:</P> +<DIV class="code"> +<PRE> +% blah [x cget -this] # Pass object to a function +</PRE> +</DIV> +<P> It is also possible to create and use objects using variables. For + example:</P> +<DIV class="code"> +<PRE> +% set b [Bar] # Create a Bar +% $b cget -f # Member access +% puts $b +_108fea88_p_Bar +% +</PRE> +</DIV> +<P> Finally, to destroy objects created from Tcl, you can either let the + object name go out of scope or you can explicitly delete the object. + For example:</P> +<DIV class="code"> +<PRE> +% Foo f # Create object f +% rename f "" +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +% Foo f # Create object f +% f -delete +</PRE> +</DIV> +<P> Note: Tcl only destroys the underlying object if it has ownership. + See the memory management section that appears shortly.</P> +<H3><A name="Tcl_nn21"></A>33.3.7 C++ classes</H3> +<P> C++ classes are wrapped as an extension of structure wrapping. For + example, if you have this class,</P> +<DIV class="code"> +<PRE> +class List { +public: + List(); + ~List(); + int search(char *item); + void insert(char *item); + void remove(char *item); + char *get(int n); + int length; +}; +</PRE> +</DIV> +<P> you can use it in Tcl like this:</P> +<DIV class="code"> +<PRE> +% List x +% x insert Ale +% x insert Stout +% x insert Lager +% x get 1 +Stout +% puts [l cget -length] +3 +% +</PRE> +</DIV> +<P> Class data members are accessed in the same manner as C structures.</P> +<P> Static class members are accessed as global functions or variables. + To illustrate, suppose you have a class like this:</P> +<DIV class="code"> +<PRE> +class Spam { +public: + static void foo(); + static int bar; + +}; +</PRE> +</DIV> +<P> In Tcl, the static member is accessed as follows:</P> +<DIV class="code"> +<PRE> +% Spam_foo # Spam::foo() +% puts $Spam_bar # Spam::bar +</PRE> +</DIV> +<H3><A name="Tcl_nn22"></A>33.3.8 C++ inheritance</H3> +<P> SWIG is fully aware of issues related to C++ inheritance. Therefore, + if you have classes like this</P> +<DIV class="code"> +<PRE> +class Foo { +... +}; + +class Bar : public Foo { +... +}; +</PRE> +</DIV> +<P> An object of type <TT>Bar</TT> can be used where a <TT>Foo</TT> is + expected. For example, if you have this function:</P> +<DIV class="code"> +<PRE> +void spam(Foo *f); +</PRE> +</DIV> +<P> then the function <TT>spam()</TT> accepts a <TT>Foo *</TT> or a + pointer to any class derived from <TT>Foo</TT>. For instance:</P> +<DIV class="code"> +<PRE> +% Foo f # Create a Foo +% Bar b # Create a Bar +% spam f # OK +% spam b # OK +</PRE> +</DIV> +<P> It is safe to use multiple inheritance with SWIG.</P> +<H3><A name="Tcl_nn23"></A>33.3.9 Pointers, references, values, and + arrays</H3> +<P> In C++, there are many different ways a function might receive and + manipulate objects. For example:</P> +<DIV class="code"> +<PRE> +void spam1(Foo *x); // Pass by pointer +void spam2(Foo &x); // Pass by reference +void spam3(Foo x); // Pass by value +void spam4(Foo x[]); // Array of objects +</PRE> +</DIV> +<P> In Tcl, there is no detailed distinction like this. Because of this, + SWIG unifies all of these types together in the wrapper code. For + instance, if you actually had the above functions, it is perfectly + legal to do this:</P> +<DIV class="code"> +<PRE> +% Foo f # Create a Foo +% spam1 f # Ok. Pointer +% spam2 f # Ok. Reference +% spam3 f # Ok. Value. +% spam4 f # Ok. Array (1 element) +</PRE> +</DIV> +<P> Similar behavior occurs for return values. For example, if you had + functions like this,</P> +<DIV class="code"> +<PRE> +Foo *spam5(); +Foo &spam6(); +Foo spam7(); +</PRE> +</DIV> +<P> then all three functions will return a pointer to some <TT>Foo</TT> + object. Since the third function (spam7) returns a value, newly + allocated memory is used to hold the result and a pointer is returned + (Tcl will release this memory when the return value is garbage + collected).</P> +<H3><A name="Tcl_nn24"></A>33.3.10 C++ overloaded functions</H3> +<P> C++ overloaded functions, methods, and constructors are mostly + supported by SWIG. For example, if you have two functions like this:</P> +<DIV class="code"> +<PRE> +void foo(int); +void foo(char *c); +</PRE> +</DIV> +<P> You can use them in Tcl in a straightforward manner:</P> +<DIV class="code"> +<PRE> +% foo 3 # foo(int) +% foo Hello # foo(char *c) +</PRE> +</DIV> +<P> Similarly, if you have a class like this,</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + Foo(const Foo &); + ... +}; +</PRE> +</DIV> +<P> you can write Tcl code like this:</P> +<DIV class="code"> +<PRE> +% Foo f # Create a Foo +% Foo g f # Copy f +</PRE> +</DIV> +<P> Overloading support is not quite as flexible as in C++. Sometimes + there are methods that SWIG can't disambiguate. For example:</P> +<DIV class="code"> +<PRE> +void spam(int); +void spam(short); +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +void foo(Bar *b); +void foo(Bar &b); +</PRE> +</DIV> +<P> If declarations such as these appear, you will get a warning message + like this:</P> +<DIV class="code"> +<PRE> +example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int) +at example.i:11. +</PRE> +</DIV> +<P> To fix this, you either need to ignore or rename one of the methods. + For example:</P> +<DIV class="code"> +<PRE> +%rename(spam_short) spam(short); +... +void spam(int); +void spam(short); // Accessed as spam_short +</PRE> +</DIV> +<P> or</P> +<DIV class="code"> +<PRE> +%ignore spam(short); +... +void spam(int); +void spam(short); // Ignored +</PRE> +</DIV> +<P> SWIG resolves overloaded functions and methods using a + disambiguation scheme that ranks and sorts declarations according to a + set of type-precedence rules. The order in which declarations appear in + the input does not matter except in situations where ambiguity + arises--in this case, the first declaration takes precedence.</P> +<P> Please refer to the "SWIG and C++" chapter for more information + about overloading.</P> +<H3><A name="Tcl_nn25"></A>33.3.11 C++ operators</H3> +<P> Certain C++ overloaded operators can be handled automatically by + SWIG. For example, consider a class like this:</P> +<DIV class="code"> +<PRE> +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c); + Complex operator+(const Complex &c) const; + Complex operator-(const Complex &c) const; + Complex operator*(const Complex &c) const; + Complex operator-() const; + + double re() const { return rpart; } + double im() const { return ipart; } +}; +</PRE> +</DIV> +<P> When wrapped, it works like this:</P> +<DIV class="code"> +<PRE> +% Complex c 3 4 +% Complex d 7 8 +% set e [c + d] +% $e re +10.0 +% $e im +12.0 +</PRE> +</DIV> +<P> It should be stressed that operators in SWIG have no relationship to + operators in Tcl. In fact, the only thing that's happening here is that + an operator like <TT>operator +</TT> has been renamed to a method <TT>+</TT> +. Therefore, the statement <TT>[c + d]</TT> is really just invoking the <TT> ++</TT> method on <TT>c</TT>. When more than operator is defined (with + different arguments), the standard method overloading facilities are + used. Here is a rather odd looking example:</P> +<DIV class="code"> +<PRE> +% Complex c 3 4 +% Complex d 7 8 +% set e [c - d] # operator-(const Complex &) +% puts "[$e re] [$e im]" +10.0 12.0 +% set f [c -] # operator-() +% puts "[$f re] [$f im]" +-3.0 -4.0 +% +</PRE> +</DIV> +<P> One restriction with operator overloading support is that SWIG is + not able to fully handle operators that aren't defined as part of the + class. For example, if you had code like this</P> +<DIV class="code"> +<PRE> +class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; +</PRE> +</DIV> +<P> then SWIG doesn't know what to do with the friend function--in fact, + it simply ignores it and issues a warning. You can still wrap the + operator, but you may have to encapsulate it in a special function. For + example:</P> +<DIV class="code"> +<PRE> +%rename(Complex_add_dc) operator+(double, const Complex &); +... +Complex operator+(double, const Complex &c); +</PRE> +</DIV> +<P> There are ways to make this operator appear as part of the class + using the <TT>%extend</TT> directive. Keep reading.</P> +<H3><A name="Tcl_nn26"></A>33.3.12 C++ namespaces</H3> +<P> SWIG is aware of C++ namespaces, but namespace names do not appear + in the module nor do namespaces result in a module that is broken up + into submodules or packages. For example, if you have a file like this,</P> +<DIV class="code"> +<PRE> +%module example + +namespace foo { + int fact(int n); + struct Vector { + double x,y,z; + }; +}; +</PRE> +</DIV> +<P> it works in Tcl as follows:</P> +<DIV class="code"> +<PRE> +% load ./example.so +% fact 3 +6 +% Vector v +% v configure -x 3.4 +</PRE> +</DIV> +<P> If your program has more than one namespace, name conflicts (if any) + can be resolved using <TT>%rename</TT> For example:</P> +<DIV class="code"> +<PRE> +%rename(Bar_spam) Bar::spam; + +namespace Foo { + int spam(); +} + +namespace Bar { + int spam(); +} +</PRE> +</DIV> +<P> If you have more than one namespace and your want to keep their + symbols separate, consider wrapping them as separate SWIG modules. For + example, make the module name the same as the namespace and create + extension modules for each namespace separately. If your program + utilizes thousands of small deeply nested namespaces each with + identical symbol names, well, then you get what you deserve.</P> +<H3><A name="Tcl_nn27"></A>33.3.13 C++ templates</H3> +<P> C++ templates don't present a huge problem for SWIG. However, in + order to create wrappers, you have to tell SWIG to create wrappers for + a particular template instantiation. To do this, you use the <TT> +%template</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%module example +%{ +#include "pair.h" +%} + +template<class T1, class T2> +struct pair { + typedef T1 first_type; + typedef T2 second_type; + T1 first; + T2 second; + pair(); + pair(const T1&, const T2&); + ~pair(); +}; + +%template(pairii) pair<int,int>; +</PRE> +</DIV> +<P> In Tcl:</P> +<DIV class="code"> +<PRE> +% pairii p 3 4 +% p cget -first +3 +% p cget -second +4 +</PRE> +</DIV> +<P> Obviously, there is more to template wrapping than shown in this + example. More details can be found in the <A href="#SWIGPlus">SWIG and + C++</A> chapter. Some more complicated examples will appear later.</P> +<H3><A name="Tcl_nn28"></A>33.3.14 C++ Smart Pointers</H3> +<P> In certain C++ programs, it is common to use classes that have been + wrapped by so-called "smart pointers." Generally, this involves the use + of a template class that implements <TT>operator->()</TT> like this:</P> +<DIV class="code"> +<PRE> +template<class T> class SmartPtr { + ... + T *operator->(); + ... +} +</PRE> +</DIV> +<P> Then, if you have a class like this,</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int x; + int bar(); +}; +</PRE> +</DIV> +<P> A smart pointer would be used in C++ as follows:</P> +<DIV class="code"> +<PRE> +SmartPtr<Foo> p = CreateFoo(); // Created somehow (not shown) +... +p->x = 3; // Foo::x +int y = p->bar(); // Foo::bar +</PRE> +</DIV> +<P> To wrap this in Tcl, simply tell SWIG about the <TT>SmartPtr</TT> + class and the low-level <TT>Foo</TT> object. Make sure you instantiate <TT> +SmartPtr</TT> using <TT>%template</TT> if necessary. For example:</P> +<DIV class="code"> +<PRE> +%module example +... +%template(SmartPtrFoo) SmartPtr<Foo>; +... +</PRE> +</DIV> +<P> Now, in Tcl, everything should just "work":</P> +<DIV class="code"> +<PRE> +% set p [CreateFoo] # Create a smart-pointer somehow +% $p configure -x 3 # Foo::x +% $p bar # Foo::bar +</PRE> +</DIV> +<P> If you ever need to access the underlying pointer returned by <TT> +operator->()</TT> itself, simply use the <TT>__deref__()</TT> method. + For example:</P> +<DIV class="code"> +<PRE> +% set f [$p __deref__] # Returns underlying Foo * +</PRE> +</DIV> +<H2><A name="Tcl_nn29"></A>33.4 Further details on the Tcl class + interface</H2> +<P> In the previous section, a high-level view of Tcl wrapping was + presented. A key component of this wrapping is that structures and + classes are wrapped by Tcl class-like objects. This provides a very + natural Tcl interface and allows SWIG to support a number of advanced + features such as operator overloading. However, a number of low-level + details were omitted. This section provides a brief overview of how the + proxy classes work.</P> +<H3><A name="Tcl_nn30"></A>33.4.1 Proxy classes</H3> +<P> In the <A href="#SWIG">"SWIG basics"</A> and <A href="#SWIGPlus"> +"SWIG and C++"</A> chapters, details of low-level structure and class + wrapping are described. To summarize those chapters, if you have a + class like this</P> +<DIV class="code"> +<PRE> +class Foo { +public: + int x; + int spam(int); + ... +</PRE> +</DIV> +<P> then SWIG transforms it into a set of low-level procedural wrappers. + For example:</P> +<DIV class="code"> +<PRE> +Foo *new_Foo() { + return new Foo(); +} +void delete_Foo(Foo *f) { + delete f; +} +int Foo_x_get(Foo *f) { + return f->x; +} +void Foo_x_set(Foo *f, int value) { + f->x = value; +} +int Foo_spam(Foo *f, int arg1) { + return f->spam(arg1); +} +</PRE> +</DIV> +<P> These wrappers are actually found in the Tcl extension module. For + example, you can certainly do this:</P> +<DIV class="code"> +<PRE> +% load ./example.so +% set f [new_Foo] +% Foo_x_get $f +0 +% Foo_spam $f 3 +1 +% +</PRE> +</DIV> +<P> However, in addition to this, the classname <TT>Foo</TT> is used as + an object constructor function. This allows objects to be encapsulated + objects that look a lot like Tk widgets as shown in the last section.</P> +<H3><A name="Tcl_nn31"></A>33.4.2 Memory management</H3> +<P> Associated with each wrapped object, is an ownership flag <TT> +thisown</TT> The value of this flag determines who is responsible for + deleting the underlying C++ object. If set to 1, the Tcl interpreter + destroys the C++ object when the proxy class is garbage collected. If + set to 0 (or if the attribute is missing), then the destruction of the + proxy class has no effect on the C++ object.</P> +<P> When an object is created by a constructor or returned by value, Tcl + automatically takes ownership of the result. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + Foo(); + Foo bar(); +}; +</PRE> +</DIV> +<P> In Tcl:</P> +<DIV class="code"> +<PRE> +% Foo f +% f cget -thisown +1 +% set g [f bar] +% $g cget -thisown +1 +</PRE> +</DIV> +<P> On the other hand, when pointers are returned to Tcl, there is often + no way to know where they came from. Therefore, the ownership is set to + zero. For example:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + ... + Foo *spam(); + ... +}; +</PRE> +</DIV> +<BR><DIV class="code"> +<PRE> +% Foo f +% set s [f spam] +% $s cget -thisown +0 +% +</PRE> +</DIV> +<P> This behavior is especially important for classes that act as + containers. For example, if a method returns a pointer to an object + that is contained inside another object, you definitely don't want Tcl + to assume ownership and destroy it!</P> +<P> Related to containers, ownership issues can arise whenever an object + is assigned to a member or global variable. For example, consider this + interface:</P> +<DIV class="code"> +<PRE> +%module example + +struct Foo { + int value; + Foo *next; +}; + +Foo *head = 0; +</PRE> +</DIV> +<P> When wrapped in Tcl, careful observation will reveal that ownership + changes whenever an object is assigned to a global variable. For + example:</P> +<DIV class="code"> +<PRE> +% Foo f +% f cget -thisown +1 +% set head f +% f cget -thisown +0 +</PRE> +</DIV> +<P> In this case, C is now holding a reference to the object---you + probably don't want Tcl to destroy it. Similarly, this occurs for + members. For example:</P> +<DIV class="code"> +<PRE> +% Foo f +% Foo g +% f cget -thisown +1 +% g cget -thisown +1 +% f configure -next g +% g cget -thisown +0 +% +</PRE> +</DIV> +<P> For the most part, memory management issues remain hidden. However, + there are occasionally situations where you might have to manually + change the ownership of an object. For instance, consider code like + this:</P> +<DIV class="code"> +<PRE> +class Node { + Object *value; +public: + void set_value(Object *v) { value = v; } + ... +}; +</PRE> +</DIV> +<P> Now, consider the following Tcl code:</P> +<DIV class="code"> +<PRE> +% Object v # Create an object +% Node n # Create a node +% n setvalue v # Set value +% v cget -thisown +1 +% +</PRE> +</DIV> +<P> In this case, the object <TT>n</TT> is holding a reference to <TT>v</TT> + internally. However, SWIG has no way to know that this has occurred. + Therefore, Tcl still thinks that it has ownership of the object. Should + the proxy object be destroyed, then the C++ destructor will be invoked + and <TT>n</TT> will be holding a stale-pointer. If you're lucky, you + will only get a segmentation fault.</P> +<P> To work around this, it is always possible to flip the ownership + flag. For example,</P> +<DIV class="code"> +<PRE> +% v -disown # Give ownership to C/C++ +% v -acquire # Acquire ownership +</PRE> +</DIV> +<P> It is also possible to deal with situations like this using + typemaps--an advanced topic discussed later.</P> +<H2><A name="Tcl_nn32"></A>33.5 Input and output parameters</H2> +<P> A common problem in some C programs is handling parameters passed as + simple pointers. For example:</P> +<DIV class="code"> +<PRE> +void add(int x, int y, int *result) { + *result = x + y; +} +</PRE> +</DIV> +<P> or perhaps</P> +<DIV class="code"> +<PRE> +int sub(int *x, int *y) { + return *x+*y; +} +</PRE> +</DIV> +<P> The easiest way to handle these situations is to use the <TT> +typemaps.i</TT> file. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +void add(int, int, int *OUTPUT); +int sub(int *INPUT, int *INPUT); +</PRE> +</DIV> +<P> In Tcl, this allows you to pass simple values instead of pointer. + For example:</P> +<DIV class="code"> +<PRE> +set a [add 3 4] +puts $a +7 +</PRE> +</DIV> +<P> Notice how the <TT>INPUT</TT> parameters allow integer values to be + passed instead of pointers and how the <TT>OUTPUT</TT> parameter + creates a return result.</P> +<P> If you don't want to use the names <TT>INPUT</TT> or <TT>OUTPUT</TT> +, use the <TT>%apply</TT> directive. For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" + +%apply int *OUTPUT { int *result }; +%apply int *INPUT { int *x, int *y}; + +void add(int x, int y, int *result); +int sub(int *x, int *y); +</PRE> +</DIV> +<P> If a function mutates one of its parameters like this,</P> +<DIV class="code"> +<PRE> +void negate(int *x) { + *x = -(*x); +} +</PRE> +</DIV> +<P> you can use <TT>INOUT</TT> like this:</P> +<DIV class="code"> +<PRE> +%include "typemaps.i" +... +void negate(int *INOUT); +</PRE> +</DIV> +<P> In Tcl, a mutated parameter shows up as a return value. For example:</P> +<DIV class="code"> +<PRE> +set a [negate 3] +puts $a +-3 +</PRE> +</DIV> +<P> The most common use of these special typemap rules is to handle + functions that return more than one value. For example, sometimes a + function returns a result as well as a special error code:</P> +<DIV class="code"> +<PRE> +/* send message, return number of bytes sent, along with success code */ +int send_message(char *text, int len, int *success); +</PRE> +</DIV> +<P> To wrap such a function, simply use the <TT>OUTPUT</TT> rule above. + For example:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +%apply int *OUTPUT { int *success }; +... +int send_message(char *text, int *success); +</PRE> +</DIV> +<P> When used in Tcl, the function will return multiple values as a + list.</P> +<DIV class="code"> +<PRE> +set r [send_message "Hello World"] +set bytes [lindex $r 0] +set success [lindex $r 1] +</PRE> +</DIV> +<P> Another common use of multiple return values are in query functions. + For example:</P> +<DIV class="code"> +<PRE> +void get_dimensions(Matrix *m, int *rows, int *columns); +</PRE> +</DIV> +<P> To wrap this, you might use the following:</P> +<DIV class="code"> +<PRE> +%module example +%include "typemaps.i" +%apply int *OUTPUT { int *rows, int *columns }; +... +void get_dimensions(Matrix *m, int *rows, *columns); +</PRE> +</DIV> +<P> Now, in Perl:</P> +<DIV class="code"> +<PRE> +set dim [get_dimensions $m] +set r [lindex $dim 0] +set c [lindex $dim 1] +</PRE> +</DIV> +<H2><A name="Tcl_nn33"></A>33.6 Exception handling</H2> +<P> The <TT>%exception</TT> directive can be used to create a + user-definable exception handler in charge of converting exceptions in + your C/C++ program into Tcl exceptions. The chapter on customization + features contains more details, but suppose you extended the array + example into a C++ class like the following :</P> +<DIV class="code"> +<PRE> +class RangeError {}; // Used for an exception + +class DoubleArray { + private: + int n; + double *ptr; + public: + // Create a new array of fixed size + DoubleArray(int size) { + ptr = new double[size]; + n = size; + } + // Destroy an array + ~DoubleArray() { + delete ptr; + } + // Return the length of the array + int length() { + return n; + } + + // Get an item from the array and perform bounds checking. + double getitem(int i) { + if ((i >= 0) && (i < n)) + return ptr[i]; + else + throw RangeError(); + } + + // Set an item in the array and perform bounds checking. + void setitem(int i, double val) { + if ((i >= 0) && (i < n)) + ptr[i] = val; + else { + throw RangeError(); + } + } + }; +</PRE> +</DIV> +<P> The functions associated with this class can throw a C++ range + exception for an out-of-bounds array access. We can catch this in our + Tcl extension by specifying the following in an interface file :</P> +<DIV class="code"> +<PRE> +%exception { + try { + $action // Gets substituted by actual function call + } + catch (RangeError) { + Tcl_SetStringObj(tcl_result,"Array index out-of-bounds"); + return TCL_ERROR; + } +} +</PRE> +</DIV> +<P> As shown, the exception handling code will be added to every wrapper + function. Since this is somewhat inefficient. You might consider + refining the exception handler to only apply to specific methods like + this:</P> +<DIV class="code"> +<PRE> +%exception getitem { + try { + $action + } + catch (RangeError) { + Tcl_SetStringObj(tcl_result,"Array index out-of-bounds"); + return TCL_ERROR; + } +} + +%exception setitem { + try { + $action + } + catch (RangeError) { + Tcl_SetStringObj(tcl_result,"Array index out-of-bounds"); + return TCL_ERROR; + } +} +</PRE> +</DIV> +<P> In this case, the exception handler is only attached to methods and + functions named <TT>getitem</TT> and <TT>setitem</TT>.</P> +<P> If you had a lot of different methods, you can avoid extra typing by + using a macro. For example:</P> +<DIV class="code"> +<PRE> +%define RANGE_ERROR +{ + try { + $action + } + catch (RangeError) { + Tcl_SetStringObj(tcl_result,"Array index out-of-bounds"); + return TCL_ERROR; + } +} +%enddef + +%exception getitem RANGE_ERROR; +%exception setitem RANGE_ERROR; +</PRE> +</DIV> +<P> Since SWIG's exception handling is user-definable, you are not + limited to C++ exception handling. See the chapter on "<A href="#Customization"> +Customization Features</A>" for more examples.</P> +<H2><A name="Tcl_nn34"></A>33.7 Typemaps</H2> +<P> This section describes how you can modify SWIG's default wrapping + behavior for various C/C++ datatypes using the <TT>%typemap</TT> + directive. This is an advanced topic that assumes familiarity with the + Tcl C API as well as the material in the "<A href="#Typemaps">Typemaps</A> +" chapter.</P> +<P> Before proceeding, it should be stressed that typemaps are not a + required part of using SWIG---the default wrapping behavior is enough + in most cases. Typemaps are only used if you want to change some aspect + of the primitive C-Tcl interface.</P> +<H3><A name="Tcl_nn35"></A>33.7.1 What is a typemap?</H3> +<P> A typemap is nothing more than a code generation rule that is + attached to a specific C datatype. For example, to convert integers + from Tcl to C, you might define a typemap like this:</P> +<DIV class="code"> +<PRE> +%module example + +%typemap(in) int { + if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR; + printf("Received an integer : %d\n",$1); +} +%inline %{ +extern int fact(int n); +%} +</PRE> +</DIV> +<P> Typemaps are always associated with some specific aspect of code + generation. In this case, the "in" method refers to the conversion of + input arguments to C/C++. The datatype <TT>int</TT> is the datatype to + which the typemap will be applied. The supplied C code is used to + convert values. In this code a number of special variable prefaced by a + <TT>$</TT> are used. The <TT>$1</TT> variable is placeholder for a + local variable of type <TT>int</TT>. The <TT>$input</TT> variable is + the input object of type <TT>Tcl_Obj *</TT>.</P> +<P> When this example is compiled into a Tcl module, it operates as + follows:</P> +<DIV class="code"> +<PRE> +% load ./example.so +% fact 6 +Received an integer : 6 +720 +</PRE> +</DIV> +<P> In this example, the typemap is applied to all occurrences of the <TT> +int</TT> datatype. You can refine this by supplying an optional + parameter name. For example:</P> +<DIV class="code"> +<PRE> +%module example + +%typemap(in) int n { + if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR; + printf("n = %d\n",$1); +} +%inline %{ +extern int fact(int n); +%} +</PRE> +</DIV> +<P> In this case, the typemap code is only attached to arguments that + exactly match <TT>int n</TT>.</P> +<P> The application of a typemap to specific datatypes and argument + names involves more than simple text-matching--typemaps are fully + integrated into the SWIG type-system. When you define a typemap for <TT> +int</TT>, that typemap applies to <TT>int</TT> and qualified variations + such as <TT>const int</TT>. In addition, the typemap system follows <TT> +typedef</TT> declarations. For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) int n { + if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR; + printf("n = %d\n",$1); +} +%inline %{ +typedef int Integer; +extern int fact(Integer n); // Above typemap is applied +%} +</PRE> +</DIV> +<P> However, the matching of <TT>typedef</TT> only occurs in one + direction. If you defined a typemap for <TT>Integer</TT>, it is not + applied to arguments of type <TT>int</TT>.</P> +<P> Typemaps can also be defined for groups of consecutive arguments. + For example:</P> +<DIV class="code"> +<PRE> +%typemap(in) (char *str, int len) { + $1 = Tcl_GetStringFromObj($input,&$2); +}; + +int count(char c, char *str, int len); +</PRE> +</DIV> +<P> When a multi-argument typemap is defined, the arguments are always + handled as a single Tcl object. This allows the function to be used + like this (notice how the length parameter is omitted):</P> +<DIV class="code"> +<PRE> +% count e "Hello World" +1 +</PRE> +</DIV> +<H3><A name="Tcl_nn36"></A>33.7.2 Tcl typemaps</H3> +<P> The previous section illustrated an "in" typemap for converting Tcl + objects to C. A variety of different typemap methods are defined by the + Tcl module. For example, to convert a C integer back into a Tcl object, + you might define an "out" typemap like this:</P> +<DIV class="code"> +<PRE> +%typemap(out) int { + Tcl_SetObjResult(interp,Tcl_NewIntObj($1)); +} +</PRE> +</DIV> +<P> The following list details all of the typemap methods that can be + used by the Tcl module:</P> +<P> <TT>%typemap(in)</TT></P> +<DIV class="indent"> Converts Tcl objects to input function arguments</DIV> +<P> <TT>%typemap(out)</TT></P> +<DIV class="indent"> Converts return value of a C function to a Tcl + object</DIV> +<P> <TT>%typemap(varin)</TT></P> +<DIV class="indent"> Assigns a C global variable from a Tcl object</DIV> +<P> <TT>%typemap(varout)</TT></P> +<DIV class="indent"> Returns a C global variable as a Tcl object</DIV> +<P> <TT>%typemap(freearg)</TT></P> +<DIV class="indent"> Cleans up a function argument (if necessary)</DIV> +<P> <TT>%typemap(argout)</TT></P> +<DIV class="indent"> Output argument processing</DIV> +<P> <TT>%typemap(ret)</TT></P> +<DIV class="indent"> Cleanup of function return values</DIV> +<P> <TT>%typemap(consttab)</TT></P> +<DIV class="indent"> Creation of Tcl constants (constant table)</DIV> +<P> <TT>%typemap(constcode)</TT></P> +<DIV class="indent"> Creation of Tcl constants (init function)</DIV> +<P> <TT>%typemap(memberin)</TT></P> +<DIV class="indent"> Setting of structure/class member data</DIV> +<P> <TT>%typemap(globalin)</TT></P> +<DIV class="indent"> Setting of C global variables</DIV> +<P> <TT>%typemap(check)</TT></P> +<DIV class="indent"> Checks function input values.</DIV> +<P> <TT>%typemap(default)</TT></P> +<DIV class="indent"> Set a default value for an argument (making it + optional).</DIV> +<P> <TT>%typemap(arginit)</TT></P> +<DIV class="indent"> Initialize an argument to a value before any + conversions occur.</DIV> +<P> Examples of these methods will appear shortly.</P> +<H3><A name="Tcl_nn37"></A>33.7.3 Typemap variables</H3> +<P> Within typemap code, a number of special variables prefaced with a <TT> +$</TT> may appear. A full list of variables can be found in the "<A href="#Typemaps"> +Typemaps</A>" chapter. This is a list of the most common variables:</P> +<P> <TT>$1</TT></P> +<DIV class="indent"> A C local variable corresponding to the actual type + specified in the <TT>%typemap</TT> directive. For input values, this is + a C local variable that's supposed to hold an argument value. For + output values, this is the raw result that's supposed to be returned to + Tcl.</DIV> +<P> <TT>$input</TT></P> +<DIV class="indent"> A <TT>Tcl_Obj *</TT> holding a raw Tcl object with + an argument or variable value.</DIV> +<P> <TT>$result</TT></P> +<DIV class="indent"> A <TT>Tcl_Obj *</TT> that holds the result to be + returned to Tcl.</DIV> +<P> <TT>$1_name</TT></P> +<DIV class="indent"> The parameter name that was matched.</DIV> +<P> <TT>$1_type</TT></P> +<DIV class="indent"> The actual C datatype matched by the typemap.</DIV> +<P> <TT>$1_ltype</TT></P> +<DIV class="indent"> An assignable version of the datatype matched by + the typemap (a type that can appear on the left-hand-side of a C + assignment operation). This type is stripped of qualifiers and may be + an altered version of <TT>$1_type</TT>. All arguments and local + variables in wrapper functions are declared using this type so that + their values can be properly assigned.</DIV> +<P> <TT>$symname</TT></P> +<DIV class="indent"> The Tcl name of the wrapper function being created.</DIV> +<H3><A name="Tcl_nn38"></A>33.7.4 Converting a Tcl list to a char **</H3> +<P> A common problem in many C programs is the processing of command + line arguments, which are usually passed in an array of NULL terminated + strings. The following SWIG interface file allows a Tcl list to be used + as a <TT>char **</TT> object.</P> +<DIV class="code"> +<PRE> +%module argv + +// This tells SWIG to treat char ** as a special case +%typemap(in) char ** { + Tcl_Obj **listobjv; + int nitems; + int i; + if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) { + return TCL_ERROR; + } + $1 = (char **) malloc((nitems+1)*sizeof(char *)); + for (i = 0; i < nitems; i++) { + $1[i] = Tcl_GetStringFromObj(listobjv[i],0); + } + $1[i] = 0; +} + +// This gives SWIG some cleanup code that will get called after the function call +%typemap(freearg) char ** { + if ($1) { + free($1); + } +} + +// Now a test functions +%inline %{ +int print_args(char **argv) { + int i = 0; + while (argv[i]) { + printf("argv[%d] = %s\n", i,argv[i]); + i++; + } + return i; +} +%} +%include "tclsh.i" + +</PRE> +</DIV> +<P> In Tcl:</P> +<DIV class="code"> +<PRE> +% print_args {John Guido Larry} +argv[0] = John +argv[1] = Guido +argv[2] = Larry +3 +</PRE> +</DIV> +<H3><A name="Tcl_nn39"></A>33.7.5 Returning values in arguments</H3> +<P> The "argout" typemap can be used to return a value originating from + a function argument. For example :</P> +<DIV class="code"> +<PRE> +// A typemap defining how to return an argument by appending it to the result +%typemap(argout) double *outvalue { + Tcl_Obj *o = Tcl_NewDoubleObj($1); + Tcl_ListObjAppendElement(interp,$result,o); +} + +// A typemap telling SWIG to ignore an argument for input +// However, we still need to pass a pointer to the C function +%typemap(in,numinputs=0) double *outvalue (double temp) { + $1 = &temp; +} + +// Now a function returning two values +int mypow(double a, double b, double *outvalue) { + if ((a < 0) || (b < 0)) return -1; + *outvalue = pow(a,b); + return 0; +}; +</PRE> +</DIV> +<P> When wrapped, SWIG matches the <TT>argout</TT> typemap to the "<TT> +double *outvalue</TT>" argument. The numinputs=0 specification tells + SWIG to simply ignore this argument when generating wrapper code. As a + result, a Tcl function using these typemaps will work like this :</P> +<DIV class="code"> +<PRE> +% mypow 2 3 # Returns two values, a status value and the result +0 8 +% +</PRE> +</DIV> +<H3><A name="Tcl_nn40"></A>33.7.6 Useful functions</H3> +<P> The following tables provide some functions that may be useful in + writing Tcl typemaps.</P> +<P><B> Integers</B></P> +<DIV class="code"> +<PRE> +Tcl_Obj *Tcl_NewIntObj(int Value); +void Tcl_SetIntObj(Tcl_Obj *obj, int Value); +int Tcl_GetIntFromObj(Tcl_Interp *, Tcl_Obj *obj, int *ip); +</PRE> +</DIV> +<P><B> Floating Point</B></P> +<DIV class="code"> +<PRE> +Tcl_Obj *Tcl_NewDoubleObj(double Value); +void Tcl_SetDoubleObj(Tcl_Obj *obj, double value); +int Tcl_GetDoubleFromObj(Tcl_Interp *, Tcl_Obj *o, double *dp); +</PRE> +</DIV> +<P><B> Strings</B></P> +<DIV class="code"> +<PRE> +Tcl_Obj *Tcl_NewStringObj(char *str, int len); +void Tcl_SetStringObj(Tcl_Obj *obj, char *str, int len); +char *Tcl_GetStringFromObj(Tcl_Obj *obj, int *len); +void Tcl_AppendToObj(Tcl_Obj *obj, char *str, int len); +</PRE> +</DIV> +<P><B> Lists</B></P> +<DIV class="code"> +<PRE> +Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *objv); +int Tcl_ListObjAppendList(Tcl_Interp *, Tcl_Obj *listPtr, Tcl_Obj *elemListPtr); +int Tcl_ListObjAppendElement(Tcl_Interp *, Tcl_Obj *listPtr, Tcl_Obj *element); +int Tcl_ListObjGetElements(Tcl_Interp *, Tcl_Obj *listPtr, int *objcPtr, + Tcl_Obj ***objvPtr); +int Tcl_ListObjLength(Tcl_Interp *, Tcl_Obj *listPtr, int *intPtr); +int Tcl_ListObjIndex(Tcl_Interp *, Tcl_Obj *listPtr, int index, + Tcl_Obj_Obj **objptr); +int Tcl_ListObjReplace(Tcl_Interp *, Tcl_Obj *listPtr, int first, int count, + int objc, Tcl_Obj *objv); +</PRE> +</DIV> +<P><B> Objects</B></P> +<DIV class="code"> +<PRE> +Tcl_Obj *Tcl_DuplicateObj(Tcl_Obj *obj); +void Tcl_IncrRefCount(Tcl_Obj *obj); +void Tcl_DecrRefCount(Tcl_Obj *obj); +int Tcl_IsShared(Tcl_Obj *obj); +</PRE> +</DIV> +<H3><A name="Tcl_nn41"></A>33.7.7 Standard typemaps</H3> +<P> The following typemaps show how to convert a few common kinds of + objects between Tcl and C (and to give a better idea of how typemaps + work)</P> +<P><B> Integer conversion</B></P> +<DIV class="code"> +<PRE> +%typemap(in) int, short, long { + int temp; + if (Tcl_GetIntFromObj(interp, $input, &temp) == TCL_ERROR) + return TCL_ERROR; + $1 = ($1_ltype) temp; +} +</PRE> +</DIV> +<BR><DIV class="code"> +<PRE> +%typemap(out) int, short, long { + Tcl_SetIntObj($result,(int) $1); +} +</PRE> +</DIV> +<P><B> Floating point conversion</B></P> +<DIV class="code"> +<PRE> +%typemap(in) float, double { + double temp; + if (Tcl_GetDoubleFromObj(interp, $input, &temp) == TCL_ERROR) + return TCL_ERROR; + $1 = ($1_ltype) temp; +} +</PRE> +</DIV> +<BR><DIV class="code"> +<PRE> +%typemap(out) float, double { + Tcl_SetDoubleObj($result, $1); +} +</PRE> +</DIV> +<P><B> String Conversion</B></P> +<DIV class="code"> +<PRE> +%typemap(in) char * { + int len; + $1 = Tcl_GetStringFromObj(interp, &len); + } +} +</PRE> +</DIV> +<BR><DIV class="code"> +<PRE> +%typemap(out) char * { + Tcl_SetStringObj($result,$1); +} +</PRE> +</DIV> +<H3><A name="Tcl_nn42"></A>33.7.8 Pointer handling</H3> +<P> SWIG pointers are mapped into Tcl strings containing the hexadecimal + value and type. The following functions can be used to create and read + pointer values.</P> +<P> <TT>int SWIG_ConvertPtr(Tcl_Obj *obj, void **ptr, swig_type_info + *ty, int flags)</TT></P> +<DIV class="indent"> Converts a Tcl object <TT>obj</TT> to a C pointer. + The result of the conversion is placed into the pointer located at <TT> +ptr</TT>. <TT>ty</TT> is a SWIG type descriptor structure. <TT>flags</TT> + is used to handle error checking and other aspects of conversion. It is + currently reserved for future expansion. Returns 0 on success and -1 on + error.</DIV> +<P> <TT>Tcl_Obj *SWIG_NewPointerObj(void *ptr, swig_type_info *ty, int + flags)</TT></P> +<DIV class="indent"> Creates a new Tcl pointer object. <TT>ptr</TT> is + the pointer to convert, <TT>ty</TT> is the SWIG type descriptor + structure that describes the type, and <TT>own</TT> is a flag reserved + for future expansion.</DIV> +<P> Both of these functions require the use of a special SWIG + type-descriptor structure. This structure contains information about + the mangled name of the datatype, type-equivalence information, as well + as information about converting pointer values under C++ inheritance. + For a type of <TT>Foo *</TT>, the type descriptor structure is usually + accessed as follows:</P> +<DIV class="indent"> +<PRE> +Foo *f; +if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL; + +Tcl_Obj *; +obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0); +</PRE> +</DIV> +<P> In a typemap, the type descriptor should always be accessed using + the special typemap variable <TT>$1_descriptor</TT>. For example:</P> +<DIV class="indent"> +<PRE> +%typemap(in) Foo * { + if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL; +} +</PRE> +</DIV> +<P> If necessary, the descriptor for any type can be obtained using the <TT> +$descriptor()</TT> macro in a typemap. For example:</P> +<DIV class="indent"> +<PRE> +%typemap(in) Foo * { + if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL; +} +</PRE> +</DIV> +<H2><A name="Tcl_nn43"></A>33.8 Turning a SWIG module into a Tcl + Package.</H2> +<P> Tcl 7.4 introduced the idea of an extension package. By default, + SWIG generates all of the code necessary to create a package. To set + the package version, simply use the <TT>-pkgversion</TT> option. For + example:</P> +<DIV class="code"> +<PRE> +% swig -tcl -pkgversion 2.3 example.i +</PRE> +</DIV> +<P> After building the SWIG generated module, you need to execute the "<TT> +pkg_mkIndex</TT>" command inside tclsh. For example :</P> +<DIV class="code"> +<PRE> +unix > tclsh +% pkg_mkIndex . example.so +% exit +</PRE> +</DIV> +<P> This creates a file "<TT>pkgIndex.tcl</TT>" with information about + the package. To use your package, you now need to move it to its own + subdirectory which has the same name as the package. For example :</P> +<DIV class="code"> +<PRE> +./example/ + pkgIndex.tcl # The file created by pkg_mkIndex + example.so # The SWIG generated module +</PRE> +</DIV> +<P> Finally, assuming that you're not entirely confused at this point, + make sure that the example subdirectory is visible from the directories + contained in either the <TT>tcl_library</TT> or <TT>auto_path</TT> + variables. At this point you're ready to use the package as follows :</P> +<DIV class="code"> +<PRE> +unix > tclsh +% package require example +% fact 4 +24 +% +</PRE> +</DIV> +<P> If you're working with an example in the current directory and this + doesn't work, do this instead :</P> +<DIV class="code"> +<PRE> +unix > tclsh +% lappend auto_path . +% package require example +% fact 4 +24 +</PRE> +</DIV> +<P> As a final note, most SWIG examples do not yet use the <TT>package</TT> + commands. For simple extensions it may be easier just to use the <TT> +load</TT> command instead.</P> +<H2><A name="Tcl_nn44"></A>33.9 Building new kinds of Tcl interfaces (in + Tcl)</H2> +<P> One of the most interesting aspects of Tcl and SWIG is that you can + create entirely new kinds of Tcl interfaces in Tcl using the low-level + SWIG accessor functions. For example, suppose you had a library of + helper functions to access arrays :</P> +<DIV class="code"> +<PRE> +/* File : array.i */ +%module array + +%inline %{ +double *new_double(int size) { + return (double *) malloc(size*sizeof(double)); +} +void delete_double(double *a) { + free(a); +} +double get_double(double *a, int index) { + return a[index]; +} +void set_double(double *a, int index, double val) { + a[index] = val; +} +int *new_int(int size) { + return (int *) malloc(size*sizeof(int)); +} +void delete_int(int *a) { + free(a); +} +int get_int(int *a, int index) { + return a[index]; +} +int set_int(int *a, int index, int val) { + a[index] = val; +} +%} + +</PRE> +</DIV> +<P> While these could be called directly, we could also write a Tcl + script like this :</P> +<DIV class="code"> +<PRE> +proc Array {type size} { + set ptr [new_$type $size] + set code { + set method [lindex $args 0] + set parms [concat $ptr [lrange $args 1 end]] + switch $method { + get {return [eval "get_$type $parms"]} + set {return [eval "set_$type $parms"]} + delete {eval "delete_$type $ptr; rename $ptr {}"} + } + } + # Create a procedure + uplevel "proc $ptr args {set ptr $ptr; set type $type;$code}" + return $ptr +} +</PRE> +</DIV> +<P> Our script allows easy array access as follows :</P> +<DIV class="code"> +<PRE> +set a [Array double 100] ;# Create a double [100] +for {set i 0} {$i < 100} {incr i 1} { ;# Clear the array + $a set $i 0.0 +} +$a set 3 3.1455 ;# Set an individual element +set b [$a get 10] ;# Retrieve an element + +set ia [Array int 50] ;# Create an int[50] +for {set i 0} {$i < 50} {incr i 1} { ;# Clear it + $ia set $i 0 +} +$ia set 3 7 ;# Set an individual element +set ib [$ia get 10] ;# Get an individual element + +$a delete ;# Destroy a +$ia delete ;# Destroy ia +</PRE> +</DIV> +<P> The cool thing about this approach is that it makes a common + interface for two different types of arrays. In fact, if we were to add + more C datatypes to our wrapper file, the Tcl code would work with + those as well--without modification. If an unsupported datatype was + requested, the Tcl code would simply return with an error so there is + very little danger of blowing something up (although it is easily + accomplished with an out of bounds array access).</P> +<H3><A name="Tcl_nn45"></A>33.9.1 Proxy classes</H3> +<P> A similar approach can be applied to proxy classes (also known as + shadow classes). The following example is provided by Erik Bierwagen + and Paul Saxe. To use it, run SWIG with the <TT>-noobject</TT> option + (which disables the builtin object oriented interface). When running + Tcl, simply source this file. Now, objects can be used in a more or + less natural fashion.</P> +<DIV class="code"> +<PRE> +# swig_c++.tcl +# Provides a simple object oriented interface using +# SWIG's low level interface. +# + +proc new {objectType handle_r args} { + # Creates a new SWIG object of the given type, + # returning a handle in the variable "handle_r". + # + # Also creates a procedure for the object and a trace on + # the handle variable that deletes the object when the + # handle variable is overwritten or unset + upvar $handle_r handle + # + # Create the new object + # + eval set handle \[new_$objectType $args\] + # + # Set up the object procedure + # + proc $handle {cmd args} "eval ${objectType}_\$cmd $handle \$args" + # + # And the trace ... + # + uplevel trace variable $handle_r uw "{deleteObject $objectType $handle}" + # + # Return the handle so that 'new' can be used as an argument to a procedure + # + return $handle +} + +proc deleteObject {objectType handle name element op} { + # + # Check that the object handle has a reasonable form + # + if {![regexp {_[0-9a-f]*_(.+)_p} $handle]} { + error "deleteObject: not a valid object handle: $handle" + } + # + # Remove the object procedure + # + catch {rename $handle {}} + # + # Delete the object + # + delete_$objectType $handle +} + +proc delete {handle_r} { + # + # A synonym for unset that is more familiar to C++ programmers + # + uplevel unset $handle_r +} +</PRE> +</DIV> +<P> To use this file, we simply source it and execute commands such as + "new" and "delete" to manipulate objects. For example :</P> +<DIV class="code"> +<PRE> +// list.i +%module List +%{ +#include "list.h" +%} + +// Very simple C++ example + +class List { +public: + List(); // Create a new list + ~List(); // Destroy a list + int search(char *value); + void insert(char *); // Insert a new item into the list + void remove(char *); // Remove item from list + char *get(int n); // Get the nth item in the list + int length; // The current length of the list +static void print(List *l); // Print out the contents of the list +}; +</PRE> +</DIV> +<P> Now a Tcl script using the interface...</P> +<DIV class="code"> +<PRE> +load ./list.so list ; # Load the module +source swig_c++.tcl ; # Source the object file + +new List l +$l insert Dave +$l insert John +$l insert Guido +$l remove Dave +puts $l length_get + +delete l +</PRE> +</DIV> +<P> The cool thing about this example is that it works with any C++ + object wrapped by SWIG and requires no special compilation. Proof that + a short, but clever Tcl script can be combined with SWIG to do many + interesting things.</P> +<H2><A name="Tcl_nn46"></A>33.10 Tcl/Tk Stubs</H2> +<P> For background information about the Tcl Stubs feature, see <A href="http://www.tcl.tk/doc/howto/stubs.html"> +http://www.tcl.tk/doc/howto/stubs.html</A>.</P> +<P> As of SWIG 1.3.10, the generated C/C++ wrapper will use the Tcl + Stubs feature if compiled with <TT>-DUSE_TCL_STUBS</TT>.</P> +<P> As of SWIG 1.3.40, the generated C/C++ wrapper will use the Tk Stubs + feature if compiled with <TT>-DUSE_TK_STUBS</TT>. Also, you can + override the minimum version to support which is passed to <TT> +Tcl_InitStubs()</TT> and <TT>Tk_InitStubs()</TT> with <TT> +-DSWIG_TCL_STUBS_VERSION="8.3"</TT> or the version being compiled with + using <TT>-DSWIG_TCL_STUBS_VERSION=TCL_VERSION</TT>.</P> +<HR NOSHADE> +<H1><A name="R"></A>34 SWIG and R</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#R_nn2">Bugs</A></LI> +<LI><A href="#R_nn3">Using R and SWIG</A></LI> +<LI><A href="#R_nn4">Precompiling large R files</A></LI> +<LI><A href="#R_nn5">General policy</A></LI> +<LI><A href="#R_language_conventions">Language conventions</A></LI> +<LI><A href="#R_nn6">C++ classes</A></LI> +<LI><A href="#R_nn7">Enumerations</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<P> R is a GPL'ed open source statistical and plotting environment. + Information about R can be found at <A href="http://www.r-project.org/"> +www.r-project.org</A>. The R bindings are under active development. They + have been used to compile and run an R interface to QuantLib running on + Mandriva Linux with gcc. The R bindings also work on Microsoft Windows + using Visual C++.</P> +<H2><A name="R_nn2"></A>34.1 Bugs</H2> +<P> Currently the following features are not implemented or broken:</P> +<UL> +<LI>Garbage collection of created objects</LI> +<LI>C Array wrappings</LI> +</UL> +<H2><A name="R_nn3"></A>34.2 Using R and SWIG</H2> +<P> To use R and SWIG in C mode, execute the following commands where + example.c is the name of the file with the functions in them</P> +<DIV class="shell"> +<PRE> +swig -r example.i +PKG_LIBS="example.c" R CMD SHLIB example_wrap.c +</PRE> +</DIV> +<P> The corresponding comments for C++ mode are</P> +<DIV class="shell"> +<PRE> +swig -c++ -r -o example_wrap.cpp example.i +PKG_LIBS="example.cxx" R CMD SHLIB example_wrap.cpp +</PRE> +</DIV> +<P> Note that R is sensitive to the name of the file and to the file + extension in C and C++ mode. The name of the wrapper file must be the + name of the library. Also in C++ mode, the file extension must be .cpp + rather than .cxx for the R compile command to recognize it.</P> +<P> The commands produces two files. A dynamic shared object file called + example.so, or example.dll, and an R wrapper file called example.R. To + load these files, start up R and type in the following commands</P> +<DIV class="shell"> +<PRE> +dyn.load(paste("example", .Platform$dynlib.ext, sep="")) +source("example.R") +cacheMetaData(1) +</PRE> +</DIV> The cacheMetaData(1) will cause R to refresh its object tables. + Without it, inheritance of wrapped objects may fail. +<P> These two files can be loaded in any order</P> +<H2><A name="R_nn4"></A>34.3 Precompiling large R files</H2> + In cases where the R file is large, one make save a lot of loading time + by precompiling the R wrapper. This can be done by creating the file + makeRData.R which contains the following +<PRE> +source('BigFile.R') +save(list=ls(all=TRUE),file="BigFile.RData", compress=TRUE) +q(save="no") +</PRE> + This will generate a compiled R file called BigFile.RData that will + save a large amount of loading time. +<H2><A name="R_nn5"></A>34.4 General policy</H2> +<P> The general policy of the module is to treat the C/C++ as a basic + wrapping over the underlying functions and rely on the R type system to + provide R syntax.</P> +<H2><A name="R_language_conventions"></A>34.5 Language conventions</H2> +<P> getitem and setitem use C++ conventions (i.e. zero based indices). [ +<!--- +and [ are overloaded to allow for R syntax (one based indices and +slices) +</p--> +</P> +<H2><A name="R_nn6"></A>34.6 C++ classes</H2> +<P> C++ objects are implemented as external pointer objects with the + class being the mangled name of the class. The C++ classes are + encapsulated as an SEXP with an external pointer type. The class is the + mangled name of the class. The nice thing about R is that is allows you + to keep track of the pointer object which removes the necessity for a + lot of the proxy class baggage you see in other languages.</P> +<H2><A name="R_nn7"></A>34.7 Enumerations</H2> +<P> enumerations are characters which are then converted back and forth + to ints before calling the C routines. All of the enumeration code is + done in R.</P> +<HR NOSHADE> +<H1><A name="Extending"></A>35 Extending SWIG to support new languages</H1> + +<!-- INDEX --> +<DIV class="sectiontoc"> +<UL> +<LI><A href="#Extending_nn2">Introduction</A></LI> +<LI><A href="#Extending_nn3">Prerequisites</A></LI> +<LI><A href="#Extending_nn4">The Big Picture</A></LI> +<LI><A href="#Extending_nn5">Execution Model</A> +<UL> +<LI><A href="#Extending_nn6">Preprocessing</A></LI> +<LI><A href="#Extending_nn7">Parsing</A></LI> +<LI><A href="#Extending_nn8">Parse Trees</A></LI> +<LI><A href="#Extending_nn9">Attribute namespaces</A></LI> +<LI><A href="#Extending_nn10">Symbol Tables</A></LI> +<LI><A href="#Extending_nn11">The %feature directive</A></LI> +<LI><A href="#Extending_nn12">Code Generation</A></LI> +<LI><A href="#Extending_nn13">SWIG and XML</A></LI> +</UL> +</LI> +<LI><A href="#Extending_nn14">Primitive Data Structures</A> +<UL> +<LI><A href="#Extending_nn15">Strings</A></LI> +<LI><A href="#Extending_nn16">Hashes</A></LI> +<LI><A href="#Extending_nn17">Lists</A></LI> +<LI><A href="#Extending_nn18">Common operations</A></LI> +<LI><A href="#Extending_nn19">Iterating over Lists and Hashes</A></LI> +<LI><A href="#Extending_nn20">I/O</A></LI> +</UL> +</LI> +<LI><A href="#Extending_nn21">Navigating and manipulating parse trees</A> +</LI> +<LI><A href="#Extending_nn22">Working with attributes</A></LI> +<LI><A href="#Extending_nn23">Type system</A> +<UL> +<LI><A href="#Extending_nn24">String encoding of types</A></LI> +<LI><A href="#Extending_nn25">Type construction</A></LI> +<LI><A href="#Extending_nn26">Type tests</A></LI> +<LI><A href="#Extending_nn27">Typedef and inheritance</A></LI> +<LI><A href="#Extending_nn28">Lvalues</A></LI> +<LI><A href="#Extending_nn29">Output functions</A></LI> +</UL> +</LI> +<LI><A href="#Extending_nn30">Parameters</A></LI> +<LI><A href="#Extending_nn31">Writing a Language Module</A> +<UL> +<LI><A href="#Extending_nn32">Execution model</A></LI> +<LI><A href="#Extending_nn33">Starting out</A></LI> +<LI><A href="#Extending_nn34">Command line options</A></LI> +<LI><A href="#Extending_nn35">Configuration and preprocessing</A></LI> +<LI><A href="#Extending_nn36">Entry point to code generation</A></LI> +<LI><A href="#Extending_nn37">Module I/O and wrapper skeleton</A></LI> +<LI><A href="#Extending_nn38">Low-level code generators</A></LI> +<LI><A href="#Extending_nn39">Configuration files</A></LI> +<LI><A href="#Extending_nn40">Runtime support</A></LI> +<LI><A href="#Extending_nn41">Standard library files</A></LI> +<LI><A href="#Extending_nn42">Examples and test cases</A></LI> +<LI><A href="#Extending_nn43">Documentation</A></LI> +<LI><A href="#Extending_prerequisites">Prerequisites for adding a new + language module to the SWIG distribution</A></LI> +<LI><A href="#Extending_coding_style_guidelines">Coding style guidelines</A> +</LI> +</UL> +</LI> +<LI><A href="#Extending_nn44">Typemaps</A> +<UL> +<LI><A href="#Extending_nn45">Proxy classes</A></LI> +</UL> +</LI> +<LI><A href="#Extending_nn46">Guide to parse tree nodes</A></LI> +</UL> +</DIV> +<!-- INDEX --> +<H2><A name="Extending_nn2"></A>35.1 Introduction</H2> +<P> This chapter describes SWIG's internal organization and the process + by which new target languages can be developed. First, a brief word of + warning---SWIG is continually evolving. The information in this chapter + is mostly up to date, but changes are ongoing. Expect a few + inconsistencies.</P> +<P> Also, this chapter is not meant to be a hand-holding tutorial. As a + starting point, you should probably look at one of SWIG's existing + modules.</P> +<H2><A name="Extending_nn3"></A>35.2 Prerequisites</H2> +<P> In order to extend SWIG, it is useful to have the following + background:</P> +<UL> +<LI>An understanding of the C API for the target language.</LI> +<LI>A good grasp of the C++ type system.</LI> +<LI>An understanding of typemaps and some of SWIG's advanced features.</LI> +<LI>Some familiarity with writing C++ (language modules are currently + written in C++).</LI> +</UL> +<P> Since SWIG is essentially a specialized C++ compiler, it may be + useful to have some prior experience with compiler design (perhaps even + a compilers course) to better understand certain parts of the system. A + number of books will also be useful. For example, "The C Programming + Language" by Kernighan and Ritchie (a.k.a, "K&R") and the C++ standard, + "ISO/IEC 14882 Programming Languages - C++" will be of great use.</P> +<P> Also, it is useful to keep in mind that SWIG primarily operates as + an extension of the C++<EM> type</EM> system. At first glance, this + might not be obvious, but almost all SWIG directives as well as the + low-level generation of wrapper code are driven by C++ datatypes.</P> +<H2><A name="Extending_nn4"></A>35.3 The Big Picture</H2> +<P> SWIG is a special purpose compiler that parses C++ declarations to + generate wrapper code. To make this conversion possible, SWIG makes + three fundamental extensions to the C++ language:</P> +<UL> +<LI><B>Typemaps</B>. Typemaps are used to define the + conversion/marshalling behavior of specific C++ datatypes. All type + conversion in SWIG is based on typemaps. Furthermore, the association + of typemaps to datatypes utilizes an advanced pattern matching + mechanism that is fully integrated with the C++ type system.</LI> +<LI><B>Declaration Annotation</B>. To customize wrapper code generation, + most declarations can be annotated with special features. For example, + you can make a variable read-only, you can ignore a declaration, you + can rename a member function, you can add exception handling, and so + forth. Virtually all of these customizations are built on top of a + low-level declaration annotator that can attach arbitrary attributes to + any declaration. Code generation modules can look for these attributes + to guide the wrapping process.</LI> +<LI><B>Class extension</B>. SWIG allows classes and structures to be + extended with new methods and attributes (the <TT>%extend</TT> + directive). This has the effect of altering the API in the target + language and can be used to generate OO interfaces to C libraries.</LI> +</UL> +<P> It is important to emphasize that virtually all SWIG features reduce + to one of these three fundamental concepts. The type system and pattern + matching rules also play a critical role in making the system work. For + example, both typemaps and declaration annotation are based on pattern + matching and interact heavily with the underlying type system.</P> +<H2><A name="Extending_nn5"></A>35.4 Execution Model</H2> +<P> When you run SWIG on an interface, processing is handled in stages + by a series of system components:</P> +<UL> +<LI>An integrated C preprocessor reads a collection of configuration + files and the specified interface file into memory. The preprocessor + performs the usual functions including macro expansion and file + inclusion. However, the preprocessor also performs some transformations + of the interface. For instance, <TT>#define</TT> statements are + sometimes transformed into <TT>%constant</TT> declarations. In + addition, information related to file/line number tracking is inserted.</LI> +<LI>A C/C++ parser reads the preprocessed input and generates a full + parse tree of all of the SWIG directives and C declarations found. The + parser is responsible for many aspects of the system including + renaming, declaration annotation, and template expansion. However, the + parser does not produce any output nor does it interact with the target + language module as it runs. SWIG is not a one-pass compiler.</LI> +<LI>A type-checking pass is made. This adjusts all of the C++ typenames + to properly handle namespaces, typedefs, nested classes, and other + issues related to type scoping.</LI> +<LI>A semantic pass is made on the parse tree to collect information + related to properties of the C++ interface. For example, this pass + would determine whether or not a class allows a default constructor.</LI> +<LI>A code generation pass is made using a specific target language + module. This phase is responsible for generating the actual wrapper + code. All of SWIG's user-defined modules are invoked during this latter + stage of compilation.</LI> +</UL> +<P> The next few sections briefly describe some of these stages.</P> +<H3><A name="Extending_nn6"></A>35.4.1 Preprocessing</H3> +<P> The preprocessor plays a critical role in the SWIG implementation. + This is because a lot of SWIG's processing and internal configuration + is managed not by code written in C, but by configuration files in the + SWIG library. In fact, when you run SWIG, parsing starts with a small + interface file like this (note: this explains the cryptic error + messages that new users sometimes get when SWIG is misconfigured or + installed incorrectly):</P> +<DIV class="code"> +<PRE> +%include "swig.swg" // Global SWIG configuration +%include "<EM>langconfig.swg</EM>" // Language specific configuration +%include "yourinterface.i" // Your interface file +</PRE> +</DIV> +<P> The <TT>swig.swg</TT> file contains global configuration + information. In addition, this file defines many of SWIG's standard + directives as macros. For instance, part of of <TT>swig.swg</TT> looks + like this:</P> +<DIV class="code"> +<PRE> +... +/* Code insertion directives such as %wrapper %{ ... %} */ + +#define %begin %insert("begin") +#define %runtime %insert("runtime") +#define %header %insert("header") +#define %wrapper %insert("wrapper") +#define %init %insert("init") + +/* Access control directives */ + +#define %immutable %feature("immutable","1") +#define %mutable %feature("immutable") + +/* Directives for callback functions */ + +#define %callback(x) %feature("callback") `x`; +#define %nocallback %feature("callback"); + +/* %ignore directive */ + +#define %ignore %rename($ignore) +#define %ignorewarn(x) %rename("$ignore:" x) +... +</PRE> +</DIV> +<P> The fact that most of the standard SWIG directives are macros is + intended to simplify the implementation of the internals. For instance, + rather than having to support dozens of special directives, it is + easier to have a few basic primitives such as <TT>%feature</TT> or <TT> +%insert</TT>.</P> +<P> The<EM> <TT>langconfig.swg</TT></EM> file is supplied by the target + language. This file contains language-specific configuration + information. More often than not, this file provides run-time wrapper + support code (e.g., the type-checker) as well as a collection of + typemaps that define the default wrapping behavior. Note: the name of + this file depends on the target language and is usually something like <TT> +python.swg</TT> or <TT>perl5.swg</TT>.</P> +<P> As a debugging aide, the text that SWIG feeds to its C++ parser can + be obtained by running <TT>swig -E interface.i</TT>. This output + probably isn't too useful in general, but it will show how macros have + been expanded as well as everything else that goes into the low-level + construction of the wrapper code.</P> +<H3><A name="Extending_nn7"></A>35.4.2 Parsing</H3> +<P> The current C++ parser handles a subset of C++. Most + incompatibilities with C are due to subtle aspects of how SWIG parses + declarations. Specifically, SWIG expects all C/C++ declarations to + follow this general form:</P> +<DIV class="diagram"> +<PRE> +<EM>storage</EM> <EM>type</EM> <EM>declarator</EM> <EM>initializer</EM>; +</PRE> +</DIV> +<P> <TT><EM>storage</EM></TT> is a keyword such as <TT>extern</TT>, <TT> +static</TT>, <TT>typedef</TT>, or <TT>virtual</TT>. <TT><EM>type</EM></TT> + is a primitive datatype such as <TT>int</TT> or <TT>void</TT>. <TT><EM> +type</EM></TT> may be optionally qualified with a qualifier such as <TT> +const</TT> or <TT>volatile</TT>. <TT><EM>declarator</EM></TT> is a name + with additional type-construction modifiers attached to it (pointers, + arrays, references, functions, etc.). Examples of declarators include <TT> +*x</TT>, <TT>**x</TT>, <TT>x[20]</TT>, and <TT>(*x)(int,double)</TT>. + The <TT><EM>initializer</EM></TT> may be a value assigned using <TT>=</TT> + or body of code enclosed in braces <TT>{ ... }</TT>.</P> +<P> This declaration format covers most common C++ declarations. + However, the C++ standard is somewhat more flexible in the placement of + the parts. For example, it is technically legal, although uncommon to + write something like <TT>int typedef const a</TT> in your program. SWIG + simply doesn't bother to deal with this case.</P> +<P> The other significant difference between C++ and SWIG is in the + treatment of typenames. In C++, if you have a declaration like this,</P> +<DIV class="code"> +<PRE> +int blah(Foo *x, Bar *y); +</PRE> +</DIV> +<P> it won't parse correctly unless <TT>Foo</TT> and <TT>Bar</TT> have + been previously defined as types either using a <TT>class</TT> + definition or a <TT>typedef</TT>. The reasons for this are subtle, but + this treatment of typenames is normally integrated at the level of the + C tokenizer---when a typename appears, a different token is returned to + the parser instead of an identifier.</P> +<P> SWIG does not operate in this manner--any legal identifier can be + used as a type name. The reason for this is primarily motivated by the + use of SWIG with partially defined data. Specifically, SWIG is supposed + to be easy to use on interfaces with missing type information.</P> +<P> Because of the different treatment of typenames, the most serious + limitation of the SWIG parser is that it can't process type + declarations where an extra (and unnecessary) grouping operator is + used. For example:</P> +<DIV class="code"> +<PRE> +int (x); /* A variable x */ +int (y)(int); /* A function y */ +</PRE> +</DIV> +<P> The placing of extra parentheses in type declarations like this is + already recognized by the C++ community as a potential source of + strange programming errors. For example, Scott Meyers "Effective STL" + discusses this problem in a section on avoiding C++'s "most vexing + parse."</P> +<P> The parser is also unable to handle declarations with no return type + or bare argument names. For example, in an old C program, you might see + things like this:</P> +<DIV class="code"> +<PRE> +foo(a,b) { +... +} +</PRE> +</DIV> +<P> In this case, the return type as well as the types of the arguments + are taken by the C compiler to be an <TT>int</TT>. However, SWIG + interprets the above code as an abstract declarator for a function + returning a <TT>foo</TT> and taking types <TT>a</TT> and <TT>b</TT> as + arguments).</P> +<H3><A name="Extending_nn8"></A>35.4.3 Parse Trees</H3> +<P> The SWIG parser produces a complete parse tree of the input file + before any wrapper code is actually generated. Each item in the tree is + known as a "Node". Each node is identified by a symbolic tag. + Furthermore, a node may have an arbitrary number of children. The parse + tree structure and tag names of an interface can be displayed using <TT> +swig -debug-tags</TT>. For example:</P> +<DIV class="shell"> +<PRE> +$ <B>swig -c++ -python -debug-tags example.i</B> + . top (example.i:1) + . top . include (example.i:1) + . top . include . typemap (/r0/beazley/Projects/lib/swig1.3/swig.swg:71) + . top . include . typemap . typemapitem (/r0/beazley/Projects/lib/swig1.3/swig.swg:71) + . top . include . typemap (/r0/beazley/Projects/lib/swig1.3/swig.swg:83) + . top . include . typemap . typemapitem (/r0/beazley/Projects/lib/swig1.3/swig.swg:83) + . top . include (example.i:4) + . top . include . insert (/r0/beazley/Projects/lib/swig1.3/python/python.swg:7) + . top . include . insert (/r0/beazley/Projects/lib/swig1.3/python/python.swg:8) + . top . include . typemap (/r0/beazley/Projects/lib/swig1.3/python/python.swg:19) +... + . top . include (example.i:6) + . top . include . module (example.i:2) + . top . include . insert (example.i:6) + . top . include . include (example.i:9) + . top . include . include . class (example.h:3) + . top . include . include . class . access (example.h:4) + . top . include . include . class . constructor (example.h:7) + . top . include . include . class . destructor (example.h:10) + . top . include . include . class . cdecl (example.h:11) + . top . include . include . class . cdecl (example.h:11) + . top . include . include . class . cdecl (example.h:12) + . top . include . include . class . cdecl (example.h:13) + . top . include . include . class . cdecl (example.h:14) + . top . include . include . class . cdecl (example.h:15) + . top . include . include . class (example.h:18) + . top . include . include . class . access (example.h:19) + . top . include . include . class . cdecl (example.h:20) + . top . include . include . class . access (example.h:21) + . top . include . include . class . constructor (example.h:22) + . top . include . include . class . cdecl (example.h:23) + . top . include . include . class . cdecl (example.h:24) + . top . include . include . class (example.h:27) + . top . include . include . class . access (example.h:28) + . top . include . include . class . cdecl (example.h:29) + . top . include . include . class . access (example.h:30) + . top . include . include . class . constructor (example.h:31) + . top . include . include . class . cdecl (example.h:32) + . top . include . include . class . cdecl (example.h:33) +</PRE> +</DIV> +<P> Even for the most simple interface, the parse tree structure is + larger than you might expect. For example, in the above output, a + substantial number of nodes are actually generated by the <TT> +python.swg</TT> configuration file which defines typemaps and other + directives. The contents of the user-supplied input file don't appear + until the end of the output.</P> +<P> The contents of each parse tree node consist of a collection of + attribute/value pairs. Internally, the nodes are simply represented by + hash tables. A display of the entire parse-tree structure can be + obtained using <TT>swig -debug-top <n></TT>, where <TT>n</TT> is the + stage being processed. There are a number of other parse tree display + options, for example, <TT>swig -debug-module <n></TT> will avoid + displaying system parse information and only display the parse tree + pertaining to the user's module at stage <TT>n</TT> of processing.</P> +<DIV class="shell"> +<PRE> +$ swig -c++ -python -debug-module 4 example.i + +++ include ---------------------------------------- + | name - "example.i" + + +++ module ---------------------------------------- + | name - "example" + | + +++ insert ---------------------------------------- + | code - "\n#include \"example.h\"\n" + | + +++ include ---------------------------------------- + | name - "example.h" + + +++ class ---------------------------------------- + | abstract - "1" + | sym:name - "Shape" + | name - "Shape" + | kind - "class" + | symtab - 0x40194140 + | sym:symtab - 0x40191078 + + +++ access ---------------------------------------- + | kind - "public" + | + +++ constructor ---------------------------------------- + | sym:name - "Shape" + | name - "Shape" + | decl - "f()." + | code - "{\n nshapes++;\n }" + | sym:symtab - 0x40194140 + | + +++ destructor ---------------------------------------- + | sym:name - "~Shape" + | name - "~Shape" + | storage - "virtual" + | code - "{\n nshapes--;\n }" + | sym:symtab - 0x40194140 + | + +++ cdecl ---------------------------------------- + | sym:name - "x" + | name - "x" + | decl - "" + | type - "double" + | sym:symtab - 0x40194140 + | + +++ cdecl ---------------------------------------- + | sym:name - "y" + | name - "y" + | decl - "" + | type - "double" + | sym:symtab - 0x40194140 + | + +++ cdecl ---------------------------------------- + | sym:name - "move" + | name - "move" + | decl - "f(double,double)." + | parms - double ,double + | type - "void" + | sym:symtab - 0x40194140 + | + +++ cdecl ---------------------------------------- + | sym:name - "area" + | name - "area" + | decl - "f(void)." + | parms - void + | storage - "virtual" + | value - "0" + | type - "double" + | sym:symtab - 0x40194140 + | + +++ cdecl ---------------------------------------- + | sym:name - "perimeter" + | name - "perimeter" + | decl - "f(void)." + | parms - void + | storage - "virtual" + | value - "0" + | type - "double" + | sym:symtab - 0x40194140 + | + +++ cdecl ---------------------------------------- + | sym:name - "nshapes" + | name - "nshapes" + | decl - "" + | storage - "static" + | type - "int" + | sym:symtab - 0x40194140 + | + +++ class ---------------------------------------- + | sym:name - "Circle" + | name - "Circle" + | kind - "class" + | bases - 0x40194510 + | symtab - 0x40194538 + | sym:symtab - 0x40191078 + + +++ access ---------------------------------------- + | kind - "private" + | + +++ cdecl ---------------------------------------- + | name - "radius" + | decl - "" + | type - "double" + | + +++ access ---------------------------------------- + | kind - "public" + | + +++ constructor ---------------------------------------- + | sym:name - "Circle" + | name - "Circle" + | parms - double + | decl - "f(double)." + | code - "{ }" + | sym:symtab - 0x40194538 + | + +++ cdecl ---------------------------------------- + | sym:name - "area" + | name - "area" + | decl - "f(void)." + | parms - void + | storage - "virtual" + | type - "double" + | sym:symtab - 0x40194538 + | + +++ cdecl ---------------------------------------- + | sym:name - "perimeter" + | name - "perimeter" + | decl - "f(void)." + | parms - void + | storage - "virtual" + | type - "double" + | sym:symtab - 0x40194538 + | + +++ class ---------------------------------------- + | sym:name - "Square" + | name - "Square" + | kind - "class" + | bases - 0x40194760 + | symtab - 0x40194788 + | sym:symtab - 0x40191078 + + +++ access ---------------------------------------- + | kind - "private" + | + +++ cdecl ---------------------------------------- + | name - "width" + | decl - "" + | type - "double" + | + +++ access ---------------------------------------- + | kind - "public" + | + +++ constructor ---------------------------------------- + | sym:name - "Square" + | name - "Square" + | parms - double + | decl - "f(double)." + | code - "{ }" + | sym:symtab - 0x40194788 + | + +++ cdecl ---------------------------------------- + | sym:name - "area" + | name - "area" + | decl - "f(void)." + | parms - void + | storage - "virtual" + | type - "double" + | sym:symtab - 0x40194788 + | + +++ cdecl ---------------------------------------- + | sym:name - "perimeter" + | name - "perimeter" + | decl - "f(void)." + | parms - void + | storage - "virtual" + | type - "double" + | sym:symtab - 0x40194788 +</PRE> +</DIV> +<H3><A name="Extending_nn9"></A>35.4.4 Attribute namespaces</H3> +<P> Attributes of parse tree nodes are often prepended with a namespace + qualifier. For example, the attributes <TT>sym:name</TT> and <TT> +sym:symtab</TT> are attributes related to symbol table management and + are prefixed with <TT>sym:</TT>. As a general rule, only those + attributes which are directly related to the raw declaration appear + without a prefix (type, name, declarator, etc.).</P> +<P> Target language modules may add additional attributes to nodes to + assist the generation of wrapper code. The convention for doing this is + to place these attributes in a namespace that matches the name of the + target language. For example, <TT>python:foo</TT> or <TT>perl:foo</TT>.</P> +<H3><A name="Extending_nn10"></A>35.4.5 Symbol Tables</H3> +<P> During parsing, all symbols are managed in the space of the target + language. The <TT>sym:name</TT> attribute of each node contains the + symbol name selected by the parser. Normally, <TT>sym:name</TT> and <TT> +name</TT> are the same. However, the <TT>%rename</TT> directive can be + used to change the value of <TT>sym:name</TT>. You can see the effect + of <TT>%rename</TT> by trying it on a simple interface and dumping the + parse tree. For example:</P> +<DIV class="code"> +<PRE> +%rename(foo_i) foo(int); +%rename(foo_d) foo(double); + +void foo(int); +void foo(double); +void foo(Bar *b); +</PRE> +</DIV> +<P> There are various <TT>debug-</TT> options that can be useful for + debugging and analysing the parse tree. For example, the <TT>debug-top + <n></TT> or <TT>debug-module <n></TT> options will dump the entire/top + of the parse tree or the module subtree at one of the four <TT>n</TT> + stages of processing. The parse tree can be viewed after the final + stage of processing by running SWIG:</P> +<DIV class="shell"> +<PRE> +$ swig -debug-top 4 example.i +... + +++ cdecl ---------------------------------------- + | sym:name - "foo_i" + | name - "foo" + | decl - "f(int)." + | parms - int + | type - "void" + | sym:symtab - 0x40165078 + | + +++ cdecl ---------------------------------------- + | sym:name - "foo_d" + | name - "foo" + | decl - "f(double)." + | parms - double + | type - "void" + | sym:symtab - 0x40165078 + | + +++ cdecl ---------------------------------------- + | sym:name - "foo" + | name - "foo" + | decl - "f(p.Bar)." + | parms - Bar * + | type - "void" + | sym:symtab - 0x40165078 +</PRE> +</DIV> +<P> All symbol-related conflicts and complaints about overloading are + based on <TT>sym:name</TT> values. For instance, the following example + uses <TT>%rename</TT> in reverse to generate a name clash.</P> +<DIV class="code"> +<PRE> +%rename(foo) foo_i(int); +%rename(foo) foo_d(double; + +void foo_i(int); +void foo_d(double); +void foo(Bar *b); +</PRE> +</DIV> +<P> When you run SWIG on this you now get:</P> +<DIV class="shell"> +<PRE> +$ ./swig example.i +example.i:6. Overloaded declaration ignored. foo_d(double ) +example.i:5. Previous declaration is foo_i(int ) +example.i:7. Overloaded declaration ignored. foo(Bar *) +example.i:5. Previous declaration is foo_i(int ) +</PRE> +</DIV> +<H3><A name="Extending_nn11"></A>35.4.6 The %feature directive</H3> +<P> A number of SWIG directives such as <TT>%exception</TT> are + implemented using the low-level <TT>%feature</TT> directive. For + example:</P> +<DIV class="code"> +<PRE> +%feature("except") getitem(int) { + try { + $action + } catch (badindex) { + ... + } +} + +... +class Foo { +public: + Object *getitem(int index) throws(badindex); + ... +}; +</PRE> +</DIV> +<P> The behavior of <TT>%feature</TT> is very easy to describe--it + simply attaches a new attribute to any parse tree node that matches the + given prototype. When a feature is added, it shows up as an attribute + in the <TT>feature:</TT> namespace. You can see this when running with + the <TT>-debug-top 4</TT> option. For example:</P> +<DIV class="shell"> +<PRE> + +++ cdecl ---------------------------------------- + | sym:name - "getitem" + | name - "getitem" + | decl - "f(int).p." + | parms - int + | type - "Object" + | feature:except - "{\n try {\n $action\n } catc..." + | sym:symtab - 0x40168ac8 + | +</PRE> +</DIV> +<P> Feature names are completely arbitrary and a target language module + can be programmed to respond to any feature name that it wants to + recognize. The data stored in a feature attribute is usually just a raw + unparsed string. For example, the exception code above is simply stored + without any modifications.</P> +<H3><A name="Extending_nn12"></A>35.4.7 Code Generation</H3> +<P> Language modules work by defining handler functions that know how to + respond to different types of parse-tree nodes. These handlers simply + look at the attributes of each node in order to produce low-level code.</P> +<P> In reality, the generation of code is somewhat more subtle than + simply invoking handler functions. This is because parse-tree nodes + might be transformed. For example, suppose you are wrapping a class + like this:</P> +<DIV class="code"> +<PRE> +class Foo { +public: + virtual int *bar(int x); +}; +</PRE> +</DIV> +<P> When the parser constructs a node for the member <TT>bar</TT>, it + creates a raw "cdecl" node with the following attributes:</P> +<DIV class="diagram"> +<PRE> +nodeType : cdecl +name : bar +type : int +decl : f(int).p +parms : int x +storage : virtual +sym:name : bar +</PRE> +</DIV> +<P> To produce wrapper code, this "cdecl" node undergoes a number of + transformations. First, the node is recognized as a function + declaration. This adjusts some of the type information--specifically, + the declarator is joined with the base datatype to produce this:</P> +<DIV class="diagram"> +<PRE> +nodeType : cdecl +name : bar +type : p.int <-- Notice change in return type +decl : f(int).p +parms : int x +storage : virtual +sym:name : bar +</PRE> +</DIV> +<P> Next, the context of the node indicates that the node is really a + member function. This produces a transformation to a low-level accessor + function like this:</P> +<DIV class="diagram"> +<PRE> +nodeType : cdecl +name : bar +type : int.p +decl : f(int).p +parms : Foo *self, int x <-- Added parameter +storage : virtual +wrap:action : result = (arg1)->bar(arg2) <-- Action code added +sym:name : Foo_bar <-- Symbol name changed +</PRE> +</DIV> +<P> In this transformation, notice how an additional parameter was added + to the parameter list and how the symbol name of the node has suddenly + changed into an accessor using the naming scheme described in the "SWIG + Basics" chapter. A small fragment of "action" code has also been + generated--notice how the <TT>wrap:action</TT> attribute defines the + access to the underlying method. The data in this transformed node is + then used to generate a wrapper.</P> +<P> Language modules work by registering handler functions for dealing + with various types of nodes at different stages of transformation. This + is done by inheriting from a special <TT>Language</TT> class and + defining a collection of virtual methods. For example, the Python + module defines a class as follows:</P> +<DIV class="code"> +<PRE> +class PYTHON : public Language { +protected: +public : + virtual void main(int, char *argv[]); + virtual int top(Node *); + virtual int functionWrapper(Node *); + virtual int constantWrapper(Node *); + virtual int variableWrapper(Node *); + virtual int nativeWrapper(Node *); + virtual int membervariableHandler(Node *); + virtual int memberconstantHandler(Node *); + virtual int memberfunctionHandler(Node *); + virtual int constructorHandler(Node *); + virtual int destructorHandler(Node *); + virtual int classHandler(Node *); + virtual int classforwardDeclaration(Node *); + virtual int insertDirective(Node *); + virtual int importDirective(Node *); +}; +</PRE> +</DIV> +<P> The role of these functions is described shortly.</P> +<H3><A name="Extending_nn13"></A>35.4.8 SWIG and XML</H3> +<P> Much of SWIG's current parser design was originally motivated by + interest in using XML to represent SWIG parse trees. Although XML is + not currently used in any direct manner, the parse tree structure, use + of node tags, attributes, and attribute namespaces are all influenced + by aspects of XML parsing. Therefore, in trying to understand SWIG's + internal data structures, it may be useful to keep XML in the back of + your mind as a model.</P> +<H2><A name="Extending_nn14"></A>35.5 Primitive Data Structures</H2> +<P> Most of SWIG is constructed using three basic data structures: + strings, hashes, and lists. These data structures are dynamic in same + way as similar structures found in many scripting languages. For + instance, you can have containers (lists and hash tables) of mixed + types and certain operations are polymorphic.</P> +<P> This section briefly describes the basic structures so that later + sections of this chapter make more sense.</P> +<P> When describing the low-level API, the following type name + conventions are used:</P> +<UL> +<LI><TT>String</TT>. A string object.</LI> +<LI><TT>Hash</TT>. A hash object.</LI> +<LI><TT>List</TT>. A list object.</LI> +<LI><TT>String_or_char</TT>. A string object or a <TT>char *</TT>.</LI> +<LI><TT>Object_or_char</TT>. An object or a <TT>char *</TT>.</LI> +<LI><TT>Object</TT>. Any object (string, hash, list, etc.)</LI> +</UL> +<P> In most cases, other typenames in the source are aliases for one of + these primitive types. Specifically:</P> +<DIV class="code"> +<PRE> +typedef String SwigType; +typedef Hash Parm; +typedef Hash ParmList; +typedef Hash Node; +typedef Hash Symtab; +typedef Hash Typetab; +</PRE> +</DIV> +<H3><A name="Extending_nn15"></A>35.5.1 Strings</H3> +<P><B> <TT>String *NewString(const String_or_char *val)</TT></B></P> +<DIV class="indent"> Creates a new string with initial value <TT>val</TT> +. <TT>val</TT> may be a <TT>char *</TT> or another <TT>String</TT> + object. If you want to create an empty string, use "" for val.</DIV> +<P><B> <TT>String *NewStringf(const char *fmt, ...)</TT></B></P> +<DIV class="indent"> Creates a new string whose initial value is set + according to a C <TT>printf</TT> style format string in <TT>fmt</TT>. + Additional arguments follow depending on <TT>fmt</TT>.</DIV> +<P><B> <TT>String *Copy(String *s)</TT></B></P> +<DIV class="indent"> Make a copy of the string <TT>s</TT>.</DIV> +<P><B> <TT>void Delete(String *s)</TT></B></P> +<DIV class="indent"> Deletes <TT>s</TT>.</DIV> +<P><B> <TT>int Len(const String_or_char *s)</TT></B></P> +<DIV class="indent"> Returns the length of the string.</DIV> +<P><B> <TT>char *Char(const String_or_char *s)</TT></B></P> +<DIV class="indent"> Returns a pointer to the first character in a + string.</DIV> +<P><B> <TT>void Append(String *s, const String_or_char *t)</TT></B></P> +<DIV class="indent"> Appends <TT>t</TT> to the end of string <TT>s</TT>.</DIV> +<P><B> <TT>void Insert(String *s, int pos, const String_or_char *t)</TT></B> +</P> +<DIV class="indent"> Inserts <TT>t</TT> into <TT>s</TT> at position <TT> +pos</TT>. The contents of <TT>s</TT> are shifted accordingly. The + special value <TT>DOH_END</TT> can be used for <TT>pos</TT> to indicate + insertion at the end of the string (appending).</DIV> +<P><B> <TT>int Strcmp(const String_or_char *s, const String_or_char *t)</TT> +</B></P> +<DIV class="indent"> Compare strings <TT>s</TT> and <TT>t</TT>. Same as + the C <TT>strcmp()</TT> function.</DIV> +<P><B> <TT>int Strncmp(const String_or_char *s, const String_or_char *t, + int len)</TT></B></P> +<DIV class="indent"> Compare the first <TT>len</TT> characters of + strings <TT>s</TT> and <TT>t</TT>. Same as the C <TT>strncmp()</TT> + function.</DIV> +<P><B> <TT>char *Strstr(const String_or_char *s, const String_or_char + *pat)</TT></B></P> +<DIV class="indent"> Returns a pointer to the first occurrence of <TT> +pat</TT> in <TT>s</TT>. Same as the C <TT>strstr()</TT> function.</DIV> +<P><B> <TT>char *Strchr(const String_or_char *s, char ch)</TT></B></P> +<DIV class="indent"> Returns a pointer to the first occurrence of + character <TT>ch</TT> in <TT>s</TT>. Same as the C <TT>strchr()</TT> + function.</DIV> +<P><B> <TT>void Chop(String *s)</TT></B></P> +<DIV class="indent"> Chops trailing whitespace off the end of <TT>s</TT> +.</DIV> +<P><B> <TT>int Replace(String *s, const String_or_char *pat, const + String_or_char *rep, int flags)</TT></B></P> +<DIV class="indent"> +<P> Replaces the pattern <TT>pat</TT> with <TT>rep</TT> in string <TT>s</TT> +. <TT>flags</TT> is a combination of the following flags:</P> +<DIV class="code"> +<PRE> +DOH_REPLACE_ANY - Replace all occurrences +DOH_REPLACE_ID - Valid C identifiers only +DOH_REPLACE_NOQUOTE - Don't replace in quoted strings +DOH_REPLACE_FIRST - Replace first occurrence only. +</PRE> +</DIV> +<P> Returns the number of replacements made (if any).</P> +</DIV> +<H3><A name="Extending_nn16"></A>35.5.2 Hashes</H3> +<P><B> <TT>Hash *NewHash()</TT></B></P> +<DIV class="indent"> Creates a new empty hash table.</DIV> +<P><B> <TT>Hash *Copy(Hash *h)</TT></B></P> +<DIV class="indent"> Make a shallow copy of the hash <TT>h</TT>.</DIV> +<P><B> <TT>void Delete(Hash *h)</TT></B></P> +<DIV class="indent"> Deletes <TT>h</TT>.</DIV> +<P><B> <TT>int Len(Hash *h)</TT></B></P> +<DIV class="indent"> Returns the number of items in <TT>h</TT>.</DIV> +<P><B> <TT>Object *Getattr(Hash *h, const String_or_char *key)</TT></B></P> +<DIV class="indent"> Gets an object from <TT>h</TT>. <TT>key</TT> may be + a string or a simple <TT>char *</TT> string. Returns NULL if not found.</DIV> +<P><B> <TT>int Setattr(Hash *h, const String_or_char *key, const + Object_or_char *val)</TT></B></P> +<DIV class="indent"> Stores <TT>val</TT> in <TT>h</TT>. <TT>key</TT> may + be a string or a simple <TT>char *</TT>. If <TT>val</TT> is not a + standard object (String, Hash, or List) it is assumed to be a <TT>char + *</TT> in which case it is used to construct a <TT>String</TT> that is + stored in the hash. If <TT>val</TT> is NULL, the object is deleted. + Increases the reference count of <TT>val</TT>. Returns 1 if this + operation replaced an existing hash entry, 0 otherwise.</DIV> +<P><B> <TT>int Delattr(Hash *h, const String_or_char *key)</TT></B></P> +<DIV class="indent"> Deletes the hash item referenced by <TT>key</TT>. + Decreases the reference count on the corresponding object (if any). + Returns 1 if an object was removed, 0 otherwise.</DIV> +<P><B> <TT>List *Keys(Hash *h)</TT></B></P> +<DIV class="indent"> Returns the list of hash table keys.</DIV> +<H3><A name="Extending_nn17"></A>35.5.3 Lists</H3> +<P><B> <TT>List *NewList()</TT></B></P> +<DIV class="indent"> Creates a new empty list.</DIV> +<P><B> <TT>List *Copy(List *x)</TT></B></P> +<DIV class="indent"> Make a shallow copy of the List <TT>x</TT>.</DIV> +<P><B> <TT>void Delete(List *x)</TT></B></P> +<DIV class="indent"> Deletes <TT>x</TT>.</DIV> +<P><B> <TT>int Len(List *x)</TT></B></P> +<DIV class="indent"> Returns the number of items in <TT>x</TT>.</DIV> +<P><B> <TT>Object *Getitem(List *x, int n)</TT></B></P> +<DIV class="indent"> Returns an object from <TT>x</TT> with index <TT>n</TT> +. If <TT>n</TT> is beyond the end of the list, the last item is + returned. If <TT>n</TT> is negative, the first item is returned.</DIV> +<P><B> <TT>int *Setitem(List *x, int n, const Object_or_char *val)</TT></B> +</P> +<DIV class="indent"> Stores <TT>val</TT> in <TT>x</TT>. If <TT>val</TT> + is not a standard object (String, Hash, or List) it is assumed to be a <TT> +char *</TT> in which case it is used to construct a <TT>String</TT> that + is stored in the list. <TT>n</TT> must be in range. Otherwise, an + assertion will be raised.</DIV> +<P><B> <TT>int *Delitem(List *x, int n)</TT></B></P> +<DIV class="indent"> Deletes item <TT>n</TT> from the list, shifting + items down if necessary. To delete the last item in the list, use the + special value <TT>DOH_END</TT> for <TT>n</TT>.</DIV> +<P><B> <TT>void Append(List *x, const Object_or_char *t)</TT></B></P> +<DIV class="indent"> Appends <TT>t</TT> to the end of <TT>x</TT>. If <TT> +t</TT> is not a standard object, it is assumed to be a <TT>char *</TT> + and is used to create a String object.</DIV> +<P><B> <TT>void Insert(String *s, int pos, const Object_or_char *t)</TT></B> +</P> +<DIV class="indent"> Inserts <TT>t</TT> into <TT>s</TT> at position <TT> +pos</TT>. The contents of <TT>s</TT> are shifted accordingly. The + special value <TT>DOH_END</TT> can be used for <TT>pos</TT> to indicate + insertion at the end of the list (appending). If <TT>t</TT> is not a + standard object, it is assumed to be a <TT>char *</TT> and is used to + create a String object.</DIV> +<H3><A name="Extending_nn18"></A>35.5.4 Common operations</H3> + The following operations are applicable to all datatypes. +<P><B> <TT>Object *Copy(Object *x)</TT></B></P> +<DIV class="indent"> Make a copy of the object <TT>x</TT>.</DIV> +<P><B> <TT>void Delete(Object *x)</TT></B></P> +<DIV class="indent"> Deletes <TT>x</TT>.</DIV> +<P><B> <TT>void Setfile(Object *x, String_or_char *f)</TT></B></P> +<DIV class="indent"> Sets the filename associated with <TT>x</TT>. Used + to track objects and report errors.</DIV> +<P><B> <TT>String *Getfile(Object *x)</TT></B></P> +<DIV class="indent"> Gets the filename associated with <TT>x</TT>.</DIV> +<P><B> <TT>void Setline(Object *x, int n)</TT></B></P> +<DIV class="indent"> Sets the line number associated with <TT>x</TT>. + Used to track objects and report errors.</DIV> +<P><B> <TT>int Getline(Object *x)</TT></B></P> +<DIV class="indent"> Gets the line number associated with <TT>x</TT>.</DIV> +<H3><A name="Extending_nn19"></A>35.5.5 Iterating over Lists and Hashes</H3> + To iterate over the elements of a list or a hash table, the following + functions are used: +<P><B> <TT>Iterator First(Object *x)</TT></B></P> +<DIV class="indent"> Returns an iterator object that points to the first + item in a list or hash table. The <TT>item</TT> attribute of the + Iterator object is a pointer to the item. For hash tables, the <TT>key</TT> + attribute of the Iterator object additionally points to the + corresponding Hash table key. The <TT>item</TT> and <TT>key</TT> + attributes are NULL if the object contains no items or if there are no + more items.</DIV> +<P><B> <TT>Iterator Next(Iterator i)</TT></B></P> +<DIV class="indent"> +<P>Returns an iterator that points to the next item in a list or hash + table. Here are two examples of iteration:</P> +<DIV class="code"> +<PRE> +List *l = (some list); +Iterator i; + +for (i = First(l); i.item; i = Next(i)) { + Printf(stdout,"%s\n", i.item); +} + +Hash *h = (some hash); +Iterator j; + +for (j = First(j); j.item; j= Next(j)) { + Printf(stdout,"%s : %s\n", j.key, j.item); +} +</PRE> +</DIV></DIV> +<H3><A name="Extending_nn20"></A>35.5.6 I/O</H3> + Special I/O functions are used for all internal I/O. These operations + work on C <TT>FILE *</TT> objects, String objects, and special <TT>File</TT> + objects (which are merely a wrapper around <TT>FILE *</TT>). +<P><B> <TT>int Printf(String_or_FILE *f, const char *fmt, ...)</TT></B></P> +<DIV class="indent"> Formatted I/O. Same as the C <TT>fprintf()</TT> + function except that output can also be directed to a string object. + Note: the <TT>%s</TT> format specifier works with both strings and <TT> +char *</TT>. All other format operators have the same meaning.</DIV> +<P><B> <TT>int Printv(String_or_FILE *f, String_or_char *arg1,..., NULL)</TT> +</B></P> +<DIV class="indent"> Prints a variable number of strings arguments to + the output. The last argument to this function must be NULL. The other + arguments can either be <TT>char *</TT> or string objects.</DIV> +<P><B> <TT>int Putc(int ch, String_or_FILE *f)</TT></B></P> +<DIV class="indent"> Same as the C <TT>fputc()</TT> function.</DIV> +<P><B> <TT>int Write(String_or_FILE *f, void *buf, int len)</TT></B></P> +<DIV class="indent"> Same as the C <TT>write()</TT> function.</DIV> +<P><B> <TT>int Read(String_or_FILE *f, void *buf, int maxlen)</TT></B></P> +<DIV class="indent"> Same as the C <TT>read()</TT> function.</DIV> +<P><B> <TT>int Getc(String_or_FILE *f)</TT></B></P> +<DIV class="indent"> Same as the C <TT>fgetc()</TT> function.</DIV> +<P><B> <TT>int Ungetc(int ch, String_or_FILE *f)</TT></B></P> +<DIV class="indent"> Same as the C <TT>ungetc()</TT> function.</DIV> +<P><B> <TT>int Seek(String_or_FILE *f, int offset, int whence)</TT></B></P> +<DIV class="indent"> Same as the C <TT>seek()</TT> function. <TT>offset</TT> + is the number of bytes. <TT>whence</TT> is one of <TT>SEEK_SET</TT>,<TT> +SEEK_CUR</TT>, or <TT>SEEK_END</TT>..</DIV> +<P><B> <TT>long Tell(String_or_FILE *f)</TT></B></P> +<DIV class="indent"> Same as the C <TT>tell()</TT> function.</DIV> +<P><B> <TT>File *NewFile(const char *filename, const char *mode, List + *newfiles)</TT></B></P> +<DIV class="indent"> Create a File object using the <TT>fopen()</TT> + library call. This file differs from <TT>FILE *</TT> in that it can be + placed in the standard SWIG containers (lists, hashes, etc.). The <TT> +filename</TT> is added to the <TT>newfiles</TT> list if <TT>newfiles</TT> + is non-zero and the file was created successfully.</DIV> +<P><B> <TT>File *NewFileFromFile(FILE *f)</TT></B></P> +<DIV class="indent"> Create a File object wrapper around an existing <TT> +FILE *</TT> object.</DIV> +<P><B> <TT>int Close(String_or_FILE *f)</TT></B></P> +<DIV class="indent"> +<P>Closes a file. Has no effect on strings.</P> +<P> The use of the above I/O functions and strings play a critical role + in SWIG. It is common to see small code fragments of code generated + using code like this:</P> +<DIV class="code"> +<PRE> +/* Print into a string */ +String *s = NewString(""); +Printf(s,"Hello\n"); +for (i = 0; i < 10; i++) { + Printf(s,"%d\n", i); +} +... +/* Print string into a file */ +Printf(f, "%s\n", s); +</PRE> +</DIV> +<P> Similarly, the preprocessor and parser all operate on string-files.</P> +</DIV> +<H2><A name="Extending_nn21"></A>35.6 Navigating and manipulating parse + trees</H2> + Parse trees are built as collections of hash tables. Each node is a + hash table in which arbitrary attributes can be stored. Certain + attributes in the hash table provide links to other parse tree nodes. + The following macros can be used to move around the parse tree. +<P><B> <TT>String *nodeType(Node *n)</TT></B></P> +<DIV class="indent"> Returns the node type tag as a string. The returned + string indicates the type of parse tree node.</DIV> +<P><B> <TT>Node *nextSibling(Node *n)</TT></B></P> +<DIV class="indent"> Returns the next node in the parse tree. For + example, the next C declaration.</DIV> +<P><B> <TT>Node *previousSibling(Node *n)</TT></B></P> +<DIV class="indent"> Returns the previous node in the parse tree. For + example, the previous C declaration.</DIV> +<P><B> <TT>Node *firstChild(Node *n)</TT></B></P> +<DIV class="indent"> Returns the first child node. For example, if <TT>n</TT> + was a C++ class node, this would return the node for the first class + member.</DIV> +<P><B> <TT>Node *lastChild(Node *n)</TT></B></P> +<DIV class="indent"> Returns the last child node. You might use this if + you wanted to append a new node to the of a class.</DIV> +<P><B> <TT>Node *parentNode(Node *n)</TT></B></P> +<DIV class="indent"> Returns the parent of node <TT>n</TT>. Use this to + move up the pass tree.</DIV> +<P> The following macros can be used to change all of the above + attributes. Normally, these functions are only used by the parser. + Changing them without knowing what you are doing is likely to be + dangerous.</P> +<P><B> <TT>void set_nodeType(Node *n, const String_or_char)</TT></B></P> +<DIV class="indent"> Change the node type. tree node.</DIV> +<P><B> <TT>void set_nextSibling(Node *n, Node *s)</TT></B></P> +<DIV class="indent"> Set the next sibling.</DIV> +<P><B> <TT>void set_previousSibling(Node *n, Node *s)</TT></B></P> +<DIV class="indent"> Set the previous sibling.</DIV> +<P><B> <TT>void set_firstChild(Node *n, Node *c)</TT></B></P> +<DIV class="indent"> Set the first child node.</DIV> +<P><B> <TT>void set_lastChild(Node *n, Node *c)</TT></B></P> +<DIV class="indent"> Set the last child node.</DIV> +<P><B> <TT>void set_parentNode(Node *n, Node *p)</TT></B></P> +<DIV class="indent"> Set the parent node.</DIV> +<P> The following utility functions are used to alter the parse tree (at + your own risk)</P> +<P><B> <TT>void appendChild(Node *parent, Node *child)</TT></B></P> +<DIV class="indent"> Append a child to <TT>parent</TT>. The appended + node becomes the last child.</DIV> +<P><B> <TT>void deleteNode(Node *node)</TT></B></P> +<DIV class="indent"> Deletes a node from the parse tree. Deletion + reconnects siblings and properly updates the parent so that sibling + nodes are unaffected.</DIV> +<H2><A name="Extending_nn22"></A>35.7 Working with attributes</H2> +<P> Since parse tree nodes are just hash tables, attributes are accessed + using the <TT>Getattr()</TT>, <TT>Setattr()</TT>, and <TT>Delattr()</TT> + operations. For example:</P> +<DIV class="code"> +<PRE> +int functionHandler(Node *n) { + String *name = Getattr(n,"name"); + String *symname = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + ... +} +</PRE> +</DIV> +<P> New attributes can be freely attached to a node as needed. However, + when new attributes are attached during code generation, they should be + prepended with a namespace prefix. For example:</P> +<DIV class="code"> +<PRE> +... +Setattr(n,"python:docstring", doc); /* Store docstring */ +... +</PRE> +</DIV> +<P> A quick way to check the value of an attribute is to use the <TT> +checkAttribute()</TT> function like this:</P> +<DIV class="code"> +<PRE> +if (checkAttribute(n,"storage","virtual")) { + /* n is virtual */ + ... +} +</PRE> +</DIV> +<P> Changing the values of existing attributes is allowed and is + sometimes done to implement node transformations. However, if a + function/method modifies a node, it is required to restore modified + attributes to their original values. To simplify the task of + saving/restoring attributes, the following functions are used:</P> +<P><B> <TT>int Swig_save(const char *ns, Node *n, const char *name1, + const char *name2, ..., NIL)</TT></B></P> +<DIV class="indent"> Saves a copy of attributes <TT>name1</TT>, <TT> +name2</TT>, etc. from node <TT>n</TT>. Copies of the attributes are + actually resaved in the node in a different namespace which is set by + the <TT>ns</TT> argument. For example, if you call <TT> +Swig_save("foo",n,"type",NIL)</TT>, then the "type" attribute will be + copied and saved as "foo:type". The namespace name itself is stored in + the "view" attribute of the node. If necessary, this can be examined to + find out where previous values of attributes might have been saved.</DIV> +<P><B> <TT>int Swig_restore(Node *n)</TT></B></P> +<DIV class="indent"> +<P> Restores the attributes saved by the previous call to <TT> +Swig_save()</TT>. Those attributes that were supplied to <TT>Swig_save()</TT> + will be restored to their original values.</P> +<P> The <TT>Swig_save()</TT> and <TT>Swig_restore()</TT> functions must + always be used as a pair. That is, every call to <TT>Swig_save()</TT> + must have a matching call to <TT>Swig_restore()</TT>. Calls can be + nested if necessary. Here is an example that shows how the functions + might be used:</P> +<DIV class="code"> +<PRE> +int variableHandler(Node *n) { + Swig_save("variableHandler",n,"type","sym:name",NIL); + String *symname = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + ... + Append(symname,"_global"); // Change symbol name + SwigType_add_pointer(type); // Add pointer + ... + generate wrappers + ... + Swig_restore(n); // Restore original values + return SWIG_OK; +} +</PRE> +</DIV></DIV> +<P><B> <TT>int Swig_require(const char *ns, Node *n, const char *name1, + const char *name2, ..., NIL)</TT></B></P> +<DIV class="indent"> This is an enhanced version of <TT>Swig_save()</TT> + that adds error checking. If an attribute name is not present in <TT>n</TT> +, a failed assertion results and SWIG terminates with a fatal error. + Optionally, if an attribute name is specified as "*<EM>name</EM>", a + copy of the attribute is saved as with <TT>Swig_save()</TT>. If an + attribute is specified as "?<EM>name</EM>", the attribute is optional. <TT> +Swig_restore()</TT> must always be called after using this function.</DIV> +<H2><A name="Extending_nn23"></A>35.8 Type system</H2> +<P> SWIG implements the complete C++ type system including typedef, + inheritance, pointers, references, and pointers to members. A detailed + discussion of type theory is impossible here. However, let's cover the + highlights.</P> +<H3><A name="Extending_nn24"></A>35.8.1 String encoding of types</H3> +<P> All types in SWIG consist of a base datatype and a collection of + type operators that are applied to the base. A base datatype is almost + always some kind of primitive type such as <TT>int</TT> or <TT>double</TT> +. The operators consist of things like pointers, references, arrays, and + so forth. Internally, types are represented as strings that are + constructed in a very precise manner. Here are some examples:</P> +<DIV class="diagram"> +<PRE> +C datatype SWIG encoding (strings) +----------------------------- -------------------------- +int "int" +int * "p.int" +const int * "p.q(const).int" +int (*x)(int,double) "p.f(int,double).int" +int [20][30] "a(20).a(30).int" +int (F::*)(int) "m(F).f(int).int" +vector<int> * "p.vector<(int)>" +</PRE> +</DIV> +<P> Reading the SWIG encoding is often easier than figuring out the C + code---just read it from left to right. For a type of + "p.f(int,double).int" is a "pointer to a function(int,double) that + returns int".</P> +<P> The following operator encodings are used in type strings:</P> +<DIV class="diagram"> +<PRE> +Operator Meaning +------------------- ------------------------------- +p. Pointer to +a(n). Array of dimension n +r. C++ reference +m(class). Member pointer to class +f(args). Function. +q(qlist). Qualifiers +</PRE> +</DIV> +<P> In addition, type names may be parameterized by templates. This is + represented by enclosing the template parameters in <TT><( ... )></TT>. + Variable length arguments are represented by the special base type of <TT> +v(...)</TT>.</P> +<P> If you want to experiment with type encodings, the raw type strings + can be inserted into an interface file using backticks `` wherever a + type is expected. For instance, here is an extremely perverted example:</P> +<DIV class="diagram"> +<PRE> +`p.a(10).p.f(int,p.f(int).int)` foo(int, int (*x)(int)); +</PRE> +</DIV> +<P> This corresponds to the immediately obvious C declaration:</P> +<DIV class="diagram"> +<PRE> +(*(*foo(int,int (*)(int)))[10])(int,int (*)(int)); +</PRE> +</DIV> +<P> Aside from the potential use of this declaration on a C programming + quiz, it motivates the use of the special SWIG encoding of types. The + SWIG encoding is much easier to work with because types can be easily + examined, modified, and constructed using simple string operations + (comparison, substrings, concatenation, etc.). For example, in the + parser, a declaration like this</P> +<DIV class="code"> +<PRE> +int *a[30]; +</PRE> +</DIV> +<P> is processed in a few pieces. In this case, you have the base type "<TT> +int</TT>" and the declarator of type "<TT>a(30).p.</TT>". To make the + final type, the two parts are just joined together using string + concatenation.</P> +<H3><A name="Extending_nn25"></A>35.8.2 Type construction</H3> +<P> The following functions are used to construct types. You should use + these functions instead of trying to build the type strings yourself.</P> +<P><B> <TT>void SwigType_add_pointer(SwigType *ty)</TT></B></P> +<DIV class="indent"> Adds a pointer to <TT>ty</TT>.</DIV> +<P><B> <TT>void SwigType_del_pointer(SwigType *ty)</TT></B></P> +<DIV class="indent"> Removes a single pointer from <TT>ty</TT>.</DIV> +<P><B> <TT>void SwigType_add_reference(SwigType *ty)</TT></B></P> +<DIV class="indent"> Adds a reference to <TT>ty</TT>.</DIV> +<P><B> <TT>void SwigType_add_array(SwigType *ty, const String_or_char + *size)</TT></B></P> +<DIV class="indent"> Adds an array with dimension <TT>dim</TT> to <TT>ty</TT> +.</DIV> +<P><B> <TT>void SwigType_del_array(SwigType *ty)</TT></B></P> +<DIV class="indent"> Removes a single array dimension from <TT>ty</TT>.</DIV> +<P><B> <TT>int SwigType_array_ndim(SwigType *ty)</TT></B></P> +<DIV class="indent"> Returns number of array dimensions of <TT>ty</TT>.</DIV> +<P><B> <TT>String* SwigType_array_getdim(SwigType *ty,int n)</TT></B></P> +<DIV class="indent"> Returns <TT>n</TT>th array dimension of <TT>ty</TT> +.</DIV> +<P><B> <TT>void SwigType_array_setdim(SwigType *ty, int n, const + String_or_char *rep)</TT></B></P> +<DIV class="indent"> Sets <TT>n</TT>th array dimensions of <TT>ty</TT> + to <TT>rep</TT>.</DIV> +<P><B> <TT>void SwigType_add_qualifier(SwigType *ty, const + String_or_char *q)</TT></B></P> +<DIV class="indent"> Adds a type qualifier <TT>q</TT> to <TT>ty</TT>. <TT> +q</TT> is typically <TT>"const"</TT> or <TT>"volatile"</TT>.</DIV> +<P><B> <TT>void SwigType_add_memberpointer(SwigType *ty, const + String_or_char *cls)</TT></B></P> +<DIV class="indent"> Adds a pointer to a member of class <TT>cls</TT> to + <TT>ty</TT>.</DIV> +<P><B> <TT>void SwigType_add_function(SwigType *ty, ParmList *p)</TT></B> +</P> +<DIV class="indent"> Adds a function to <TT>ty</TT>. <TT>p</TT> is a + linked-list of parameter nodes as generated by the parser. See the + section on parameter lists for details about the representation.</DIV> +<P><B> <TT>void SwigType_add_template(SwigType *ty, ParmList *p)</TT></B> +</P> +<DIV class="indent"> Adds a template to <TT>ty</TT>. <TT>p</TT> is a + linked-list of parameter nodes as generated by the parser. See the + section on parameter lists for details about the representation.</DIV> +<P><B> <TT>SwigType *SwigType_pop(SwigType *ty)</TT></B></P> +<DIV class="indent"> Removes the last type constructor from <TT>ty</TT> + and returns it. <TT>ty</TT> is modified.</DIV> +<P><B> <TT>void SwigType_push(SwigType *ty, SwigType *op)</TT></B></P> +<DIV class="indent"> Pushes the type operators in <TT>op</TT> onto type <TT> +ty</TT>. The opposite of <TT>SwigType_pop()</TT>.</DIV> +<P><B> <TT>SwigType *SwigType_pop_arrays(SwigType *ty)</TT></B></P> +<DIV class="indent"> Removes all leading array operators from <TT>ty</TT> + and returns them. <TT>ty</TT> is modified. For example, if <TT>ty</TT> + is <TT>"a(20).a(10).p.int"</TT>, then this function would return <TT> +"a(20).a(10)."</TT> and modify <TT>ty</TT> so that it has the value <TT> +"p.int"</TT>.</DIV> +<P><B> <TT>SwigType *SwigType_pop_function(SwigType *ty)</TT></B></P> +<DIV class="indent"> Removes a function operator from <TT>ty</TT> + including any qualification. <TT>ty</TT> is modified. For example, if <TT> +ty</TT> is <TT>"f(int).int"</TT>, then this function would return <TT> +"f(int)."</TT> and modify <TT>ty</TT> so that it has the value <TT>"int"</TT> +.</DIV> +<P><B> <TT>SwigType *SwigType_base(SwigType *ty)</TT></B></P> +<DIV class="indent"> Returns the base type of a type. For example, if <TT> +ty</TT> is <TT>"p.a(20).int"</TT>, this function would return <TT>"int"</TT> +. <TT>ty</TT> is unmodified.</DIV> +<P><B> <TT>SwigType *SwigType_prefix(SwigType *ty)</TT></B></P> +<DIV class="indent"> Returns the prefix of a type. For example, if <TT> +ty</TT> is <TT>"p.a(20).int"</TT>, this function would return <TT> +"p.a(20)."</TT>. <TT>ty</TT> is unmodified.</DIV> +<H3><A name="Extending_nn26"></A>35.8.3 Type tests</H3> +<P> The following functions can be used to test properties of a + datatype.</P> +<P><B> <TT>int SwigType_ispointer(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a standard pointer.</DIV> +<P><B> <TT>int SwigType_ismemberpointer(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a member pointer.</DIV> +<P><B> <TT>int SwigType_isreference(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a C++ reference.</DIV> +<P><B> <TT>int SwigType_isarray(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is an array.</DIV> +<P><B> <TT>int SwigType_isfunction(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a function.</DIV> +<P><B> <TT>int SwigType_isqualifier(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a qualifier.</DIV> +<P><B> <TT>int SwigType_issimple(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a simple type. No + operators applied.</DIV> +<P><B> <TT>int SwigType_isconst(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a const type.</DIV> +<P><B> <TT>int SwigType_isvarargs(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a varargs type.</DIV> +<P><B> <TT>int SwigType_istemplate(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> is a templatized type.</DIV> +<H3><A name="Extending_nn27"></A>35.8.4 Typedef and inheritance</H3> +<P> The behavior of <TT>typedef</TT> declaration is to introduce a type + alias. For instance, <TT>typedef int Integer</TT> makes the identifier <TT> +Integer</TT> an alias for <TT>int</TT>. The treatment of typedef in SWIG + is somewhat complicated due to the pattern matching rules that get + applied in typemaps and the fact that SWIG prefers to generate wrapper + code that closely matches the input to simplify debugging (a user will + see the typedef names used in their program instead of the low-level + primitive C datatypes).</P> +<P> To handle <TT>typedef</TT>, SWIG builds a collection of trees + containing typedef relations. For example,</P> +<DIV class="code"> +<PRE> +typedef int Integer; +typedef Integer *IntegerPtr; +typedef int Number; +typedef int Size; +</PRE> +</DIV> +<P> produces two trees like this:</P> +<DIV class="diagram"> +<PRE> + int p.Integer + ^ ^ ^ ^ + / | \ | + / | \ | + Integer Size Number IntegerPtr +</PRE> +</DIV> +<P> To resolve a single typedef relationship, the following function is + used:</P> +<P><B> <TT>SwigType *SwigType_typedef_resolve(SwigType *ty)</TT></B></P> +<DIV class="indent"> Checks if <TT>ty</TT> can be reduced to a new type + via typedef. If so, returns the new type. If not, returns NULL.</DIV> +<P> Typedefs are only resolved in simple typenames that appear in a + type. For example, the type base name and in function parameters. When + resolving types, the process starts in the leaf nodes and moves up the + tree towards the root. Here are a few examples that show how it works:</P> +<DIV class="diagram"> +<PRE> +Original type After typedef_resolve() +------------------------ ----------------------- +Integer int +a(30).Integer int +p.IntegerPtr p.p.Integer +p.p.Integer p.p.int +</PRE> +</DIV> +<P> For complicated types, the process can be quite involved. Here is + the reduction of a function pointer:</P> +<DIV class="diagram"> +<PRE> +p.f(Integer, p.IntegerPtr, Size).Integer : Start +p.f(Integer, p.IntegerPtr, Size).int +p.f(int, p.IntegerPtr, Size).int +p.f(int, p.p.Integer, Size).int +p.f(int, p.p.int, Size).int +p.f(int, p.p.int, int).int : End +</PRE> +</DIV> +<P> Two types are equivalent if their full type reductions are the same. + The following function will fully reduce a datatype:</P> +<P><B> <TT>SwigType *SwigType_typedef_resolve_all(SwigType *ty)</TT></B></P> +<DIV class="indent"> Fully reduces <TT>ty</TT> according to typedef + rules. Resulting datatype will consist only of primitive typenames.</DIV> +<H3><A name="Extending_nn28"></A>35.8.5 Lvalues</H3> +<P> When generating wrapper code, it is necessary to emit datatypes that + can be used on the left-hand side of an assignment operator (an + lvalue). However, not all C datatypes can be used in this + way---especially arrays and const-qualified types. To generate a type + that can be used as an lvalue, use the following function:</P> +<P><B> <TT>SwigType *SwigType_ltype(SwigType *ty)</TT></B></P> +<DIV class="indent"> Converts type <TT>ty</TT> to a type that can be + used as an lvalue in assignment. The resulting type is stripped of + qualifiers and arrays are converted to a pointers.</DIV> +<P> The creation of lvalues is fully aware of typedef and other aspects + of the type system. Therefore, the creation of an lvalue may result in + unexpected results. Here are a few examples:</P> +<DIV class="code"> +<PRE> +typedef double Matrix4[4][4]; +Matrix4 x; // type = 'Matrix4', ltype='p.a(4).double' + +typedef const char * Literal; +Literal y; // type = 'Literal', ltype='p.char' +</PRE> +</DIV> +<H3><A name="Extending_nn29"></A>35.8.6 Output functions</H3> +<P> The following functions produce strings that are suitable for + output.</P> +<P><B> <TT>String *SwigType_str(SwigType *ty, const String_or_char *id = + 0)</TT></B></P> +<DIV class="indent"> Generates a C string for a datatype. <TT>id</TT> is + an optional declarator. For example, if <TT>ty</TT> is "p.f(int).int" + and <TT>id</TT> is "foo", then this function produces "<TT>int + (*foo)(int)</TT>". This function is used to convert string-encoded + types back into a form that is valid C syntax.</DIV> +<P><B> <TT>String *SwigType_lstr(SwigType *ty, const String_or_char *id + = 0)</TT></B></P> +<DIV class="indent"> This is the same as <TT>SwigType_str()</TT> except + that the result is generated from the type's lvalue (as generated from + SwigType_ltype).</DIV> +<P><B> <TT>String *SwigType_lcaststr(SwigType *ty, const String_or_char + *id = 0)</TT></B></P> +<DIV class="indent"> Generates a casting operation that converts from + type <TT>ty</TT> to its lvalue. <TT>id</TT> is an optional name to + include in the cast. For example, if <TT>ty</TT> is "<TT> +q(const).p.char</TT>" and <TT>id</TT> is "<TT>foo</TT>", this function + produces the string "<TT>(char *) foo</TT>".</DIV> +<P><B> <TT>String *SwigType_rcaststr(SwigType *ty, const String_or_char + *id = 0)</TT></B></P> +<DIV class="indent"> Generates a casting operation that converts from a + type's lvalue to a type equivalent to <TT>ty</TT>. <TT>id</TT> is an + optional name to include in the cast. For example, if <TT>ty</TT> is "<TT> +q(const).p.char</TT>" and <TT>id</TT> is "<TT>foo</TT>", this function + produces the string "<TT>(const char *) foo</TT>".</DIV> +<P><B> <TT>String *SwigType_manglestr(SwigType *ty)</TT></B></P> +<DIV class="indent"> Generates a mangled string encoding of type <TT>ty</TT> +. The mangled string only contains characters that are part of a valid C + identifier. The resulting string is used in various parts of SWIG, but + is most commonly associated with type-descriptor objects that appear in + wrappers (e.g., <TT>SWIGTYPE_p_double</TT>).</DIV> +<H2><A name="Extending_nn30"></A>35.9 Parameters</H2> +<P> Several type-related functions involve parameter lists. These + include functions and templates. Parameter list are represented as a + list of nodes with the following attributes:</P> +<DIV class="diagram"> +<PRE> +"type" - Parameter type (required) +"name" - Parameter name (optional) +"value" - Initializer (optional) +</PRE> +</DIV> +<P> Typically parameters are denoted in the source by using a typename + of <TT>Parm *</TT> or <TT>ParmList *</TT>. To walk a parameter list, + simply use code like this:</P> +<DIV class="diagram"> +<PRE> +Parm *parms; +Parm *p; +for (p = parms; p; p = nextSibling(p)) { + SwigType *type = Getattr(p,"type"); + String *name = Getattr(p,"name"); + String *value = Getattr(p,"value"); + ... +} +</PRE> +</DIV> +<P> Note: this code is exactly the same as what you would use to walk + parse tree nodes.</P> +<P> An empty list of parameters is denoted by a NULL pointer.</P> +<P> Since parameter lists are fairly common, the following utility + functions are provided to manipulate them:</P> +<P><B> <TT>Parm *CopyParm(Parm *p);</TT></B></P> +<DIV class="indent"> Copies a single parameter.</DIV> +<P><B> <TT>ParmList *CopyParmList(ParmList *p);</TT></B></P> +<DIV class="indent"> Copies an entire list of parameters.</DIV> +<P><B> <TT>int ParmList_len(ParmList *p);</TT></B></P> +<DIV class="indent"> Returns the number of parameters in a parameter + list.</DIV> +<P><B> <TT>String *ParmList_str(ParmList *p);</TT></B></P> +<DIV class="indent"> Converts a parameter list into a C string. For + example, produces a string like "<TT>(int *p, int n, double x);</TT>".</DIV> +<P><B> <TT>String *ParmList_protostr(ParmList *p);</TT></B></P> +<DIV class="indent"> The same as <TT>ParmList_str()</TT> except that + parameter names are not included. Used to emit prototypes.</DIV> +<P><B> <TT>int ParmList_numrequired(ParmList *p);</TT></B></P> +<DIV class="indent"> Returns the number of required (non-optional) + arguments in <TT>p</TT>.</DIV> +<H2><A name="Extending_nn31"></A>35.10 Writing a Language Module</H2> +<P> One of the easiest routes to supporting a new language module is to + copy an already supported language module implementation and modify it. + Be sure to choose a language that is similar in nature to the new + language. All language modules follow a similar structure and this + section briefly outlines the steps needed to create a bare-bones + language module from scratch. Since the code is relatively easy to + read, this section describes the creation of a minimal Python module. + You should be able to extrapolate this to other languages.</P> +<H3><A name="Extending_nn32"></A>35.10.1 Execution model</H3> +<P> Code generation modules are defined by inheriting from the <TT> +Language</TT> class, currently defined in the <TT>Source/Modules</TT> + directory of SWIG. Starting from the parsing of command line options, + all aspects of code generation are controlled by different methods of + the <TT>Language</TT> that must be defined by your module.</P> +<H3><A name="Extending_nn33"></A>35.10.2 Starting out</H3> +<P> To define a new language module, first create a minimal + implementation using this example as a guide:</P> +<DIV class="code"> +<PRE> +#include "swigmod.h" + +class PYTHON : public Language { +public: + + virtual void main(int argc, char *argv[]) { + printf("I'm the Python module.\n"); + } + + virtual int top(Node *n) { + printf("Generating code.\n"); + return SWIG_OK; + } + +}; + +extern "C" Language * +swig_python(void) { + return new PYTHON(); +} +</PRE> +</DIV> +<P> The "swigmod.h" header file contains, among other things, the + declaration of the <TT>Language</TT> base class and so you should + include it at the top of your language module's source file. Similarly, + the "swigconfig.h" header file contains some other useful definitions + that you may need. Note that you should<EM> not</EM> include any header + files that are installed with the target language. That is to say, the + implementation of the SWIG Python module shouldn't have any + dependencies on the Python header files. The wrapper code generated by + SWIG will almost always depend on some language-specific C/C++ header + files, but SWIG itself does not.</P> +<P> Give your language class a reasonable name, usually the same as the + target language. By convention, these class names are all uppercase + (e.g. "PYTHON" for the Python language module) but this is not a + requirement. This class will ultimately consist of a number of + overrides of the virtual functions declared in the <TT>Language</TT> + base class, in addition to any language-specific member functions and + data you need. For now, just use the dummy implementations shown above.</P> +<P> The language module ends with a factory function, <TT>swig_python()</TT> +, that simply returns a new instance of the language class. As shown, it + should be declared with the <TT>extern "C"</TT> storage qualifier so + that it can be called from C code. It should also return a pointer to + the base class (<TT>Language</TT>) so that only the interface (and not + the implementation) of your language module is exposed to the rest of + SWIG.</P> +<P> Save the code for your language module in a file named "<TT> +python.cxx</TT>" and. place this file in the <TT>Source/Modules</TT> + directory of the SWIG distribution. To ensure that your module is + compiled into SWIG along with the other language modules, modify the + file <TT>Source/Modules/Makefile.am</TT> to include the additional + source files. In addition, modify the file <TT> +Source/Modules/swigmain.cxx</TT> with an additional command line option + that activates the module. Read the source---it's straightforward.</P> +<P> Next, at the top level of the SWIG distribution, re-run the <TT> +autogen.sh</TT> script to regenerate the various build files:</P> +<DIV class="shell"> +<PRE> +$ <B>./autogen.sh</B> +</PRE> +</DIV> +<P> Next re-run <TT>configure</TT> to regenerate all of the Makefiles:</P> +<DIV class="shell"> +<PRE> +$ <B>./configure</B> +</PRE> +</DIV> +<P> Finally, rebuild SWIG with your module added:</P> +<DIV class="shell"> +<PRE> +$ <B>make</B> +</PRE> +</DIV> +<P> Once it finishes compiling, try running SWIG with the command-line + option that activates your module. For example, <TT>swig -python foo.i</TT> +. The messages from your new module should appear.</P> +<H3><A name="Extending_nn34"></A>35.10.3 Command line options</H3> +<P> When SWIG starts, the command line options are passed to your + language module. This occurs before any other processing occurs + (preprocessing, parsing, etc.). To capture the command line options, + simply use code similar to this:</P> +<DIV class="code"> +<PRE> +void Language::main(int argc, char *argv[]) { + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if(strcmp(argv[i],"-interface") == 0) { + if (argv[i+1]) { + interface = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if (strcmp(argv[i],"-globals") == 0) { + if (argv[i+1]) { + global_name = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if ( (strcmp(argv[i],"-proxy") == 0)) { + proxy_flag = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-keyword") == 0) { + use_kw = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } + ... + } + } +} +</PRE> +</DIV> +<P> The exact set of options depends on what you want to do in your + module. Generally, you would use the options to change code generation + modes or to print diagnostic information.</P> +<P> If a module recognizes an option, it should always call <TT> +Swig_mark_arg()</TT> to mark the option as valid. If you forget to do + this, SWIG will terminate with an unrecognized command line option + error.</P> +<H3><A name="Extending_nn35"></A>35.10.4 Configuration and preprocessing</H3> +<P> In addition to looking at command line options, the <TT>main()</TT> + method is responsible for some initial configuration of the SWIG + library and preprocessor. To do this, insert some code like this:</P> +<DIV class="code"> +<PRE> +void main(int argc, char *argv[]) { + ... command line options ... + + /* Set language-specific subdirectory in SWIG library */ + SWIG_library_directory("python"); + + /* Set language-specific preprocessing symbol */ + Preprocessor_define("SWIGPYTHON 1", 0); + + /* Set language-specific configuration file */ + SWIG_config_file("python.swg"); + + /* Set typemap language (historical) */ + SWIG_typemap_lang("python"); +} +</PRE> +</DIV> +<P> The above code does several things--it registers the name of the + language module with the core, it supplies some preprocessor macro + definitions for use in input files (so that they can determine the + target language), and it registers a start-up file. In this case, the + file <TT>python.swg</TT> will be parsed before any part of the + user-supplied input file.</P> +<P> Before proceeding any further, create a directory for your module in + the SWIG library (The <TT>Lib</TT> directory). Now, create a + configuration file in the directory. For example, <TT>python.swg</TT>.</P> +<P> Just to review, your language module should now consist of two + files-- an implementation file <TT>python.cxx</TT> and a configuration + file <TT>python.swg</TT>.</P> +<H3><A name="Extending_nn36"></A>35.10.5 Entry point to code generation</H3> +<P> SWIG is a multi-pass compiler. Once the <TT>main()</TT> method has + been invoked, the language module does not execute again until + preprocessing, parsing, and a variety of semantic analysis passes have + been performed. When the core is ready to start generating wrappers, it + invokes the <TT>top()</TT> method of your language class. The argument + to <TT>top</TT> is a single parse tree node that corresponds to the top + of the entire parse tree.</P> +<P> To get the code generation process started, the <TT>top()</TT> + procedure needs to do several things:</P> +<UL> +<LI>Initialize the wrapper code output.</LI> +<LI>Set the module name.</LI> +<LI>Emit common initialization code.</LI> +<LI>Emit code for all of the child nodes.</LI> +<LI>Finalize the wrapper module and cleanup.</LI> +</UL> +<P> An outline of <TT>top()</TT> might be as follows:</P> +<DIV class="code"> +<PRE> +int Python::top(Node *n) { + + /* Get the module name */ + String *module = Getattr(n,"name"); + + /* Get the output file name */ + String *outfile = Getattr(n,"outfile"); + + /* Initialize I/O (see next section) */ + ... + + /* Output module initialization code */ + ... + + /* Emit code for children */ + Language::top(n); + + ... + /* Cleanup files */ + ... + + return SWIG_OK; +} +</PRE> +</DIV> +<H3><A name="Extending_nn37"></A>35.10.6 Module I/O and wrapper skeleton</H3> + +<!-- please report bugs in this section to mgossage --> +<P> Within SWIG wrappers, there are four main sections. These are (in + order)</P> +<UL> +<LI>runtime: This section has most of the common SWIG runtime code</LI> +<LI>header: This section holds declarations and inclusions from the .i + file</LI> +<LI>wrapper: This section holds all the wrappering code</LI> +<LI>init: This section holds the module initalisation function (the + entry point for the interpreter)</LI> +</UL> +<P> Different parts of the SWIG code will fill different sections, then + upon completion of the wrappering all the sections will be saved to the + wrapper file.</P> +<P> To perform this will require several additions to the code in + various places, such as:</P> +<DIV class="code"> +<PRE> +class PYTHON : public Language { +protected: + /* General DOH objects used for holding the strings */ + File *f_begin; + File *f_runtime; + File *f_header; + File *f_wrappers; + File *f_init; + +public: + ... + +}; + +int Python::top(Node *n) { + + ... + + /* Initialize I/O */ + f_begin = NewFile(outfile, "w", SWIG_output_files()); + if (!f_begin) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } + f_runtime = NewString(""); + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("begin", f_begin); + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrappers); + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("init", f_init); + + /* Output module initialization code */ + Swig_banner(f_begin); + ... + + /* Emit code for children */ + Language::top(n); + + ... + /* Write all to the file */ + Dump(f_runtime, f_begin); + Dump(f_header, f_begin); + Dump(f_wrappers, f_begin); + Wrapper_pretty_print(f_init, f_begin); + + /* Cleanup files */ + Delete(f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_begin); + Delete(f_begin); + + return SWIG_OK; +} +</PRE> +</DIV> +<P> Using this to process a file will generate a wrapper file, however + the wrapper will only consist of the common SWIG code as well as any + inline code which was written in the .i file. It does not contain any + wrappers for any of the functions or classes.</P> +<P> The code to generate the wrappers are the various member functions, + which currently have not been touched. We will look at <TT> +functionWrapper()</TT> as this is the most commonly used function. In + fact many of the other wrapper routines will call this to do their + work.</P> +<P> A simple modification to write some basic details to the wrapper + looks like this:</P> +<DIV class="code"> +<PRE> +int Python::functionWrapper(Node *n) { + /* Get some useful attributes of this function */ + String *name = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + ParmList *parms = Getattr(n,"parms"); + String *parmstr= ParmList_str_defaultargs(parms); // to string + String *func = SwigType_str(type, NewStringf("%s(%s)", name, parmstr)); + String *action = Getattr(n,"wrap:action"); + + Printf(f_wrappers,"functionWrapper : %s\n", func); + Printf(f_wrappers," action : %s\n", action); + return SWIG_OK; +} +</PRE> +</DIV> +<P> This will now produce some useful information within your wrapper + file.</P> +<DIV class="shell"> +<PRE> +functionWrapper : void delete_Shape(Shape *self) + action : delete arg1; + +functionWrapper : void Shape_x_set(Shape *self,double x) + action : if (arg1) (arg1)->x = arg2; + +functionWrapper : double Shape_x_get(Shape *self) + action : result = (double) ((arg1)->x); + +functionWrapper : void Shape_y_set(Shape *self,double y) + action : if (arg1) (arg1)->y = arg2; +... +</PRE> +</DIV> +<H3><A name="Extending_nn38"></A>35.10.7 Low-level code generators</H3> + +<!-- please report bugs in this section to mgossage --> +<P> As ingenious as SWIG is, and despite all its capabilities and the + power of its parser, the Low-level code generation takes a lot of work + to write properly. Mainly because every language insists on its own + manner of interfacing to C/C++. To write the code generators you will + need a good understanding of how to manually write an interface to your + chosen language, so make sure you have your documentation handy.</P> +<P> At this point it is also probably a good idea to take a very simple + file (just one function), and try letting SWIG generate wrappers for + many different languages. Take a look at all of the wrappers generated, + and decide which one looks closest to the language you are trying to + wrap. This may help you to decide which code to look at.</P> +<P> In general most language wrappers look a little like this:</P> +<DIV class="code"> +<PRE> +/* wrapper for TYPE3 some_function(TYPE1,TYPE2); */ +RETURN_TYPE _wrap_some_function(ARGS){ + TYPE1 arg1; + TYPE2 arg2; + TYPE3 result; + + if(ARG1 is not of TYPE1) goto fail; + arg1=(convert ARG1); + if(ARG2 is not of TYPE2) goto fail; + arg2=(convert ARG2); + + result=some_function(arg1,arg2); + + convert 'result' to whatever the language wants; + + do any tidy up; + + return ALL_OK; + + fail: + do any tidy up; + return ERROR; +} +</PRE> +</DIV> +<P> Yes, it is rather vague and not very clear. But each language works + differently so this will have to do for now.</P> +<P> Tackling this problem will be done in two stages:</P> +<UL> +<LI>The skeleton: the function wrapper, and call, but without the + conversion</LI> +<LI>The conversion: converting the arguments to-from what the language + wants</LI> +</UL> +<P> The first step will be done in the code, the second will be done in + typemaps.</P> +<P> Our first step will be to write the code for <TT>functionWrapper()</TT> +. What is shown below is<B> NOT</B> the solution, merely a step in the + right direction. There are a lot of issues to address.</P> +<UL> +<LI>Variable length and default parameters</LI> +<LI>Typechecking and number of argument checks</LI> +<LI>Overloaded functions</LI> +<LI>Inout and Output only arguments</LI> +</UL> +<DIV class="code"> +<PRE> +virtual int functionWrapper(Node *n) { + /* get useful atributes */ + String *name = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + ParmList *parms = Getattr(n,"parms"); + ... + + /* create the wrapper object */ + Wrapper *wrapper = NewWrapper(); + + /* create the functions wrappered name */ + String *wname = Swig_name_wrapper(iname); + + /* deal with overloading */ + .... + + /* write the wrapper function definition */ + Printv(wrapper->def,"RETURN_TYPE ", wname, "(ARGS) {",NIL); + + /* if any additional local variable needed, add them now */ + ... + + /* write the list of locals/arguments required */ + emit_args(type, parms, wrapper); + + /* check arguments */ + ... + + /* write typemaps(in) */ + .... + + /* write constriants */ + .... + + /* Emit the function call */ + emit_action(n,wrapper); + + /* return value if necessary */ + .... + + /* write typemaps(out) */ + .... + + /* add cleanup code */ + .... + + /* Close the function(ok) */ + Printv(wrapper->code, "return ALL_OK;\n", NIL); + + /* add the failure cleanup code */ + ... + + /* Close the function(error) */ + Printv(wrapper->code, "return ERROR;\n", "}\n", NIL); + + /* final substititions if applicable */ + ... + + /* Dump the function out */ + Wrapper_print(wrapper,f_wrappers); + + /* tidy up */ + Delete(wname); + DelWrapper(wrapper); + + return SWIG_OK; +} +</PRE> +</DIV> +<P> Executing this code will produce wrappers which have our basic + skeleton but without the typemaps, there is still work to do.</P> +<H3><A name="Extending_nn39"></A>35.10.8 Configuration files</H3> + +<!-- please report bugs in this section to ttn --> +<P> At the time of this writing, SWIG supports nearly a dozen languages, + which means that for continued sanity in maintaining the configuration + files, the language modules need to follow some conventions. These are + outlined here along with the admission that, yes it is ok to violate + these conventions in minor ways, as long as you know where to apply the + proper kludge to keep the overall system regular and running. + Engineering is the art of compromise, see...</P> +<P> Much of the maintenance regularity depends on choosing a suitable + nickname for your language module (and then using it in a controlled + way). Nicknames should be all lower case letters with an optional + numeric suffix (no underscores, no dashes, no spaces). Some examples + are: <TT>foo</TT>, <TT>bar</TT>, <TT>qux99</TT>.</P> +<P> The numeric suffix variant, as in the last example, is somewhat + tricky to work with because sometimes people expect to refer to the + language without this number but sometimes that number is extremely + relevant (especially when it corresponds to language implementation + versions with incompatible interfaces). New language modules that + unavoidably require a numeric suffix in their nickname should include + that number in all uses, or be prepared to kludge.</P> +<P> The nickname is used in four places:</P> +<TABLE summary="nickname table"> +<TR><TD><B>usage</B></TD><TD><B>transform</B></TD></TR> +<TR><TD>"skip" tag</TD><TD>(none)</TD></TR> +<TR><TD>Examples/ subdir name</TD><TD>(none)</TD></TR> +<TR><TD>Examples/GIFPlot/ subdir name</TD><TD>capitalize (upcase first + letter)</TD></TR> +<TR><TD>Examples/test-suite/ subdir name</TD><TD>(none)</TD></TR> + +<!-- add more uses here (remember to adjust header) --> +</TABLE> +<P> As you can see, most usages are direct.</P> +<DL> +<DT><B> configure.in</B></DT> +<DD> This file is processed by +<P> <A HREF="http://www.gnu.org/software/autoconf/">autoconf</A> to + generate the <TT>configure</TT> script. This is where you need to add + shell script fragments and autoconf macros to detect the presence of + whatever development support your language module requires, typically + directories where headers and libraries can be found, and/or utility + programs useful for integrating the generated wrapper code.</P> +<P> Use the <TT>AC_ARG_WITH</TT>, <TT>AC_MSG_CHECKING</TT>, <TT>AC_SUBST</TT> + macros and so forth (see other languages for examples). Avoid using the + <TT>[</TT> and <TT>]</TT> character in shell script fragments. The + variable names passed to <TT>AC_SUBST</TT> should begin with the + nickname, entirely upcased.</P> +<P> At the end of the new section is the place to put the aforementioned + nickname kludges (should they be needed). See Perl5 for examples of + what to do. [If this is still unclear after you've read the code, ping + me and I'll expand on this further. --ttn]</P> +</DD> +<DT><B> Makefile.in</B></DT> +<DD> +<P> Some of the variables AC_SUBSTituted are essential to the support of + your language module. Fashion these into a shell script "test" clause + and assign that to a skip tag using "-z" and "-o":</P> +<DIV class="code"> <TT>skip-qux99 = [ -z "@QUX99INCLUDE@" -o -z + "@QUX99LIBS" ]</TT></DIV> +<P> This means if those vars should ever be empty, qux99 support should + be considered absent and so it would be a good idea to skip actions + that might rely on it.</P> +<P> Here is where you may also define an alias (but then you'll need to + kludge --- don't do this):</P> +<DIV class="code"> <TT>skip-qux = $(skip-qux99)</TT></DIV> +<P> Lastly, you need to modify each of <TT>check-aliveness</TT>, <TT> +check-examples</TT>, <TT>check-test-suite</TT>, <TT>check-gifplot</TT> + (all targets) and <TT>lib-languages</TT> (var). Use the nickname for + these, not the alias. Note that you can do this even before you have + any tests or examples set up; the Makefile rules do some sanity + checking and skip around these kinds of problems.</P> +</DD> +<DT><B> Examples/Makefile.in</B></DT> +<DD> Nothing special here; see comments at top the of this file and look + to the existing languages for examples.</DD> +<DT><B> Examples/qux99/check.list</B></DT> +<DD> Do <TT>cp ../python/check.list .</TT> and modify to taste. One + subdir per line.</DD> +<DT><B> Examples/GIFPlot/Qux99/check.list</B></DT> +<DD> Do <TT>cp ../Python/check.list .</TT> and modify to taste. One + subdir per line.</DD> +<DT><B> Lib/qux99/extra-install.list</B></DT> +<DD> If you add your language to the top-level Makefile.in var <TT> +lib-languages</TT>, then <TT>make install</TT> will install all <TT>*.i</TT> + and <TT>*.swg</TT> files from the language-specific subdirectory of <TT> +Lib</TT>. Use (optional) file <TT>extra-install.list</TT> in that + directory to name additional files to install (see ruby for example).</DD> +<DT><B> Source/Modules/Makefile.am</B></DT> +<DD> Add appropriate files to this Automake file. That's it! +<P> When you have modified these files, please make sure that the new + language module is completely ignored if it is not installed and + detected on a box, that is, <TT>make check-examples</TT> and <TT>make + check-test-suite</TT> politely displays the ignoring language message.</P> +</DD> +</DL> +<H3><A name="Extending_nn40"></A>35.10.9 Runtime support</H3> +<P> Discuss the kinds of functions typically needed for SWIG runtime + support (e.g. <TT>SWIG_ConvertPtr()</TT> and <TT>SWIG_NewPointerObj()</TT> +) and the names of the SWIG files that implement those functions.</P> +<H3><A name="Extending_nn41"></A>35.10.10 Standard library files</H3> +<P> The standard library files that most languages supply keeps growing + as SWIG matures. The following are the minimum that are usually + supported:</P> +<UL> +<LI> typemaps.i</LI> +<LI> std_string.i</LI> +<LI> std_vector.i</LI> +<LI> stl.i</LI> +</UL> +<P> Please copy these and modify for any new language.</P> +<H3><A name="Extending_nn42"></A>35.10.11 Examples and test cases</H3> +<P> Each of the language modules provides one or more examples. These + examples are used to demonstrate different features of the language + module to SWIG end-users, but you'll find that they're useful during + development and testing of your language module as well. You can use + examples from the existing SWIG language modules for inspiration.</P> +<P> Each example is self-contained and consists of (at least) a <TT> +Makefile</TT>, a SWIG interface file for the example module, and a + 'runme' script that demonstrates the functionality for that module. All + of these files are stored in the same subdirectory under the <TT> +Examples/[lang]</TT> directory. There are two classic examples which + should be the first to convert to a new language module. These are the + "simple" C example and the "class" C++ example. These can be found, for + example for Python, in <TT>Examples/python/simple</TT> and <TT> +Examples/python/class</TT>.</P> +<P> By default, all of the examples are built and run when the user + types <TT>make check</TT>. To ensure that your examples are + automatically run during this process, see the section on <A href="#n37a"> +configuration files</A>.</P> +<H3><A name="Extending_nn43"></A>35.10.12 Documentation</H3> +<P> Don't forget to write end-user documentation for your language + module. Currently, each language module has a dedicated chapter You + shouldn't rehash things that are already covered in sufficient detail + in the <A href="#SWIG">SWIG Basics</A> and <A href="#SWIGPlus">SWIG and + C++</A> chapters. There is no fixed format for<EM> what</EM>, exactly, + you should document about your language module, but you'll obviously + want to cover issues that are unique to your language.</P> +<P> Some topics that you'll want to be sure to address include:</P> +<UL> +<LI> Command line options unique to your language module.</LI> +<LI> Non-obvious mappings between C/C++ and target language concepts. + For example, if your target language provides a single floating point + type, it should be no big surprise to find that C/C++ <TT>float</TT> + and <TT>double</TT> types are mapped to it. On the other hand, if your + target language doesn't provide support for "classes" or something + similar, you'd want to discuss how C++ classes are handled.</LI> +<LI> How to compile the SWIG-generated wrapper code into shared + libraries that can actually be used. For some languages, there are + well-defined procedures for doing this, but for others it's an ad hoc + process. Provide as much detail as appropriate, and links to other + resources if available.</LI> +</UL> +<H3><A name="Extending_prerequisites"></A>35.10.13 Prerequisites for + adding a new language module to the SWIG distribution</H3> +<P> If you wish for a new language module to be distributed with SWIG, + which we encourage for all popular languages, there are a few + requirements. While we appreciate that getting all aspects of a new + language working won't happen at the outset, there are a set of minimum + requirements before a module can be committed into the SVN repository + for distribution with future versions of SWIG. The following are really + a summary of this whole section with details being outlined earlier on.</P> +<OL> +<LI> Demonstrate basic C code working by porting the "simple" example + including a runtime test, see for example <TT>Examples/python/simple</TT> +.</LI> +<LI> Demonstrate basic C++ code working by porting the "class" example + including a runtime test, see for example <TT>Examples/python/class</TT> +.</LI> +<LI> Modify <TT>configure.in</TT>, <TT>Makefile.in</TT> and <TT> +Examples/Makefile.in</TT> to run these examples. Please make sure that + if the new language is not installed properly on a box, <TT>make -k + check</TT> should still work by skipping the tests and examples for the + new language module.</LI> +<LI> Get the test-suite running for the new language (<TT>make + check-[lang]-test-suite</TT>). While the test-suite tests many corner + cases, we'd expect the majority of it to work by compiling the + generated code correctly as most of the corner cases are covered in the + SWIG core. Get at least one C and one C++ runtime test running in the + test-suite.</LI> +<LI> Provide a chapter in the html documentation on the basics of using + the language module.</LI> +<LI> Ensure your source code is formatted according to the <A href="#Extending_coding_style_guidelines"> +coding style guidelines</A>.</LI> +<LI> Finally, email the SWIG developers with a patch and a demonstration + of commitment to maintaining the language module, certainly in the + short term and ideally long term.</LI> +</OL> +<P> Once accepted into SVN, development efforts should concentrate on + getting the entire test-suite to work with plenty of runtime tests. + Runtime tests should be for existing testcases and new test cases + should be added should there be an area not already covered by the + existing tests.</P> +<H3><A name="Extending_coding_style_guidelines"></A>35.10.14 Coding + style guidelines</H3> +<P> The coding guidelines for the C/C++ source code are pretty much K&R + C style. The style can be inferred from the existing code base and is + largely dictated by the <TT>indent</TT> code beautifier tool set to K&R + style. The code can formatted using the make targets in the Source + directory. Below is an example of how to format the emit.cxx file:</P> +<BLOCKQUOTE> +<PRE> +$ cd Source +$ make beautify-file INDENTFILE=Modules/emit.cxx +</PRE> +</BLOCKQUOTE> +<P> Of particular note is indentation is set to 2 spaces and a tab is + used instead of 8 spaces. The generated C/C++ code should also follow + this style as close as possible. However, tabs should be avoided as + unlike the SWIG developers, users will never have consistent tab + settings.</P> +<H2><A name="Extending_nn44"></A>35.11 Typemaps</H2> +<H3><A name="Extending_nn45"></A>35.11.1 Proxy classes</H3> +<H2><A name="Extending_nn46"></A>35.12 Guide to parse tree nodes</H2> +<P> This section describes the different parse tree nodes and their + attributes.</P> +<P><B> cdecl</B></P> +<P> Describes general C declarations including variables, functions, and + typedefs. A declaration is parsed as "storage T D" where storage is a + storage class, T is a base type, and D is a declarator.</P> +<DIV class="diagram"> +<PRE> +"name" - Declarator name +"type" - Base type T +"decl" - Declarator type (abstract) +"storage" - Storage class (static, extern, typedef, etc.) +"parms" - Function parameters (if a function) +"code" - Function body code (if supplied) +"value" - Default value (if supplied) +</PRE> +</DIV> +<P><B> constructor</B></P> +<P> C++ constructor declaration.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of constructor +"parms" - Parameters +"decl" - Declarator (function with parameters) +"code" - Function body code (if any) +"feature:new" - Set to indicate return of new object. +</PRE> +</DIV> +<P><B> destructor</B></P> +<P> C++ destructor declaration.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of destructor +"code" - Function body code (if any) +"storage" - Storage class (set if virtual) +"value" - Default value (set if pure virtual). +</PRE> +</DIV> +<P><B> access</B></P> +<P> C++ access change.</P> +<DIV class="diagram"> +<PRE> +"kind" - public, protected, private +</PRE> +</DIV> +<P><B> constant</B></P> +<P> Constant created by %constant or #define.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of constant. +"type" - Base type. +"value" - Value. +"storage" - Set to %constant +"feature:immutable" - Set to indicate read-only +</PRE> +</DIV> +<P><B> class</B></P> +<P> C++ class definition or C structure definition.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of the class. +"kind" - Class kind ("struct", "union", "class") +"symtab" - Enclosing symbol table. +"tdname" - Typedef name. Use for typedef struct { ... } A. +"abstract" - Set if class has pure virtual methods. +"baselist" - List of base class names. +"storage" - Storage class (if any) +"unnamed" - Set if class is unnamed. +</PRE> +</DIV> +<P><B> enum</B></P> +<P> Enumeration.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of the enum (if supplied). +"storage" - Storage class (if any) +"tdname" - Typedef name (typedef enum { ... } name). +"unnamed" - Set if enum is unnamed. +</PRE> +</DIV> +<P><B> enumitem</B></P> +<P> Enumeration value.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of the enum value. +"type" - Type (integer or char) +"value" - Enum value (if given) +"feature:immutable" - Set to indicate read-only +</PRE> +</DIV> +<P><B> namespace</B></P> +<P> C++ namespace.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of the namespace. +"symtab" - Symbol table for enclosed scope. +"unnamed" - Set if unnamed namespace +"alias" - Alias name. Set for namespace A = B; +</PRE> +</DIV> +<P><B> using</B></P> +<P> C++ using directive.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of the object being referred to. +"uname" - Qualified name actually given to using. +"node" - Node being referenced. +"namespace" - Namespace name being reference (using namespace name) +</PRE> +</DIV> +<P><B> classforward</B></P> +<P> A forward C++ class declaration.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of the class. +"kind" - Class kind ("union", "struct", "class") +</PRE> +</DIV> +<P><B> insert</B></P> +<P> Code insertion directive. For example, %{ ... %} or + %insert(section).</P> +<DIV class="diagram"> +<PRE> +"code" - Inserted code +"section" - Section name ("header", "wrapper", etc.) +</PRE> +</DIV> +<P><B> top</B></P> +<P> Top of the parse tree.</P> +<DIV class="diagram"> +<PRE> +"module" - Module name +</PRE> +</DIV> +<P><B> extend</B></P> +<P> %extend directive.</P> +<DIV class="diagram"> +<PRE> +"name" - Module name +"symtab" - Symbol table of enclosed scope. +</PRE> +</DIV> +<P><B> apply</B></P> +<P> %apply pattern { patternlist }.</P> +<DIV class="diagram"> +<PRE> +"pattern" - Source pattern. +"symtab" - Symbol table of enclosed scope. +</PRE> +</DIV> +<P><B> clear</B></P> +<P> %clear patternlist;</P> +<DIV class="diagram"> +<PRE> +"firstChild" - Patterns to clear +</PRE> +</DIV> +<P><B> include</B></P> +<P> %include directive.</P> +<DIV class="diagram"> +<PRE> +"name" - Filename +"firstChild" - Children +</PRE> +</DIV> +<P><B> import</B></P> +<P> %import directive.</P> +<DIV class="diagram"> +<PRE> +"name" - Filename +"firstChild" - Children +</PRE> +</DIV> +<P><B> module</B></P> +<P> %module directive.</P> +<DIV class="diagram"> +<PRE> +"name" - Name of the module +</PRE> +</DIV> +<P><B> typemap</B></P> +<P> %typemap directive.</P> +<DIV class="diagram"> +<PRE> +"method" - Typemap method name. +"code" - Typemap code. +"kwargs" - Keyword arguments (if any) +"firstChild" - Typemap patterns +</PRE> +</DIV> +<P><B> typemapcopy</B></P> +<P> %typemap directive with copy.</P> +<DIV class="diagram"> +<PRE> +"method" - Typemap method name. +"pattern" - Typemap source pattern. +"firstChild" - Typemap patterns +</PRE> +</DIV> +<P><B> typemapitem</B></P> +<P> %typemap pattern. Used with %apply, %clear, %typemap.</P> +<DIV class="diagram"> +<PRE> +"pattern" - Typemap pattern (a parameter list) +"parms" - Typemap parameters. +</PRE> +</DIV> +<P><B> types</B></P> +<P> %types directive.</P> +<DIV class="diagram"> +<PRE> +"parms" - List of parameter types. +"convcode" - Code which replaces the default casting / conversion code +</PRE> +</DIV> +<P><B> extern</B></P> +<P> extern "X" { ... } declaration.</P> +<DIV class="diagram"> +<PRE> +"name" - Name "C", "Fortran", etc. +</PRE> +</DIV></BODY> +</HTML>
\ No newline at end of file |
