66329 lines
2.4 MiB
66329 lines
2.4 MiB
<!DOCTYPE html>
|
|
<HTML>
|
|
<HEAD>
|
|
<TITLE>SWIG-4.3 Documentation</TITLE>
|
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=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;
|
|
font-family: "Courier New", Courier, "Courier 10 Pitch", monospace;
|
|
}
|
|
|
|
div.targetlang {
|
|
border-style: solid;
|
|
border-width: 1px;
|
|
padding: 2pt;
|
|
margin-left: 4em;
|
|
margin-right: 4em;
|
|
background-color: #d7f6bb;
|
|
font-family: "Courier New", Courier, "Courier 10 Pitch", monospace;
|
|
}
|
|
|
|
div.shell {
|
|
border-style: solid;
|
|
border-width: 1px;
|
|
padding: 2pt;
|
|
margin-left: 4em;
|
|
margin-right: 4em;
|
|
background-color: #DCDCDC;
|
|
font-family: "Courier New", Courier, "Courier 10 Pitch", monospace;
|
|
}
|
|
|
|
div.diagram {
|
|
border-style: solid;
|
|
border-width: 1px;
|
|
padding: 2pt;
|
|
margin-left: 4em;
|
|
margin-right: 4em;
|
|
background-color: #FFEBCD;
|
|
font-family: "Courier New", Courier, "Courier 10 Pitch", monospace;
|
|
}
|
|
|
|
div.diagram li {
|
|
margin-left: 0;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
pre, code, tt {
|
|
font-family: "Courier New", Courier, "Courier 10 Pitch", monospace;
|
|
}
|
|
|
|
body { font-family: serif; }
|
|
|
|
--></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-4.3 Documentation"><BR>
|
|
<H1>SWIG-4.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-4.3 Documentation</a></b>
|
|
<ul>
|
|
<li><a HREF="#Sections_Sections">Sections</a>
|
|
<ul>
|
|
<li><a HREF="#Sections_core_docs">SWIG Core Documentation</a></li>
|
|
<li><a HREF="#Sections_language_modules">Supported Language Modules
|
|
Documentation</a></li>
|
|
<li><a HREF="#Sections_experimental_language_modules">Experimental
|
|
Language Modules Documentation</a></li>
|
|
<li><a HREF="#Sections_deprecated_language_modules">Deprecated Language
|
|
Modules Documentation</a></li>
|
|
<li><a HREF="#Sections_developers_docs">Developer Documentation</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_nn4">1.2 SWIG Versions</a></li>
|
|
<li><a HREF="#Preface_license">1.3 SWIG License</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_release_notes">1.9 Release notes</a></li>
|
|
<li><a HREF="#Preface_nn10">1.10 Credits</a></li>
|
|
<li><a HREF="#Preface_nn11">1.11 Bug reports</a></li>
|
|
<li><a HREF="#Preface_installation">1.12 Installation</a>
|
|
<ul>
|
|
<li><a HREF="#Preface_windows_installation">1.12.1 Windows installation</a>
|
|
</li>
|
|
<li><a HREF="#Preface_unix_installation">1.12.2 Unix installation</a></li>
|
|
<li><a HREF="#Preface_osx_installation">1.12.3 Macintosh OS X
|
|
installation</a></li>
|
|
<li><a HREF="#Preface_testing">1.12.4 Testing</a></li>
|
|
<li><a HREF="#Preface_examples">1.12.5 Examples</a></li>
|
|
</ul>
|
|
</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_target_languages">2.3 Target languages</a>
|
|
<ul>
|
|
<li><a HREF="#Introduction_supported_status">2.3.1 Supported status</a></li>
|
|
<li><a HREF="#Introduction_experimental_status">2.3.2 Experimental
|
|
status</a></li>
|
|
<li><a HREF="#Introduction_deprecated_status">2.3.3 Deprecated status</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Introduction_nn4">2.4 A SWIG example</a>
|
|
<ul>
|
|
<li><a HREF="#Introduction_nn5">2.4.1 SWIG interface file</a></li>
|
|
<li><a HREF="#Introduction_nn6">2.4.2 The swig command</a></li>
|
|
<li><a HREF="#Introduction_nn7">2.4.3 Building a Perl5 module</a></li>
|
|
<li><a HREF="#Introduction_nn8">2.4.4 Building a Python module</a></li>
|
|
<li><a HREF="#Introduction_nn9">2.4.5 Shortcuts</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Introduction_nn10">2.5 Supported C/C++ language features</a>
|
|
</li>
|
|
<li><a HREF="#Introduction_nn11">2.6 Non-intrusive interface building</a>
|
|
</li>
|
|
<li><a HREF="#Introduction_build_system">2.7 Incorporating SWIG into a
|
|
build system</a></li>
|
|
<li><a HREF="#Introduction_nn12">2.8 Hands off code generation</a></li>
|
|
<li><a HREF="#Introduction_nn13">2.9 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_python">3.2.1.3 Python</a></li>
|
|
<li><a HREF="#Windows_tcl">3.2.1.4 TCL</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_swig_exe">3.3 Building swig.exe on Windows</a>
|
|
<ul>
|
|
<li><a HREF="#Windows_cmake">3.3.1 Building swig.exe using CMake</a></li>
|
|
<li><a HREF="#Windows_msys2">3.3.2 Building swig.exe using MSYS2 and
|
|
MinGW-w64</a></li>
|
|
<li><a HREF="#Windows_mingw_msys">3.3.3 Building swig.exe using MinGW
|
|
and MSYS</a></li>
|
|
<li><a HREF="#Windows_cygwin">3.3.4 Building swig.exe using Cygwin</a>
|
|
<ul>
|
|
<li><a HREF="#Windows_examples_cygwin">3.3.4.1 Running the examples on
|
|
Windows using Cygwin</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Windows_interface_file">3.4 Microsoft extensions and other
|
|
Windows quirks</a>
|
|
<ul>
|
|
<li><a HREF="#Windows_msvc_cpp_standards">3.4.1 Visual C++ standards
|
|
compliance</a></li>
|
|
<li><a HREF="#Windows_calling_conventions">3.4.2 Calling conventions</a></li>
|
|
</ul>
|
|
</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="#SWIG_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>
|
|
<li><a HREF="#SWIG_parse_tree">5.1.7 Parse tree</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>
|
|
<ul>
|
|
<li><a HREF="#SWIG_nn29">5.4.7.1 Simple renaming of specific identifiers</a>
|
|
</li>
|
|
<li><a HREF="#SWIG_ignore">5.4.7.2 Ignoring identifiers</a></li>
|
|
<li><a HREF="#SWIG_advanced_renaming">5.4.7.3 Advanced renaming support</a>
|
|
</li>
|
|
<li><a HREF="#SWIG_limiting_renaming">5.4.7.4 Limiting global renaming
|
|
rules</a></li>
|
|
<li><a HREF="#SWIG_chosen_unignore">5.4.7.5 Ignoring everything then
|
|
wrapping a few selected symbols</a></li>
|
|
</ul>
|
|
</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_nn15">6.7 Protection</a></li>
|
|
<li><a HREF="#SWIGPlus_nn16">6.8 Enums and constants</a></li>
|
|
<li><a HREF="#SWIGPlus_nn17">6.9 Friends</a>
|
|
<ul>
|
|
<li><a HREF="#SWIGPlus_friend_classes">6.9.1 Friend classes</a></li>
|
|
<li><a HREF="#SWIGPlus_friend_function_definitions">6.9.2 Friend
|
|
function definitions</a></li>
|
|
<li><a HREF="#SWIGPlus_friend_function_declarations">6.9.3 Friend
|
|
function declarations</a></li>
|
|
<li><a HREF="#SWIGPlus_friends_unqualified">6.9.4 Unqualified friend
|
|
functions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#SWIGPlus_nn18">6.10 References and pointers</a></li>
|
|
<li><a HREF="#SWIGPlus_nn19">6.11 Pass and return by value</a></li>
|
|
<li><a HREF="#SWIGPlus_nn20">6.12 Inheritance</a></li>
|
|
<li><a HREF="#SWIGPlus_nn21">6.13 A brief discussion of multiple
|
|
inheritance, pointers, and type checking</a></li>
|
|
<li><a HREF="#SWIGPlus_default_args">6.14 Default arguments</a></li>
|
|
<li><a HREF="#SWIGPlus_overloaded_methods">6.15 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="#SWIGPlus_ambiguity_resolution_renaming">6.15.3 Renaming
|
|
and ambiguity resolution</a></li>
|
|
<li><a HREF="#SWIGPlus_nn27">6.15.4 Comments on overloading</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#SWIGPlus_nn28">6.16 Overloaded operators</a></li>
|
|
<li><a HREF="#SWIGPlus_class_extension">6.17 Class extension</a>
|
|
<ul>
|
|
<li><a HREF="#SWIGPlus_replacing_methods">6.17.1 Replacing class methods</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#SWIGPlus_nn30">6.18 Templates</a>
|
|
<ul>
|
|
<li><a HREF="#SWIGPlus_template_directive">6.18.1 The %template
|
|
directive</a></li>
|
|
<li><a HREF="#SWIGPlus_template_functions">6.18.2 Function templates</a></li>
|
|
<li><a HREF="#SWIGPlus_template_classes">6.18.3 Default template
|
|
arguments</a></li>
|
|
<li><a HREF="#SWIGPlus_template_class_inheritance">6.18.4 Template base
|
|
classes</a></li>
|
|
<li><a HREF="#SWIGPlus_template_empty">6.18.5 Empty template
|
|
instantiation</a></li>
|
|
<li><a HREF="#SWIGPlus_template_specialization">6.18.6 Template
|
|
specialization</a></li>
|
|
<li><a HREF="#SWIGPlus_template_member">6.18.7 Member templates</a></li>
|
|
<li><a HREF="#SWIGPlus_template_scoping">6.18.8 Scoping and templates</a>
|
|
</li>
|
|
<li><a HREF="#SWIGPlus_template_more">6.18.9 More on templates</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#SWIGPlus_namespaces">6.19 Namespaces</a>
|
|
<ul>
|
|
<li><a HREF="#SWIGPlus_nspace">6.19.1 The nspace feature for namespaces</a>
|
|
<ul>
|
|
<li><a HREF="#SWIGPlus_nspace_feature_flag">6.19.1.1 %nspace for
|
|
mirroring namespace hierarchies</a></li>
|
|
<li><a HREF="#SWIGPlus_nspacemove">6.19.1.2 %nspacemove for modifying
|
|
namespace hierarchies</a></li>
|
|
<li><a HREF="#SWIGPlus_nspace_more">6.19.1.3 More about the nspace
|
|
feature</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</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_smart_pointers">6.24 Smart pointers and
|
|
operator->()</a></li>
|
|
<li><a HREF="#SWIGPlus_ref_unref">6.25 C++ reference counted objects -
|
|
ref/unref feature</a></li>
|
|
<li><a HREF="#SWIGPlus_nn35">6.26 Using declarations and inheritance</a></li>
|
|
<li><a HREF="#SWIGPlus_nested_classes">6.27 Nested classes</a></li>
|
|
<li><a HREF="#SWIGPlus_const">6.28 A brief rant about const-correctness</a>
|
|
</li>
|
|
<li><a HREF="#SWIGPlus_target_language_callbacks">6.29 Callbacks to the
|
|
target language</a>
|
|
<ul>
|
|
<li><a HREF="#SWIGPlus_director_classes_introduction">6.29.1
|
|
Introduction to director classes</a></li>
|
|
<li><a HREF="#SWIGPlus_directors_for_function_pointers">6.29.2 Using
|
|
directors and target language callbacks</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#SWIGPlus_nn42">6.30 Where to go for more information</a></li>
|
|
</ul>
|
|
<b><a HREF="#CPlusPlus11">7 SWIG and C++11</a></b>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus11_introduction">7.1 Introduction</a></li>
|
|
<li><a HREF="#CPlusPlus11_core_language_changes">7.2 Core language
|
|
changes</a>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus11_rvalue_reference_and_move_semantics">7.2.1
|
|
Rvalue reference and move semantics</a>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus11_rvalue_reference_inputs">7.2.1.1 Rvalue
|
|
reference inputs</a></li>
|
|
<li><a HREF="#CPlusPlus11_rvalue_reference_outputs">7.2.1.2 Rvalue
|
|
reference outputs</a></li>
|
|
<li><a HREF="#CPlusPlus11_move_only">7.2.1.3 Movable and move-only types
|
|
by value</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus11_generalized_constant_expressions">7.2.2
|
|
Generalized constant expressions</a></li>
|
|
<li><a HREF="#CPlusPlus11_extern_template">7.2.3 Extern template</a></li>
|
|
<li><a HREF="#CPlusPlus11_initializer_lists">7.2.4 Initializer lists</a></li>
|
|
<li><a HREF="#CPlusPlus11_uniform_initialization">7.2.5 Uniform
|
|
initialization</a></li>
|
|
<li><a HREF="#CPlusPlus11_type_inference">7.2.6 Type inference</a></li>
|
|
<li><a HREF="#CPlusPlus11_range_based_for_loop">7.2.7 Range-based
|
|
for-loop</a></li>
|
|
<li><a HREF="#CPlusPlus11_lambda_functions_and_expressions">7.2.8 Lambda
|
|
functions and expressions</a></li>
|
|
<li><a HREF="#CPlusPlus11_alternate_function_syntax">7.2.9 Alternate
|
|
function syntax</a></li>
|
|
<li><a HREF="#CPlusPlus11_object_construction_improvement">7.2.10 Object
|
|
construction improvement</a></li>
|
|
<li><a HREF="#CPlusPlus11_explicit_overrides_final">7.2.11 Explicit
|
|
overrides and final</a></li>
|
|
<li><a HREF="#CPlusPlus11_null_pointer_constant">7.2.12 Null pointer
|
|
constant</a></li>
|
|
<li><a HREF="#CPlusPlus11_strongly_typed_enumerations">7.2.13 Strongly
|
|
typed enumerations</a></li>
|
|
<li><a HREF="#CPlusPlus11_double_angle_brackets">7.2.14 Double angle
|
|
brackets</a></li>
|
|
<li><a HREF="#CPlusPlus11_explicit_conversion_operators">7.2.15 Explicit
|
|
conversion operators</a></li>
|
|
<li><a HREF="#CPlusPlus11_alias_templates">7.2.16 Type alias and alias
|
|
templates</a></li>
|
|
<li><a HREF="#CPlusPlus11_unrestricted_unions">7.2.17 Unrestricted
|
|
unions</a></li>
|
|
<li><a HREF="#CPlusPlus11_variadic_templates">7.2.18 Variadic templates</a>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus11_new_char_literals">7.2.19 New character
|
|
literals</a></li>
|
|
<li><a HREF="#CPlusPlus11_new_string_literals">7.2.20 New string
|
|
literals</a></li>
|
|
<li><a HREF="#CPlusPlus11_user_defined_literals">7.2.21 User-defined
|
|
literals</a></li>
|
|
<li><a HREF="#CPlusPlus11_thread_local_storage">7.2.22 Thread-local
|
|
storage</a></li>
|
|
<li><a HREF="#CPlusPlus11_defaulted_deleted">7.2.23 Explicitly defaulted
|
|
functions and deleted functions</a></li>
|
|
<li><a HREF="#CPlusPlus11_type_long_long_int">7.2.24 Type long long int</a>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus11_static_assertions">7.2.25 Static assertions</a>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus11_sizeof">7.2.26 Allow sizeof to work on members
|
|
of classes without an explicit object</a></li>
|
|
<li><a HREF="#CPlusPlus11_noexcept">7.2.27 Exception specifications and
|
|
noexcept</a></li>
|
|
<li><a HREF="#CPlusPlus11_alignment">7.2.28 Control and query object
|
|
alignment</a></li>
|
|
<li><a HREF="#CPlusPlus11_attributes">7.2.29 Attributes</a></li>
|
|
<li><a HREF="#CPlusPlus11_ref_qualifiers">7.2.30 Methods with
|
|
ref-qualifiers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus11_standard_library_changes">7.3 Standard library
|
|
changes</a>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus11_threading_facilities">7.3.1 Threading
|
|
facilities</a></li>
|
|
<li><a HREF="#CPlusPlus11_tuple_types">7.3.2 Tuple types</a></li>
|
|
<li><a HREF="#CPlusPlus11_hash_tables">7.3.3 Hash tables</a></li>
|
|
<li><a HREF="#CPlusPlus11_regular_expressions">7.3.4 Regular expressions</a>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus11_general_purpose_smart_pointers">7.3.5
|
|
General-purpose smart pointers</a></li>
|
|
<li><a HREF="#CPlusPlus11_extensible_random_number_facility">7.3.6
|
|
Extensible random number facility</a></li>
|
|
<li><a HREF="#CPlusPlus11_wrapper_reference">7.3.7 Wrapper reference</a></li>
|
|
<li><a HREF="#CPlusPlus11_polymorphous_wrappers_for_function_objects">
|
|
7.3.8 Polymorphic wrappers for function objects</a></li>
|
|
<li><a HREF="#CPlusPlus11_type_traits_for_metaprogramming">7.3.9 Type
|
|
traits for metaprogramming</a></li>
|
|
<li><a HREF="#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">
|
|
7.3.10 Uniform method for computing return type of function objects</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#CPlusPlus14">8 SWIG and C++14</a></b>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus14_introduction">8.1 Introduction</a></li>
|
|
<li><a HREF="#CPlusPlus14_core_language_changes">8.2 Core language
|
|
changes</a>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus14_binary_literals">8.2.1 Binary integer literals</a>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus14_return_type_deduction">8.2.2 Return type
|
|
deduction</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus14_standard_library_changes">8.3 Standard library
|
|
changes</a></li>
|
|
</ul>
|
|
<b><a HREF="#CPlusPlus17">9 SWIG and C++17</a></b>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus17_introduction">9.1 Introduction</a></li>
|
|
<li><a HREF="#CPlusPlus17_core_language_changes">9.2 Core language
|
|
changes</a>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus17_nested_namespaces">9.2.1 Nested namespace
|
|
definitions</a></li>
|
|
<li><a HREF="#CPlusPlus17_u8_char_literals">9.2.2 UTF-8 character
|
|
literals</a></li>
|
|
<li><a HREF="#CPlusPlus17_hexadecimal_floating_literals">9.2.3
|
|
Hexadecimal floating literals</a></li>
|
|
<li><a HREF="#CPlusPlus17_fold_expressions">9.2.4 Fold expressions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus17_standard_library_changes">9.3 Standard library
|
|
changes</a></li>
|
|
</ul>
|
|
<b><a HREF="#CPlusPlus20">10 SWIG and C++20</a></b>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus20_introduction">10.1 Introduction</a></li>
|
|
<li><a HREF="#CPlusPlus20_core_language_changes">10.2 Core language
|
|
changes</a>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus20_spaceship_operator">10.2.1 Spaceship operator</a>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus20_lambda_templates">10.2.2 Lambda templates</a></li>
|
|
<li><a HREF="#CPlusPlus20_constexpr_destructors">10.2.3 Constexpr
|
|
destructors</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus20_preprocessor_changes">10.3 Preprocessor
|
|
changes</a>
|
|
<ul>
|
|
<li><a HREF="#CPlusPlus20_va_opt">10.3.1 __VA_OPT__()</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CPlusPlus20_standard_library_changes">10.4 Standard
|
|
library changes</a></li>
|
|
</ul>
|
|
<b><a HREF="#Preprocessor">11 Preprocessing</a></b>
|
|
<ul>
|
|
<li><a HREF="#Preprocessor_nn2">11.1 File inclusion</a></li>
|
|
<li><a HREF="#Preprocessor_nn3">11.2 File imports</a></li>
|
|
<li><a HREF="#Preprocessor_condition_compilation">11.3 Conditional
|
|
Compilation</a></li>
|
|
<li><a HREF="#Preprocessor_nn5">11.4 Macro Expansion</a></li>
|
|
<li><a HREF="#Preprocessor_nn6">11.5 SWIG Macros</a></li>
|
|
<li><a HREF="#Preprocessor_nn7">11.6 Variadic Macros</a></li>
|
|
<li><a HREF="#Preprocessor_delimiters">11.7 Preprocessing and delimiters</a>
|
|
<ul>
|
|
<li><a HREF="#Preprocessor_nn8">11.7.1 Preprocessing and %{ ... %} & "
|
|
... " delimiters</a></li>
|
|
<li><a HREF="#Preprocessor_nn9">11.7.2 Preprocessing and { ... }
|
|
delimiters</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Preprocessor_typemap_delimiters">11.8 Preprocessor and
|
|
Typemaps</a></li>
|
|
<li><a HREF="#Preprocessor_nn10">11.9 Viewing preprocessor output</a></li>
|
|
<li><a HREF="#Preprocessor_warning_error">11.10 The #error and #warning
|
|
directives</a></li>
|
|
<li><a HREF="#Preprocessor_trigraphs">11.11 Trigraphs</a></li>
|
|
<li><a HREF="#Preprocessor_digraphs">11.12 Digraphs</a></li>
|
|
</ul>
|
|
<b><a HREF="#Library">12 SWIG library</a></b>
|
|
<ul>
|
|
<li><a HREF="#Library_nn2">12.1 The %include directive and library
|
|
search path</a></li>
|
|
<li><a HREF="#Library_nn3">12.2 C arrays and pointers</a>
|
|
<ul>
|
|
<li><a HREF="#Library_argcargv">12.2.1 argcargv.i</a></li>
|
|
<li><a HREF="#Library_nn4">12.2.2 cpointer.i</a></li>
|
|
<li><a HREF="#Library_carrays">12.2.3 carrays.i</a></li>
|
|
<li><a HREF="#Library_nn6">12.2.4 cmalloc.i</a></li>
|
|
<li><a HREF="#Library_nn7">12.2.5 cdata.i</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Library_nn8">12.3 C string handling</a>
|
|
<ul>
|
|
<li><a HREF="#Library_nn9">12.3.1 Default string handling</a></li>
|
|
<li><a HREF="#Library_nn10">12.3.2 Passing a string with length</a></li>
|
|
<li><a HREF="#Library_nn11">12.3.3 Using %newobject to release memory</a>
|
|
</li>
|
|
<li><a HREF="#Library_nn12">12.3.4 cstring.i</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Library_c_standard_library">12.4 C standard library</a>
|
|
<ul>
|
|
<li><a HREF="#Library_complex">12.4.1 Complex floating types</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Library_stl_cpp_library">12.5 STL/C++ library</a>
|
|
<ul>
|
|
<li><a HREF="#Library_std_string">12.5.1 std::string</a></li>
|
|
<li><a HREF="#Library_std_string_view">12.5.2 std::string_view</a></li>
|
|
<li><a HREF="#Library_std_vector">12.5.3 std::vector</a></li>
|
|
<li><a HREF="#Library_stl_exceptions">12.5.4 STL exceptions</a></li>
|
|
<li><a HREF="#Library_std_shared_ptr">12.5.5 shared_ptr smart pointer</a>
|
|
<ul>
|
|
<li><a HREF="#Library_shared_ptr_basics">12.5.5.1 shared_ptr basics</a></li>
|
|
<li><a HREF="#Library_shared_ptr_inheritance">12.5.5.2 shared_ptr and
|
|
inheritance</a></li>
|
|
<li><a HREF="#Library_shared_ptr_overloading">12.5.5.3 shared_ptr and
|
|
method overloading</a></li>
|
|
<li><a HREF="#Library_shared_ptr_templates">12.5.5.4 shared_ptr and
|
|
templates</a></li>
|
|
<li><a HREF="#Library_shared_ptr_directors">12.5.5.5 shared_ptr and
|
|
directors</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Library_std_unique_ptr">12.5.6 unique_ptr smart pointer</a>
|
|
<ul>
|
|
<li><a HREF="#Library_std_unique_ptr_by_value">12.5.6.1 unique_ptr
|
|
passed by value</a></li>
|
|
<li><a HREF="#Library_std_unique_ptr_by_ref">12.5.6.2 unique_ptr passed
|
|
by reference</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Library_std_auto_ptr">12.5.7 auto_ptr smart pointer</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Library_nn16">12.6 Utility Libraries</a>
|
|
<ul>
|
|
<li><a HREF="#Library_nn17">12.6.1 exception.i</a></li>
|
|
<li><a HREF="#Library_attributes">12.6.2 attribute.i</a>
|
|
<ul>
|
|
<li><a HREF="#Library_attribute_templates">12.6.2.1 %attribute and C++
|
|
templates</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Arguments">13 Argument Handling</a></b>
|
|
<ul>
|
|
<li><a HREF="#Arguments_nn2">13.1 The typemaps.i library</a>
|
|
<ul>
|
|
<li><a HREF="#Arguments_nn3">13.1.1 Introduction</a></li>
|
|
<li><a HREF="#Arguments_nn4">13.1.2 Input parameters</a></li>
|
|
<li><a HREF="#Arguments_nn5">13.1.3 Output parameters</a></li>
|
|
<li><a HREF="#Arguments_nn6">13.1.4 Input/Output parameters</a></li>
|
|
<li><a HREF="#Arguments_nn7">13.1.5 Using different names</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Arguments_nn8">13.2 Applying constraints to input values</a>
|
|
<ul>
|
|
<li><a HREF="#Arguments_nn9">13.2.1 Simple constraint example</a></li>
|
|
<li><a HREF="#Arguments_nn10">13.2.2 Constraint methods</a></li>
|
|
<li><a HREF="#Arguments_nn11">13.2.3 Applying constraints to new
|
|
datatypes</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Typemaps">14 Typemaps</a></b>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_nn2">14.1 Introduction</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_nn3">14.1.1 Type conversion</a></li>
|
|
<li><a HREF="#Typemaps_nn4">14.1.2 Typemaps</a></li>
|
|
<li><a HREF="#Typemaps_nn5">14.1.3 Pattern matching</a></li>
|
|
<li><a HREF="#Typemaps_nn6">14.1.4 Reusing typemaps</a></li>
|
|
<li><a HREF="#Typemaps_nn7">14.1.5 What can be done with typemaps?</a></li>
|
|
<li><a HREF="#Typemaps_nn8">14.1.6 What can't be done with typemaps?</a></li>
|
|
<li><a HREF="#Typemaps_aspects">14.1.7 Similarities to Aspect Oriented
|
|
Programming</a></li>
|
|
<li><a HREF="#Typemaps_nn9">14.1.8 The rest of this chapter</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_nn10">14.2 Typemap specifications</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_defining">14.2.1 Defining a typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn12">14.2.2 Typemap scope</a></li>
|
|
<li><a HREF="#Typemaps_nn13">14.2.3 Copying a typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn14">14.2.4 Deleting a typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn15">14.2.5 Placement of typemaps</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_pattern_matching">14.3 Pattern matching rules</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_nn17">14.3.1 Basic matching rules</a></li>
|
|
<li><a HREF="#Typemaps_typedef_reductions">14.3.2 Typedef reductions
|
|
matching</a></li>
|
|
<li><a HREF="#Typemaps_nn19">14.3.3 Default typemap matching rules</a></li>
|
|
<li><a HREF="#Typemaps_multi_argument_typemaps_patterns">14.3.4
|
|
Multi-arguments typemaps</a></li>
|
|
<li><a HREF="#Typemaps_matching_template_comparison">14.3.5 Matching
|
|
rules compared to C++ templates</a></li>
|
|
<li><a HREF="#Typemaps_debugging_search">14.3.6 Debugging typemap
|
|
pattern matching</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_nn21">14.4 Code generation rules</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_nn22">14.4.1 Scope</a></li>
|
|
<li><a HREF="#Typemaps_nn23">14.4.2 Declaring new local variables</a></li>
|
|
<li><a HREF="#Typemaps_special_variables">14.4.3 Special variables</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_type_special_variables">14.4.3.1 Type related
|
|
special variables</a></li>
|
|
<li><a HREF="#Typemaps_non_type_special_variables">14.4.3.2 Non-type
|
|
related special variables</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_special_variable_macros">14.4.4 Special variable
|
|
macros</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_special_macro_descriptor">14.4.4.1
|
|
$descriptor(type)</a></li>
|
|
<li><a HREF="#Typemaps_special_macro_typemap">14.4.4.2 $typemap(method,
|
|
typepattern)</a></li>
|
|
<li><a HREF="#Typemaps_special_macro_typemap_attribute">14.4.4.3
|
|
$typemap(method:attribute, typepattern)</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_special_variable_attributes">14.4.5 Special
|
|
variables and typemap attributes</a></li>
|
|
<li><a HREF="#Typemaps_special_variables_and_macros">14.4.6 Special
|
|
variables combined with special variable macros</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_nn25">14.5 Common typemap methods</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_nn26">14.5.1 "in" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn27">14.5.2 "typecheck" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn28">14.5.3 "out" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn29">14.5.4 "arginit" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn30">14.5.5 "default" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn31">14.5.6 "check" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn32">14.5.7 "argout" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn33">14.5.8 "freearg" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn34">14.5.9 "newfree" typemap</a></li>
|
|
<li><a HREF="#Typemaps_ret">14.5.10 "ret" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn35">14.5.11 "memberin" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn36">14.5.12 "varin" typemap</a></li>
|
|
<li><a HREF="#Typemaps_nn37">14.5.13 "varout" typemap</a></li>
|
|
<li><a HREF="#Typemaps_throws_typemap">14.5.14 "throws" typemap</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_nn39">14.6 Some typemap examples</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_nn40">14.6.1 Typemaps for arrays</a></li>
|
|
<li><a HREF="#Typemaps_nn41">14.6.2 Implementing constraints with
|
|
typemaps</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_nn43">14.7 Typemaps for multiple target languages</a>
|
|
</li>
|
|
<li><a HREF="#Typemaps_optimal">14.8 Optimal code generation when
|
|
returning by value</a></li>
|
|
<li><a HREF="#Typemaps_multi_argument_typemaps">14.9 Multi-argument
|
|
typemaps</a></li>
|
|
<li><a HREF="#Typemaps_warnings">14.10 Typemap warnings</a></li>
|
|
<li><a HREF="#Typemaps_fragments">14.11 Typemap fragments</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_fragment_type_specialization">14.11.1 Fragment
|
|
type specialization</a></li>
|
|
<li><a HREF="#Typemaps_automatic_specialization">14.11.2 Fragments and
|
|
automatic typemap specialization</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_runtime_type_checker">14.12 The run-time type
|
|
checker</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_nn45">14.12.1 Implementation</a></li>
|
|
<li><a HREF="#Typemaps_runtime_type_checker_usage">14.12.2 Usage</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_overloading">14.13 Typemaps and overloading</a>
|
|
<ul>
|
|
<li><a HREF="#Typemaps_typecheck_pointer">14.13.1 SWIG_TYPECHECK_POINTER
|
|
precedence level and the typecheck typemap</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Typemaps_nn48">14.14 More about %apply and %clear</a></li>
|
|
<li><a HREF="#Typemaps_nn47">14.15 Passing data between typemaps</a></li>
|
|
<li><a HREF="#Typemaps_nn52">14.16 C++ "this" pointer</a></li>
|
|
<li><a HREF="#Typemaps_nn51">14.17 Where to go for more information?</a></li>
|
|
</ul>
|
|
<b><a HREF="#Customization">15 Customization Features</a></b>
|
|
<ul>
|
|
<li><a HREF="#Customization_exception">15.1 Exception handling with
|
|
%exception</a>
|
|
<ul>
|
|
<li><a HREF="#Customization_nn3">15.1.1 Handling exceptions in C code</a>
|
|
</li>
|
|
<li><a HREF="#Customization_nn4">15.1.2 Exception handling with
|
|
longjmp()</a></li>
|
|
<li><a HREF="#Customization_nn5">15.1.3 Handling C++ exceptions</a></li>
|
|
<li><a HREF="#Customization_allowexcept">15.1.4 Exception handlers for
|
|
variables</a></li>
|
|
<li><a HREF="#Customization_nn6">15.1.5 Defining different exception
|
|
handlers</a></li>
|
|
<li><a HREF="#Customization_exception_special_variables">15.1.6 Special
|
|
variables for %exception</a></li>
|
|
<li><a HREF="#Customization_nn7">15.1.7 Using The SWIG exception library</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Customization_ownership">15.2 Object ownership and
|
|
%newobject</a></li>
|
|
<li><a HREF="#Customization_features">15.3 Features and the %feature
|
|
directive</a>
|
|
<ul>
|
|
<li><a HREF="#Customization_feature_attributes">15.3.1 Feature
|
|
attributes</a></li>
|
|
<li><a HREF="#Customization_feature_flags">15.3.2 Feature flags</a></li>
|
|
<li><a HREF="#Customization_clearing_features">15.3.3 Clearing features</a>
|
|
</li>
|
|
<li><a HREF="#Customization_features_default_args">15.3.4 Features and
|
|
default arguments</a></li>
|
|
<li><a HREF="#Customization_features_example">15.3.5 Feature example</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Contract">16 Contracts</a></b>
|
|
<ul>
|
|
<li><a HREF="#Contract_nn2">16.1 The %contract directive</a></li>
|
|
<li><a HREF="#Contract_nn3">16.2 %contract and classes</a></li>
|
|
<li><a HREF="#Contract_nn4">16.3 Constant aggregation and
|
|
%aggregate_check</a></li>
|
|
<li><a HREF="#Contract_nn5">16.4 Notes</a></li>
|
|
</ul>
|
|
<b><a HREF="#Varargs">17 Variable Length Arguments</a></b>
|
|
<ul>
|
|
<li><a HREF="#Varargs_nn2">17.1 Introduction</a></li>
|
|
<li><a HREF="#Varargs_nn3">17.2 The Problem</a></li>
|
|
<li><a HREF="#Varargs_nn4">17.3 Default varargs support</a></li>
|
|
<li><a HREF="#Varargs_nn5">17.4 Argument replacement using %varargs</a></li>
|
|
<li><a HREF="#Varargs_nn6">17.5 Varargs and typemaps</a></li>
|
|
<li><a HREF="#Varargs_nn7">17.6 Varargs wrapping with libffi</a></li>
|
|
<li><a HREF="#Varargs_nn8">17.7 Wrapping of va_list</a></li>
|
|
<li><a HREF="#Varargs_nn9">17.8 C++ Issues</a></li>
|
|
<li><a HREF="#Varargs_nn10">17.9 Discussion</a></li>
|
|
</ul>
|
|
<b><a HREF="#Doxygen">18 SWIG and Doxygen Translation</a></b>
|
|
<ul>
|
|
<li><a HREF="#Doxygen_translation_overview">18.1 Doxygen translation
|
|
overview</a></li>
|
|
<li><a HREF="#Doxygen_file_preparation">18.2 Preparations</a>
|
|
<ul>
|
|
<li><a HREF="#Doxygen_running_swig">18.2.1 Enabling Doxygen translation</a>
|
|
</li>
|
|
<li><a HREF="#Doxygen_features">18.2.2 Doxygen-specific %feature
|
|
directives</a>
|
|
<ul>
|
|
<li><a HREF="#Doxygen_notranslate">18.2.2.1 doxygen:notranslate</a></li>
|
|
<li><a HREF="#Doxygen_alias">18.2.2.2 doxygen:alias:<command-name></a></li>
|
|
<li><a HREF="#Doxygen_ignore">18.2.2.3 doxygen:ignore:<command-name></a></li>
|
|
<li><a HREF="#Doxygen_nolinktranslate">18.2.2.4 doxygen:nolinktranslate</a>
|
|
</li>
|
|
<li><a HREF="#Doxygen_nostripparams">18.2.2.5 doxygen:nostripparams</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Doxygen_additional_options">18.2.3 Additional command line
|
|
options</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Doxygen_javadoc">18.3 Doxygen to Javadoc</a>
|
|
<ul>
|
|
<li><a HREF="#Doxygen_javadoc_basic_example">18.3.1 Basic Javadoc
|
|
example</a></li>
|
|
<li><a HREF="#Doxygen_javadoc_tags">18.3.2 Javadoc tags</a></li>
|
|
<li><a HREF="#Doxygen_javadoc_unsupported_tags">18.3.3 Unsupported tags
|
|
for Javadoc</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Doxygen_pydoc">18.4 Doxygen to Pydoc</a>
|
|
<ul>
|
|
<li><a HREF="#Doxygen_pydoc_basic_example">18.4.1 Basic Pydoc example</a>
|
|
</li>
|
|
<li><a HREF="#Doxygen_pydoc_tags">18.4.2 Pydoc translator</a></li>
|
|
<li><a HREF="#Doxygen_pydoc_unsupported_tags">18.4.3 Unsupported tags
|
|
for Pydoc</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Doxygen_csharp">18.5 Doxygen to XML C# documentation</a>
|
|
<ul>
|
|
<li><a HREF="#Doxygen_csharp_basic_example">18.5.1 Basic C# example</a></li>
|
|
<li><a HREF="#Doxygen_csharp_tags">18.5.2 C# tags</a></li>
|
|
<li><a HREF="#Doxygen_csharp_unsupported_tags">18.5.3 Unsupported tags
|
|
for C#</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Doxygen_troubleshooting">18.6 Troubleshooting</a>
|
|
<ul>
|
|
<li><a HREF="#troubleshooting_ifndef">18.6.1 Problem with conditional
|
|
compilation</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Doxygen_developer_details">18.7 Developer information</a>
|
|
<ul>
|
|
<li><a HREF="#Doxygen_translator_design">18.7.1 Doxygen translator
|
|
design</a></li>
|
|
<li><a HREF="#Doxygen_debugging_commands">18.7.2 Debugging the Doxygen
|
|
parser and translator</a></li>
|
|
<li><a HREF="#Doxygen_tests">18.7.3 Tests</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Doxygen_language_extension">18.8 Extending to other
|
|
languages</a></li>
|
|
</ul>
|
|
<b><a HREF="#Warnings">19 Warning Messages</a></b>
|
|
<ul>
|
|
<li><a HREF="#Warnings_nn2">19.1 Introduction</a></li>
|
|
<li><a HREF="#Warnings_suppression">19.2 Warning message suppression</a></li>
|
|
<li><a HREF="#Warnings_nn4">19.3 Enabling extra warnings</a></li>
|
|
<li><a HREF="#Warnings_nn5">19.4 Issuing a warning message</a></li>
|
|
<li><a HREF="#Warnings_symbolic_symbols">19.5 Symbolic symbols</a></li>
|
|
<li><a HREF="#Warnings_nn6">19.6 Commentary</a></li>
|
|
<li><a HREF="#Warnings_nn7">19.7 Warnings as errors</a></li>
|
|
<li><a HREF="#Warnings_nn8">19.8 Message output format</a></li>
|
|
<li><a HREF="#Warnings_nn9">19.9 Warning number reference</a>
|
|
<ul>
|
|
<li><a HREF="#Warnings_nn10">19.9.1 Deprecated features (100-199)</a></li>
|
|
<li><a HREF="#Warnings_nn11">19.9.2 Preprocessor (200-299)</a></li>
|
|
<li><a HREF="#Warnings_nn12">19.9.3 C/C++ Parser (300-399)</a></li>
|
|
<li><a HREF="#Warnings_nn13">19.9.4 Types and typemaps (400-499)</a></li>
|
|
<li><a HREF="#Warnings_nn14">19.9.5 Code generation (500-559)</a></li>
|
|
<li><a HREF="#Warnings_doxygen">19.9.6 Doxygen comments (560-599)</a></li>
|
|
<li><a HREF="#Warnings_nn15">19.9.7 Language module specific (700-899)</a>
|
|
</li>
|
|
<li><a HREF="#Warnings_nn16">19.9.8 User defined (900-999)</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Warnings_nn17">19.10 History</a></li>
|
|
</ul>
|
|
<b><a HREF="#Modules">20 Working with Modules</a></b>
|
|
<ul>
|
|
<li><a HREF="#Modules_introduction">20.1 Modules Introduction</a></li>
|
|
<li><a HREF="#Modules_nn1">20.2 Basics</a></li>
|
|
<li><a HREF="#Modules_nn2">20.3 The SWIG runtime code</a></li>
|
|
<li><a HREF="#Modules_external_run_time">20.4 External access to the
|
|
runtime</a></li>
|
|
<li><a HREF="#Modules_nn4">20.5 A word of caution about static libraries</a>
|
|
</li>
|
|
<li><a HREF="#Modules_nn5">20.6 References</a></li>
|
|
<li><a HREF="#Modules_nn6">20.7 Reducing the wrapper file size</a></li>
|
|
</ul>
|
|
<b><a HREF="#CCache">21 Using SWIG with ccache - ccache-swig(1) manpage</a>
|
|
</b>
|
|
<ul>
|
|
<li><a HREF="#CCache_nn2">21.1 NAME</a></li>
|
|
<li><a HREF="#CCache_nn3">21.2 SYNOPSIS</a></li>
|
|
<li><a HREF="#CCache_nn4">21.3 DESCRIPTION</a></li>
|
|
<li><a HREF="#CCache_nn5">21.4 OPTIONS SUMMARY</a></li>
|
|
<li><a HREF="#CCache_nn6">21.5 OPTIONS</a></li>
|
|
<li><a HREF="#CCache_nn7">21.6 INSTALLATION</a></li>
|
|
<li><a HREF="#CCache_nn8">21.7 EXTRA OPTIONS</a></li>
|
|
<li><a HREF="#CCache_nn9">21.8 ENVIRONMENT VARIABLES</a></li>
|
|
<li><a HREF="#CCache_nn10">21.9 CACHE SIZE MANAGEMENT</a></li>
|
|
<li><a HREF="#CCache_nn11">21.10 CACHE COMPRESSION</a></li>
|
|
<li><a HREF="#CCache_nn12">21.11 HOW IT WORKS</a></li>
|
|
<li><a HREF="#CCache_nn13">21.12 USING CCACHE WITH DISTCC</a></li>
|
|
<li><a HREF="#CCache_nn14">21.13 SHARING A CACHE</a></li>
|
|
<li><a HREF="#CCache_nn15">21.14 HISTORY</a></li>
|
|
<li><a HREF="#CCache_nn16">21.15 DIFFERENCES FROM COMPILERCACHE</a></li>
|
|
<li><a HREF="#CCache_nn17">21.16 CREDITS</a></li>
|
|
<li><a HREF="#CCache_nn18">21.17 AUTHOR</a></li>
|
|
</ul>
|
|
<b><a HREF="#Android">22 SWIG and Android</a></b>
|
|
<ul>
|
|
<li><a HREF="#Android_overview">22.1 Overview</a></li>
|
|
<li><a HREF="#Android_examples">22.2 Android examples</a>
|
|
<ul>
|
|
<li><a HREF="#Android_examples_intro">22.2.1 Examples introduction</a></li>
|
|
<li><a HREF="#Android_example_simple">22.2.2 Simple C example</a></li>
|
|
<li><a HREF="#Android_example_class">22.2.3 C++ class example</a></li>
|
|
<li><a HREF="#Android_examples_other">22.2.4 Other examples</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Android_stl">22.3 C++ STL</a></li>
|
|
</ul>
|
|
<b><a HREF="#CSharp">23 SWIG and C#</a></b>
|
|
<ul>
|
|
<li><a HREF="#CSharp_introduction">23.1 Introduction</a>
|
|
<ul>
|
|
<li><a HREF="#CSharp_introduction_swig2_compatibility">23.1.1 SWIG 2
|
|
Compatibility</a></li>
|
|
<li><a HREF="#CSharp_commandline">23.1.2 Additional command line options</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CSharp_differences_java">23.2 Differences to the Java
|
|
module</a></li>
|
|
<li><a HREF="#CSharp_type_mapping">23.3 Type mapping</a>
|
|
<ul>
|
|
<li><a HREF="#CSharp_primitive_types">23.3.1 Primitive types</a></li>
|
|
<li><a HREF="#CSharp_other_type_mappings">23.3.2 Other types</a></li>
|
|
<li><a HREF="#CSharp_void_pointers">23.3.3 Void pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CSharp_arrays">23.4 C# Arrays</a>
|
|
<ul>
|
|
<li><a HREF="#CSharp_arrays_swig_library">23.4.1 The SWIG C arrays
|
|
library</a></li>
|
|
<li><a HREF="#CSharp_arrays_pinvoke_default_array_marshalling">23.4.2
|
|
Managed arrays using P/Invoke default array marshalling</a></li>
|
|
<li><a HREF="#CSharp_arrays_pinning">23.4.3 Managed arrays using pinning</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CSharp_exceptions">23.5 C# Exceptions</a>
|
|
<ul>
|
|
<li><a HREF="#CSharp_exception_example_check_typemap">23.5.1 C#
|
|
exception example using "check" typemap</a></li>
|
|
<li><a HREF="#CSharp_exception_example_percent_exception">23.5.2 C#
|
|
exception example using %exception</a></li>
|
|
<li><a HREF="#CSharp_exception_example_exception_specifications">23.5.3
|
|
C# exception example using exception specifications</a></li>
|
|
<li><a HREF="#CSharp_custom_application_exception">23.5.4 Custom C#
|
|
ApplicationException example</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CSharp_directors">23.6 C# Directors</a>
|
|
<ul>
|
|
<li><a HREF="#CSharp_directors_example">23.6.1 Directors example</a></li>
|
|
<li><a HREF="#CSharp_directors_implementation">23.6.2 Directors
|
|
implementation</a></li>
|
|
<li><a HREF="#CSharp_director_caveats">23.6.3 Director caveats</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#CSharp_multiple_modules">23.7 Multiple modules</a></li>
|
|
<li><a HREF="#CSharp_named_arguments">23.8 C# named and optional
|
|
arguments</a></li>
|
|
<li><a HREF="#CSharp_typemap_examples">23.9 C# Typemap examples</a>
|
|
<ul>
|
|
<li><a HREF="#CSharp_memory_management_member_variables">23.9.1 Memory
|
|
management when returning references to member variables</a></li>
|
|
<li><a HREF="#CSharp_memory_management_objects">23.9.2 Memory management
|
|
for objects passed to the C++ layer</a></li>
|
|
<li><a HREF="#CSharp_date_marshalling">23.9.3 Date marshalling using the
|
|
csin typemap and associated attributes</a></li>
|
|
<li><a HREF="#CSharp_date_properties">23.9.4 A date example
|
|
demonstrating marshalling of C# properties</a></li>
|
|
<li><a HREF="#CSharp_date_pre_post_directors">23.9.5 Date example
|
|
demonstrating the 'pre' and 'post' typemap attributes for directors</a></li>
|
|
<li><a HREF="#CSharp_partial_classes">23.9.6 Turning proxy classes into
|
|
partial classes</a></li>
|
|
<li><a HREF="#CSharp_sealed_proxy_class">23.9.7 Turning proxy classes
|
|
into sealed classes</a></li>
|
|
<li><a HREF="#CSharp_extending_proxy_class">23.9.8 Extending proxy
|
|
classes with additional C# code</a></li>
|
|
<li><a HREF="#CSharp_enum_underlying_type">23.9.9 Underlying type for
|
|
enums</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#D">24 SWIG and D</a></b>
|
|
<ul>
|
|
<li><a HREF="#D_introduction">24.1 Introduction</a></li>
|
|
<li><a HREF="#D_command_line_invocation">24.2 Command line invocation</a>
|
|
</li>
|
|
<li><a HREF="#D_typemaps">24.3 Typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#D_typemap_name_comparison">24.3.1 C# <-> D name comparison</a>
|
|
</li>
|
|
<li><a HREF="#D_ctype_imtype_dtype">24.3.2 ctype, imtype, dtype</a></li>
|
|
<li><a HREF="#D_in_out_directorin_direcetorout">24.3.3 in, out,
|
|
directorin, directorout</a></li>
|
|
<li><a HREF="#D_din_dout_ddirectorin_ddirectorout">24.3.4 din, dout,
|
|
ddirectorin, ddirectorout</a></li>
|
|
<li><a HREF="#D_typecheck_typemaps">24.3.5 typecheck typemaps</a></li>
|
|
<li><a HREF="#D_code_injection_typemaps">24.3.6 Code injection typemaps</a>
|
|
</li>
|
|
<li><a HREF="#D_special_variables">24.3.7 Special variable macros</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#D_other_code_control">24.4 Other D code control features</a>
|
|
<ul>
|
|
<li><a HREF="#D_module">24.4.1 D begin</a></li>
|
|
<li><a HREF="#D_features">24.4.2 D and %feature</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#D_pragmas">24.5 Pragmas</a></li>
|
|
<li><a HREF="#D_exceptions">24.6 D Exceptions</a></li>
|
|
<li><a HREF="#D_directors">24.7 D Directors</a></li>
|
|
<li><a HREF="#D_other_features">24.8 Other features</a>
|
|
<ul>
|
|
<li><a HREF="#D_nspace">24.8.1 Extended namespace support (nspace)</a></li>
|
|
<li><a HREF="#D_native_pointer_support">24.8.2 Native pointer support</a>
|
|
</li>
|
|
<li><a HREF="#D_operator_overloading">24.8.3 Operator overloading</a></li>
|
|
<li><a HREF="#D_test_suite">24.8.4 Running the test-suite</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#D_typemap_examples">24.9 D Typemap examples</a></li>
|
|
<li><a HREF="#D_planned_features">24.10 Work in progress and planned
|
|
features</a></li>
|
|
</ul>
|
|
<b><a HREF="#Go">25 SWIG and Go</a></b>
|
|
<ul>
|
|
<li><a HREF="#Go_overview">25.1 Overview</a></li>
|
|
<li><a HREF="#Go_examples">25.2 Examples</a></li>
|
|
<li><a HREF="#Go_running_swig">25.3 Running SWIG with Go</a>
|
|
<ul>
|
|
<li><a HREF="#Go_commandline">25.3.1 Go-specific Commandline Options</a></li>
|
|
<li><a HREF="#Go_outputs">25.3.2 Generated Wrapper Files</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Go_basic_tour">25.4 A tour of basic C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#Go_package">25.4.1 Go Package Name</a></li>
|
|
<li><a HREF="#Go_names">25.4.2 Go Names</a></li>
|
|
<li><a HREF="#Go_constants">25.4.3 Go Constants</a></li>
|
|
<li><a HREF="#Go_enumerations">25.4.4 Go Enumerations</a></li>
|
|
<li><a HREF="#Go_classes">25.4.5 Go Classes</a>
|
|
<ul>
|
|
<li><a HREF="#Go_class_memory">25.4.5.1 Go Class Memory Management</a></li>
|
|
<li><a HREF="#Go_class_inheritance">25.4.5.2 Go Class Inheritance</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Go_templates">25.4.6 Go Templates</a></li>
|
|
<li><a HREF="#Go_threads">25.4.7 Go and C/C++ Threads</a></li>
|
|
<li><a HREF="#Go_exceptions">25.4.8 Go and C++ Exceptions</a></li>
|
|
<li><a HREF="#Go_director_classes">25.4.9 Go Director Classes</a>
|
|
<ul>
|
|
<li><a HREF="#Go_director_example_cpp_code">25.4.9.1 Example C++ code</a>
|
|
</li>
|
|
<li><a HREF="#Go_director_enable">25.4.9.2 Enable director feature</a></li>
|
|
<li><a HREF="#Go_director_ctor_dtor">25.4.9.3 Constructor and destructor</a>
|
|
</li>
|
|
<li><a HREF="#Go_director_overriding">25.4.9.4 Override virtual methods</a>
|
|
</li>
|
|
<li><a HREF="#Go_director_base_methods">25.4.9.5 Call base methods</a></li>
|
|
<li><a HREF="#Go_director_subclass">25.4.9.6 Subclass via embedding</a></li>
|
|
<li><a HREF="#Go_director_finalizer">25.4.9.7 Memory management with
|
|
runtime.SetFinalizer</a></li>
|
|
<li><a HREF="#Go_director_foobargo_class">25.4.9.8 Complete FooBarGo
|
|
example class</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Go_primitive_type_mappings">25.4.10 Default Go primitive
|
|
type mappings</a></li>
|
|
<li><a HREF="#Go_output_arguments">25.4.11 Output arguments</a></li>
|
|
<li><a HREF="#Go_adding_additional_code">25.4.12 Adding additional go
|
|
code</a></li>
|
|
<li><a HREF="#Go_typemaps">25.4.13 Go typemaps</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Guile">26 SWIG and Guile</a></b>
|
|
<ul>
|
|
<li><a HREF="#Guile_nn1">26.1 Supported Guile Versions</a></li>
|
|
<li><a HREF="#Guile_nn2">26.2 Meaning of "Module"</a></li>
|
|
<li><a HREF="#Guile_nn3">26.3 Old GH Guile API</a></li>
|
|
<li><a HREF="#Guile_nn4">26.4 Linkage</a>
|
|
<ul>
|
|
<li><a HREF="#Guile_nn5">26.4.1 Simple Linkage</a></li>
|
|
<li><a HREF="#Guile_nn6">26.4.2 Passive Linkage</a></li>
|
|
<li><a HREF="#Guile_nn7">26.4.3 Native Guile Module Linkage</a></li>
|
|
<li><a HREF="#Guile_nn8">26.4.4 Old Auto-Loading Guile Module Linkage</a>
|
|
</li>
|
|
<li><a HREF="#Guile_nn9">26.4.5 Hobbit4D Linkage</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Guile_nn10">26.5 Underscore Folding</a></li>
|
|
<li><a HREF="#Guile_nn11">26.6 Typemaps</a></li>
|
|
<li><a HREF="#Guile_nn12">26.7 Representation of pointers as smobs</a>
|
|
<ul>
|
|
<li><a HREF="#Guile_nn14">26.7.1 Smobs</a></li>
|
|
<li><a HREF="#Guile_nn15">26.7.2 Garbage Collection</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Guile_nn16">26.8 Native Guile pointers</a></li>
|
|
<li><a HREF="#Guile_nn17">26.9 Exception Handling</a></li>
|
|
<li><a HREF="#Guile_nn18">26.10 Procedure documentation</a></li>
|
|
<li><a HREF="#Guile_nn19">26.11 Procedures with setters</a></li>
|
|
<li><a HREF="#Guile_nn20">26.12 GOOPS Proxy Classes</a>
|
|
<ul>
|
|
<li><a HREF="#Guile_nn21">26.12.1 Naming Issues</a></li>
|
|
<li><a HREF="#Guile_nn22">26.12.2 Linking</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Java">27 SWIG and Java</a></b>
|
|
<ul>
|
|
<li><a HREF="#Java_overview">27.1 Overview</a></li>
|
|
<li><a HREF="#Java_preliminaries">27.2 Preliminaries</a>
|
|
<ul>
|
|
<li><a HREF="#Java_running_swig">27.2.1 Running SWIG</a></li>
|
|
<li><a HREF="#Java_commandline">27.2.2 Additional Commandline Options</a>
|
|
</li>
|
|
<li><a HREF="#Java_getting_right_headers">27.2.3 Getting the right
|
|
header files</a></li>
|
|
<li><a HREF="#Java_compiling_dynamic">27.2.4 Compiling a dynamic module</a>
|
|
</li>
|
|
<li><a HREF="#Java_using_module">27.2.5 Using your module</a></li>
|
|
<li><a HREF="#Java_dynamic_linking_problems">27.2.6 Dynamic linking
|
|
problems</a></li>
|
|
<li><a HREF="#Java_compilation_problems_cpp">27.2.7 Compilation problems
|
|
and compiling with C++</a></li>
|
|
<li><a HREF="#Java_building_windows">27.2.8 Building on Windows</a>
|
|
<ul>
|
|
<li><a HREF="#Java_visual_studio">27.2.8.1 Running SWIG from Visual
|
|
Studio</a></li>
|
|
<li><a HREF="#Java_nmake">27.2.8.2 Using NMAKE</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_basic_tour">27.3 A tour of basic C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#Java_module_packages_classes">27.3.1 Modules, packages and
|
|
generated Java classes</a></li>
|
|
<li><a HREF="#Java_functions">27.3.2 Functions</a></li>
|
|
<li><a HREF="#Java_global_variables">27.3.3 Global variables</a></li>
|
|
<li><a HREF="#Java_constants">27.3.4 Constants</a></li>
|
|
<li><a HREF="#Java_enumerations">27.3.5 Enumerations</a>
|
|
<ul>
|
|
<li><a HREF="#Java_anonymous_enums">27.3.5.1 Anonymous enums</a></li>
|
|
<li><a HREF="#Java_typesafe_enums">27.3.5.2 Typesafe enums</a></li>
|
|
<li><a HREF="#Java_proper_enums">27.3.5.3 Proper Java enums</a></li>
|
|
<li><a HREF="#Java_typeunsafe_enums">27.3.5.4 Type unsafe enums</a></li>
|
|
<li><a HREF="#Java_simple_enums">27.3.5.5 Simple enums</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_pointers">27.3.6 Pointers</a></li>
|
|
<li><a HREF="#Java_structures">27.3.7 Structures</a></li>
|
|
<li><a HREF="#Java_classes">27.3.8 C++ classes</a></li>
|
|
<li><a HREF="#Java_inheritance">27.3.9 C++ inheritance</a></li>
|
|
<li><a HREF="#Java_pointers_refs_arrays">27.3.10 Pointers, references,
|
|
arrays and pass by value</a>
|
|
<ul>
|
|
<li><a HREF="#Java_null_pointers">27.3.10.1 Null pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_overloaded_functions">27.3.11 C++ overloaded
|
|
functions</a></li>
|
|
<li><a HREF="#Java_default_arguments">27.3.12 C++ default arguments</a></li>
|
|
<li><a HREF="#Java_namespaces">27.3.13 C++ namespaces</a></li>
|
|
<li><a HREF="#Java_templates">27.3.14 C++ templates</a></li>
|
|
<li><a HREF="#Java_smart_pointers">27.3.15 C++ Smart Pointers</a>
|
|
<ul>
|
|
<li><a HREF="#Java_smart_pointers_shared_ptr">27.3.15.1 The shared_ptr
|
|
Smart Pointer</a></li>
|
|
<li><a HREF="#Java_smart_pointers_generic">27.3.15.2 Generic Smart
|
|
Pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_further_details">27.4 Further details on the
|
|
generated Java classes</a>
|
|
<ul>
|
|
<li><a HREF="#Java_imclass">27.4.1 The intermediary JNI class</a>
|
|
<ul>
|
|
<li><a HREF="#Java_imclass_pragmas">27.4.1.1 The intermediary JNI class
|
|
pragmas</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_module_class">27.4.2 The Java module class</a>
|
|
<ul>
|
|
<li><a HREF="#Java_module_class_pragmas">27.4.2.1 The Java module class
|
|
pragmas</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_constants_interface">27.4.3 The Java constants
|
|
interface</a>
|
|
<ul>
|
|
<li><a HREF="#Java_constants_interface_pragmas">27.4.3.1 The Java
|
|
constants interface pragmas</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_proxy_classes">27.4.4 Java proxy classes</a>
|
|
<ul>
|
|
<li><a HREF="#Java_memory_management">27.4.4.1 Memory management</a></li>
|
|
<li><a HREF="#Java_inheritance_mirroring">27.4.4.2 Inheritance</a></li>
|
|
<li><a HREF="#Java_proxy_classes_gc">27.4.4.3 Proxy classes and garbage
|
|
collection</a></li>
|
|
<li><a HREF="#Java_pgcpp">27.4.4.4 The premature garbage collection
|
|
prevention parameter for proxy class marshalling</a></li>
|
|
<li><a HREF="#Java_multithread_libraries">27.4.4.5 Single threaded
|
|
applications and thread safety</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_type_wrapper_classes">27.4.5 Type wrapper classes</a></li>
|
|
<li><a HREF="#Java_enum_classes">27.4.6 Enum classes</a>
|
|
<ul>
|
|
<li><a HREF="#Java_typesafe_enums_classes">27.4.6.1 Typesafe enum
|
|
classes</a></li>
|
|
<li><a HREF="#Java_proper_enums_classes">27.4.6.2 Proper Java enum
|
|
classes</a></li>
|
|
<li><a HREF="#Java_typeunsafe_enums_classes">27.4.6.3 Type unsafe enum
|
|
classes</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_interfaces">27.4.7 Interfaces</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_directors">27.5 Cross language polymorphism using
|
|
directors</a>
|
|
<ul>
|
|
<li><a HREF="#Java_enabling_directors">27.5.1 Enabling directors</a></li>
|
|
<li><a HREF="#Java_directors_classes">27.5.2 Director classes</a></li>
|
|
<li><a HREF="#Java_directors_overhead">27.5.3 Overhead and code bloat</a>
|
|
</li>
|
|
<li><a HREF="#Java_directors_example">27.5.4 Simple directors example</a>
|
|
</li>
|
|
<li><a HREF="#Java_directors_threading">27.5.5 Director threading issues</a>
|
|
</li>
|
|
<li><a HREF="#Java_directors_performance">27.5.6 Director performance
|
|
tuning</a></li>
|
|
<li><a HREF="#Java_exceptions_from_directors">27.5.7 Java exceptions
|
|
from directors</a>
|
|
<ul>
|
|
<li><a HREF="#Java_customizing_director_exceptions">27.5.7.1 Customizing
|
|
director exceptions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_protected_virtual_methods">27.5.8 Accessing virtual
|
|
protected methods</a></li>
|
|
<li><a HREF="#Java_allprotected">27.5.9 Accessing non-virtual protected
|
|
members</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_common_customization">27.6 Common customization
|
|
features</a>
|
|
<ul>
|
|
<li><a HREF="#Java_helper_functions">27.6.1 C/C++ helper functions</a></li>
|
|
<li><a HREF="#Java_class_extension">27.6.2 Class extension with %extend</a>
|
|
</li>
|
|
<li><a HREF="#Java_proxycode">27.6.3 Class extension with %proxycode</a></li>
|
|
<li><a HREF="#Java_exception_handling">27.6.4 Exception handling with
|
|
%exception and %javaexception</a></li>
|
|
<li><a HREF="#Java_method_access">27.6.5 Method access with
|
|
%javamethodmodifiers</a></li>
|
|
<li><a HREF="#Java_begin">27.6.6 Java begin</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_tips_techniques">27.7 Tips and techniques</a>
|
|
<ul>
|
|
<li><a HREF="#Java_input_output_parameters">27.7.1 Input and output
|
|
parameters using primitive pointers and references</a></li>
|
|
<li><a HREF="#Java_simple_pointers">27.7.2 Simple pointers</a></li>
|
|
<li><a HREF="#Java_c_arrays">27.7.3 Wrapping C arrays with Java arrays</a>
|
|
</li>
|
|
<li><a HREF="#Java_unbounded_c_arrays">27.7.4 Unbounded C Arrays</a></li>
|
|
<li><a HREF="#Java_string_length">27.7.5 Passing a string with length</a>
|
|
</li>
|
|
<li><a HREF="#Java_heap_allocations">27.7.6 Overriding new and delete to
|
|
allocate from Java heap</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_typemaps">27.8 Java typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#Java_default_primitive_type_mappings">27.8.1 Default
|
|
primitive type mappings</a></li>
|
|
<li><a HREF="#Java_default_non_primitive_typemaps">27.8.2 Default
|
|
typemaps for non-primitive types</a></li>
|
|
<li><a HREF="#Java_jvm64">27.8.3 Sixty four bit JVMs</a></li>
|
|
<li><a HREF="#Java_what_is_typemap">27.8.4 What is a typemap?</a></li>
|
|
<li><a HREF="#Java_typemaps_c_to_java_types">27.8.5 Typemaps for mapping
|
|
C/C++ types to Java types</a></li>
|
|
<li><a HREF="#Java_typemap_attributes">27.8.6 Java typemap attributes</a>
|
|
</li>
|
|
<li><a HREF="#Java_special_variables">27.8.7 Java special variables</a></li>
|
|
<li><a HREF="#Java_typemaps_for_c_and_cpp">27.8.8 Typemaps for both C
|
|
and C++ compilation</a></li>
|
|
<li><a HREF="#Java_code_typemaps">27.8.9 Java code typemaps</a></li>
|
|
<li><a HREF="#Java_directors_typemaps">27.8.10 Director specific
|
|
typemaps</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_typemap_examples">27.9 Typemap Examples</a>
|
|
<ul>
|
|
<li><a HREF="#Java_simpler_enum_classes">27.9.1 Simpler Java enums for
|
|
enums without initializers</a></li>
|
|
<li><a HREF="#Java_exception_typemap">27.9.2 Handling C++ exception
|
|
specifications as Java exceptions</a></li>
|
|
<li><a HREF="#Java_nan_exception_typemap">27.9.3 NaN Exception -
|
|
exception handling for a particular type</a></li>
|
|
<li><a HREF="#Java_converting_java_string_arrays">27.9.4 Converting Java
|
|
String arrays to char **</a></li>
|
|
<li><a HREF="#Java_expanding_java_object">27.9.5 Expanding a Java object
|
|
to multiple arguments</a></li>
|
|
<li><a HREF="#Java_using_typemaps_return_arguments">27.9.6 Using
|
|
typemaps to return arguments</a></li>
|
|
<li><a HREF="#Java_adding_downcasts">27.9.7 Adding Java downcasts to
|
|
polymorphic return types</a></li>
|
|
<li><a HREF="#Java_adding_equals_method">27.9.8 Adding an equals method
|
|
to the Java classes</a></li>
|
|
<li><a HREF="#Java_void_pointers">27.9.9 Void pointers and a common Java
|
|
base class</a></li>
|
|
<li><a HREF="#Java_struct_pointer_pointer">27.9.10 Struct pointer to
|
|
pointer</a></li>
|
|
<li><a HREF="#Java_memory_management_member_variables">27.9.11 Memory
|
|
management when returning references to member variables</a></li>
|
|
<li><a HREF="#Java_memory_management_objects">27.9.12 Memory management
|
|
for objects passed to the C++ layer</a></li>
|
|
<li><a HREF="#Java_date_marshalling">27.9.13 Date marshalling using the
|
|
javain typemap and associated attributes</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_directors_faq">27.10 Living with Java Directors</a></li>
|
|
<li><a HREF="#Java_odds_ends">27.11 Odds and ends</a>
|
|
<ul>
|
|
<li><a HREF="#Java_javadoc_comments">27.11.1 JavaDoc comments</a></li>
|
|
<li><a HREF="#Java_functional_interface">27.11.2 Functional interface
|
|
without proxy classes</a></li>
|
|
<li><a HREF="#Java_using_own_jni_functions">27.11.3 Using your own JNI
|
|
functions</a></li>
|
|
<li><a HREF="#Java_performance">27.11.4 Performance concerns and hints</a>
|
|
</li>
|
|
<li><a HREF="#Java_debugging">27.11.5 Debugging</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Java_examples">27.12 Java Examples</a></li>
|
|
</ul>
|
|
<b><a HREF="#Javascript">28 SWIG and Javascript</a></b>
|
|
<ul>
|
|
<li><a HREF="#Javascript_overview">28.1 Overview</a></li>
|
|
<li><a HREF="#Javascript_preliminaries">28.2 Preliminaries</a>
|
|
<ul>
|
|
<li><a HREF="#Javascript_running_swig">28.2.1 Running SWIG</a></li>
|
|
<li><a HREF="#Javascript_running_tests_examples">28.2.2 Running Tests
|
|
and Examples</a></li>
|
|
<li><a HREF="#Javascript_known_issues">28.2.3 Known Issues</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Javascript_integration">28.3 Integration</a>
|
|
<ul>
|
|
<li><a HREF="#Javascript_node_extensions">28.3.1 Creating node.js
|
|
Extensions</a>
|
|
<ul>
|
|
<li><a HREF="#Javascript_using_yeoman">28.3.1.1 Using yeoman to generate
|
|
a Node-API skeleton</a></li>
|
|
<li><a HREF="#Javascript_troubleshooting">28.3.1.2 Troubleshooting</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Javascript_embedded_webkit">28.3.2 Embedded Webkit</a>
|
|
<ul>
|
|
<li><a HREF="#Javascript_osx">28.3.2.1 Mac OS X</a></li>
|
|
<li><a HREF="#Javascript_gtk">28.3.2.2 GTK</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Javascript_applications_webkit">28.3.3 Creating
|
|
Applications with node-webkit</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Javascript_examples">28.4 Examples</a>
|
|
<ul>
|
|
<li><a HREF="#Javascript_simple_example">28.4.1 Simple</a></li>
|
|
<li><a HREF="#Javascript_class_example">28.4.2 Class</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Javascript_implementation">28.5 Implementation</a>
|
|
<ul>
|
|
<li><a HREF="#Javascript_source_code">28.5.1 Source Code</a></li>
|
|
<li><a HREF="#Javascript_code_templates">28.5.2 Code Templates</a></li>
|
|
<li><a HREF="#Javascript_emitter">28.5.3 Emitter</a></li>
|
|
<li><a HREF="#Javascript_emitter_states">28.5.4 Emitter states</a></li>
|
|
<li><a HREF="#Javascript_jsc_exceptions">28.5.5 Handling Exceptions in
|
|
JavascriptCore</a></li>
|
|
<li><a HREF="#Javascript_napi_exceptions">28.5.6 Handling Exceptions in
|
|
Node-API</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Lua">29 SWIG and Lua</a></b>
|
|
<ul>
|
|
<li><a HREF="#Lua_nn2">29.1 Preliminaries</a></li>
|
|
<li><a HREF="#Lua_nn3">29.2 Running SWIG</a>
|
|
<ul>
|
|
<li><a HREF="#Lua_commandline">29.2.1 Additional command line options</a>
|
|
</li>
|
|
<li><a HREF="#Lua_nn4">29.2.2 Compiling and Linking and Interpreter</a></li>
|
|
<li><a HREF="#Lua_nn5">29.2.3 Compiling a dynamic module</a></li>
|
|
<li><a HREF="#Lua_nn6">29.2.4 Using your module</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Lua_nn7">29.3 A tour of basic C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#Lua_nn8">29.3.1 Modules</a></li>
|
|
<li><a HREF="#Lua_nn9">29.3.2 Functions</a></li>
|
|
<li><a HREF="#Lua_nn10">29.3.3 Global variables</a></li>
|
|
<li><a HREF="#Lua_nn11">29.3.4 Constants and enums</a>
|
|
<ul>
|
|
<li><a HREF="#Lua_nn13">29.3.4.1 Constants/enums and classes/structures</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Lua_nn12">29.3.5 Pointers</a></li>
|
|
<li><a HREF="#Lua_structures">29.3.6 Structures</a></li>
|
|
<li><a HREF="#Lua_nn14">29.3.7 C++ classes</a></li>
|
|
<li><a HREF="#Lua_nn15">29.3.8 C++ inheritance</a></li>
|
|
<li><a HREF="#Lua_nn16">29.3.9 Pointers, references, values, and arrays</a>
|
|
</li>
|
|
<li><a HREF="#Lua_nn17">29.3.10 C++ overloaded functions</a></li>
|
|
<li><a HREF="#Lua_nn18">29.3.11 C++ operators</a></li>
|
|
<li><a HREF="#Lua_nn19">29.3.12 Class extension with %extend</a></li>
|
|
<li><a HREF="#Lua_nn20">29.3.13 Using %newobject to release memory</a></li>
|
|
<li><a HREF="#Lua_nn21">29.3.14 C++ templates</a></li>
|
|
<li><a HREF="#Lua_nn22">29.3.15 C++ Smart Pointers</a></li>
|
|
<li><a HREF="#Lua_nn23">29.3.16 C++ Exceptions</a></li>
|
|
<li><a HREF="#Lua_namespaces">29.3.17 Namespaces</a>
|
|
<ul>
|
|
<li><a HREF="#Lua_nn27">29.3.17.1 Compatibility Note</a></li>
|
|
<li><a HREF="#Lua_nn29">29.3.17.2 Names</a></li>
|
|
<li><a HREF="#Lua_nn30">29.3.17.3 Inheritance</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Lua_nn24">29.4 Typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#Lua_nn25">29.4.1 What is a typemap?</a></li>
|
|
<li><a HREF="#Lua_nn26">29.4.2 Using typemaps</a></li>
|
|
<li><a HREF="#Lua_typemap_arrays">29.4.3 Typemaps and arrays</a></li>
|
|
<li><a HREF="#Lua_typemaps_ptr_ptr_functions">29.4.4 Typemaps and
|
|
pointer-pointer functions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Lua_writing_typemaps">29.5 Writing typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#Lua_typemaps_write">29.5.1 Typemaps you can write</a></li>
|
|
<li><a HREF="#Lua_nn31">29.5.2 SWIG's Lua-C API</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Lua_nn32">29.6 Customization of your Bindings</a>
|
|
<ul>
|
|
<li><a HREF="#Lua_nn33">29.6.1 Writing your own custom wrappers</a></li>
|
|
<li><a HREF="#Lua_nn34">29.6.2 Adding additional Lua code</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Lua_nn35">29.7 Details on the Lua binding</a>
|
|
<ul>
|
|
<li><a HREF="#Lua_nn36">29.7.1 Binding global data into the module.</a></li>
|
|
<li><a HREF="#Lua_nn37">29.7.2 Userdata and Metatables</a></li>
|
|
<li><a HREF="#Lua_nn38">29.7.3 Memory management</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Octave">30 SWIG and Octave</a></b>
|
|
<ul>
|
|
<li><a HREF="#Octave_nn2">30.1 Preliminaries</a></li>
|
|
<li><a HREF="#Octave_nn3">30.2 Running SWIG</a>
|
|
<ul>
|
|
<li><a HREF="#Octave_nn4">30.2.1 Command-line options</a></li>
|
|
<li><a HREF="#Octave_nn5">30.2.2 Compiling a dynamic module</a></li>
|
|
<li><a HREF="#Octave_nn6">30.2.3 Using your module</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Octave_nn7">30.3 A tour of basic C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#Octave_nn8">30.3.1 Modules</a></li>
|
|
<li><a HREF="#Octave_nn9">30.3.2 Functions</a></li>
|
|
<li><a HREF="#Octave_nn10">30.3.3 Global variables</a></li>
|
|
<li><a HREF="#Octave_nn11">30.3.4 Constants and enums</a></li>
|
|
<li><a HREF="#Octave_nn12">30.3.5 Pointers</a></li>
|
|
<li><a HREF="#Octave_nn13">30.3.6 Structures and C++ classes</a></li>
|
|
<li><a HREF="#Octave_nn15">30.3.7 C++ inheritance</a></li>
|
|
<li><a HREF="#Octave_nn17">30.3.8 C++ overloaded functions</a></li>
|
|
<li><a HREF="#Octave_nn18">30.3.9 C++ operators</a></li>
|
|
<li><a HREF="#Octave_nn19">30.3.10 Class extension with %extend</a></li>
|
|
<li><a HREF="#Octave_nn20">30.3.11 C++ templates</a></li>
|
|
<li><a HREF="#Octave_nn21">30.3.12 C++ Smart Pointers</a>
|
|
<ul>
|
|
<li><a HREF="#Octave_smart_pointers_shared_ptr">30.3.12.1 The shared_ptr
|
|
Smart Pointer</a></li>
|
|
<li><a HREF="#Octave_smart_pointers_generic">30.3.12.2 Generic Smart
|
|
Pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Octave_nn22">30.3.13 Directors (calling Octave from C++
|
|
code)</a></li>
|
|
<li><a HREF="#Octave_nn23">30.3.14 Threads</a></li>
|
|
<li><a HREF="#Octave_nn24">30.3.15 Memory management</a></li>
|
|
<li><a HREF="#Octave_nn25">30.3.16 STL support</a></li>
|
|
<li><a HREF="#Octave_nn26">30.3.17 Matrix typemaps</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Perl5">31 SWIG and Perl5</a></b>
|
|
<ul>
|
|
<li><a HREF="#Perl5_nn2">31.1 Overview</a></li>
|
|
<li><a HREF="#Perl5_nn3">31.2 Preliminaries</a>
|
|
<ul>
|
|
<li><a HREF="#Perl5_nn4">31.2.1 Getting the right header files</a></li>
|
|
<li><a HREF="#Perl5_nn5">31.2.2 Compiling a dynamic module</a></li>
|
|
<li><a HREF="#Perl5_nn6">31.2.3 Building a dynamic module with MakeMaker</a>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn7">31.2.4 Building a static version of Perl</a></li>
|
|
<li><a HREF="#Perl5_nn8">31.2.5 Using the module</a></li>
|
|
<li><a HREF="#Perl5_nn9">31.2.6 Compilation problems and compiling with
|
|
C++</a></li>
|
|
<li><a HREF="#Perl5_nn10">31.2.7 Compiling for 64-bit platforms</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn11">31.3 Building Perl Extensions under Windows</a>
|
|
<ul>
|
|
<li><a HREF="#Perl5_nn12">31.3.1 Running SWIG from Developer Studio</a></li>
|
|
<li><a HREF="#Perl5_nn13">31.3.2 Using other compilers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn14">31.4 The low-level interface</a>
|
|
<ul>
|
|
<li><a HREF="#Perl5_nn15">31.4.1 Functions</a></li>
|
|
<li><a HREF="#Perl5_nn16">31.4.2 Global variables</a></li>
|
|
<li><a HREF="#Perl5_nn17">31.4.3 Constants</a></li>
|
|
<li><a HREF="#Perl5_nn18">31.4.4 Pointers</a></li>
|
|
<li><a HREF="#Perl5_nn19">31.4.5 Structures</a></li>
|
|
<li><a HREF="#Perl5_nn20">31.4.6 C++ classes</a></li>
|
|
<li><a HREF="#Perl5_nn21">31.4.7 C++ classes and type-checking</a></li>
|
|
<li><a HREF="#Perl5_nn22">31.4.8 C++ overloaded functions</a></li>
|
|
<li><a HREF="#Perl5_nn23">31.4.9 Operators</a></li>
|
|
<li><a HREF="#Perl5_nn24">31.4.10 Modules and packages</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn25">31.5 Input and output parameters</a></li>
|
|
<li><a HREF="#Perl5_nn26">31.6 Exception handling</a></li>
|
|
<li><a HREF="#Perl5_nn27">31.7 Remapping datatypes with typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#Perl5_nn28">31.7.1 A simple typemap example</a></li>
|
|
<li><a HREF="#Perl5_nn29">31.7.2 Perl5 typemaps</a></li>
|
|
<li><a HREF="#Perl5_nn30">31.7.3 Typemap variables</a></li>
|
|
<li><a HREF="#Perl5_nn31">31.7.4 Useful functions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn32">31.8 Typemap Examples</a>
|
|
<ul>
|
|
<li><a HREF="#Perl5_nn33">31.8.1 Converting a Perl5 array to a char **</a>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn34">31.8.2 Return values</a></li>
|
|
<li><a HREF="#Perl5_nn35">31.8.3 Returning values from arguments</a></li>
|
|
<li><a HREF="#Perl5_nn36">31.8.4 Accessing array structure members</a></li>
|
|
<li><a HREF="#Perl5_nn37">31.8.5 Turning Perl references into C pointers</a>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn38">31.8.6 Pointer handling</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn39">31.9 Proxy classes</a>
|
|
<ul>
|
|
<li><a HREF="#Perl5_nn40">31.9.1 Preliminaries</a></li>
|
|
<li><a HREF="#Perl5_nn41">31.9.2 Structure and class wrappers</a></li>
|
|
<li><a HREF="#Perl5_nn42">31.9.3 Object Ownership</a></li>
|
|
<li><a HREF="#Perl5_nn43">31.9.4 Nested Objects</a></li>
|
|
<li><a HREF="#Perl5_nn44">31.9.5 Proxy Functions</a></li>
|
|
<li><a HREF="#Perl5_nn45">31.9.6 Inheritance</a></li>
|
|
<li><a HREF="#Perl5_nn46">31.9.7 Modifying the proxy methods</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Perl5_nn47">31.10 Adding additional Perl code</a></li>
|
|
<li><a HREF="#Perl5_directors">31.11 Cross language polymorphism</a>
|
|
<ul>
|
|
<li><a HREF="#Perl5_nn48">31.11.1 Enabling directors</a></li>
|
|
<li><a HREF="#Perl5_nn49">31.11.2 Director classes</a></li>
|
|
<li><a HREF="#Perl5_nn50">31.11.3 Ownership and object destruction</a></li>
|
|
<li><a HREF="#Perl5_nn51">31.11.4 Exception unrolling</a></li>
|
|
<li><a HREF="#Perl5_nn52">31.11.5 Overhead and code bloat</a></li>
|
|
<li><a HREF="#Perl5_nn53">31.11.6 Typemaps</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Php">32 SWIG and PHP</a></b>
|
|
<ul>
|
|
<li><a HREF="#Php_nn1">32.1 Generating PHP Extensions</a>
|
|
<ul>
|
|
<li><a HREF="#Php_nn1_1">32.1.1 Building a loadable extension</a></li>
|
|
<li><a HREF="#Php_nn1_3">32.1.2 Using PHP Extensions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Php_nn2">32.2 Basic PHP interface</a>
|
|
<ul>
|
|
<li><a HREF="#Php_nn2_1">32.2.1 Constants</a></li>
|
|
<li><a HREF="#Php_nn2_2">32.2.2 Global Variables</a></li>
|
|
<li><a HREF="#Php_nn2_3">32.2.3 Functions</a></li>
|
|
<li><a HREF="#Php_nn2_4">32.2.4 Overloading</a></li>
|
|
<li><a HREF="#Php_nn2_5">32.2.5 Pointers and References</a></li>
|
|
<li><a HREF="#Php_nn2_6">32.2.6 Structures and C++ classes</a>
|
|
<ul>
|
|
<li><a HREF="#Php_nn2_6_1">32.2.6.1 Using -noproxy</a></li>
|
|
<li><a HREF="#Php_nn2_6_2">32.2.6.2 Constructors and Destructors</a></li>
|
|
<li><a HREF="#Php_nn2_6_3">32.2.6.3 Static Member Variables</a></li>
|
|
<li><a HREF="#Php_nn2_6_4">32.2.6.4 Static Member Functions</a></li>
|
|
<li><a HREF="#Php_nn2_6_5">32.2.6.5 Specifying Implemented Interfaces</a>
|
|
</li>
|
|
<li><a HREF="#Php_nn2_6_6">32.2.6.6 Dynamic Properties</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Php_nn2_7">32.2.7 PHP Pragmas, Startup and Shutdown code</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Php_nn3">32.3 Cross language polymorphism</a>
|
|
<ul>
|
|
<li><a HREF="#Php_nn3_1">32.3.1 Enabling directors</a></li>
|
|
<li><a HREF="#Php_nn3_2">32.3.2 Director classes</a></li>
|
|
<li><a HREF="#Php_nn3_3">32.3.3 Ownership and object destruction</a></li>
|
|
<li><a HREF="#Php_nn3_4">32.3.4 Exception unrolling</a></li>
|
|
<li><a HREF="#Php_nn3_5">32.3.5 Overhead and code bloat</a></li>
|
|
<li><a HREF="#Php_nn3_6">32.3.6 Typemaps</a></li>
|
|
<li><a HREF="#Php_nn3_7">32.3.7 Miscellaneous</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Python">33 SWIG and Python</a></b>
|
|
<ul>
|
|
<li><a HREF="#Python_nn2">33.1 Overview</a></li>
|
|
<li><a HREF="#Python_nn3">33.2 Preliminaries</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn4">33.2.1 Running SWIG</a></li>
|
|
<li><a HREF="#Python_nn6">33.2.2 Using distutils</a></li>
|
|
<li><a HREF="#Python_nn7">33.2.3 Hand compiling a dynamic module</a></li>
|
|
<li><a HREF="#Python_nn8">33.2.4 Static linking</a></li>
|
|
<li><a HREF="#Python_nn9">33.2.5 Using your module</a></li>
|
|
<li><a HREF="#Python_nn10">33.2.6 Compilation of C++ extensions</a></li>
|
|
<li><a HREF="#Python_nn11">33.2.7 Compiling for 64-bit platforms</a></li>
|
|
<li><a HREF="#Python_nn12">33.2.8 Building Python extensions under
|
|
Windows</a></li>
|
|
<li><a HREF="#Python_commandline">33.2.9 Additional Python commandline
|
|
options</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn13">33.3 A tour of basic C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn14">33.3.1 Modules</a></li>
|
|
<li><a HREF="#Python_nn15">33.3.2 Functions</a></li>
|
|
<li><a HREF="#Python_nn16">33.3.3 Global variables</a></li>
|
|
<li><a HREF="#Python_nn17">33.3.4 Constants and enums</a></li>
|
|
<li><a HREF="#Python_nn18">33.3.5 Pointers</a></li>
|
|
<li><a HREF="#Python_nn19">33.3.6 Structures</a></li>
|
|
<li><a HREF="#Python_nn20">33.3.7 C++ classes</a></li>
|
|
<li><a HREF="#Python_nn21">33.3.8 C++ inheritance</a></li>
|
|
<li><a HREF="#Python_nn22">33.3.9 Pointers, references, values, and
|
|
arrays</a></li>
|
|
<li><a HREF="#Python_nn23">33.3.10 C++ overloaded functions</a></li>
|
|
<li><a HREF="#Python_nn24">33.3.11 C++ operators</a></li>
|
|
<li><a HREF="#Python_nn25">33.3.12 C++ namespaces</a></li>
|
|
<li><a HREF="#Python_nn26">33.3.13 C++ templates</a></li>
|
|
<li><a HREF="#Python_nn27">33.3.14 C++ Smart Pointers</a>
|
|
<ul>
|
|
<li><a HREF="#Python_smart_pointers_shared_ptr">33.3.14.1 The shared_ptr
|
|
Smart Pointer</a></li>
|
|
<li><a HREF="#Python_smart_pointers_generic">33.3.14.2 Generic Smart
|
|
Pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn27a">33.3.15 C++ reference counted objects</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn28">33.4 Further details on the Python class
|
|
interface</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn29">33.4.1 Proxy classes</a></li>
|
|
<li><a HREF="#Python_builtin_types">33.4.2 Built-in Types</a>
|
|
<ul>
|
|
<li><a HREF="#Python_builtin_limitations">33.4.2.1 Limitations</a></li>
|
|
<li><a HREF="#Python_builtin_overloads">33.4.2.2 Operator overloads and
|
|
slots -- use them!</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn30">33.4.3 Memory management</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_directors">33.5 Cross language polymorphism</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn33">33.5.1 Enabling directors</a></li>
|
|
<li><a HREF="#Python_nn34">33.5.2 Director classes</a></li>
|
|
<li><a HREF="#Python_nn35">33.5.3 Ownership and object destruction</a></li>
|
|
<li><a HREF="#Python_nn36">33.5.4 Exception unrolling</a></li>
|
|
<li><a HREF="#Python_nn37">33.5.5 Overhead and code bloat</a></li>
|
|
<li><a HREF="#Python_nn38">33.5.6 Typemaps</a></li>
|
|
<li><a HREF="#Python_director_thread_safety">33.5.7 Thread safety</a></li>
|
|
<li><a HREF="#Python_nn39">33.5.8 Miscellaneous</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn40">33.6 Common customization features</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn41">33.6.1 C/C++ helper functions</a></li>
|
|
<li><a HREF="#Python_nn42">33.6.2 Adding additional Python code</a></li>
|
|
<li><a HREF="#Python_nn43">33.6.3 Class extension with %extend</a></li>
|
|
<li><a HREF="#Python_nn44">33.6.4 Exception handling with %exception</a></li>
|
|
<li><a HREF="#Python_optimization">33.6.5 Optimization options</a>
|
|
<ul>
|
|
<li><a HREF="#Python_fastproxy">33.6.5.1 -fastproxy</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_stable_abi">33.6.6 Stable ABI</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn45">33.7 Tips and techniques</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn46">33.7.1 Input and output parameters</a></li>
|
|
<li><a HREF="#Python_nn47">33.7.2 Simple pointers</a></li>
|
|
<li><a HREF="#Python_nn48">33.7.3 Unbounded C Arrays</a></li>
|
|
<li><a HREF="#Python_nn49">33.7.4 String handling</a></li>
|
|
<li><a HREF="#Python_default_args">33.7.5 Default arguments</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn53">33.8 Typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn54">33.8.1 What is a typemap?</a></li>
|
|
<li><a HREF="#Python_nn55">33.8.2 Python typemaps</a></li>
|
|
<li><a HREF="#Python_nn56">33.8.3 Typemap variables</a></li>
|
|
<li><a HREF="#Python_nn57">33.8.4 Useful Python Functions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn58">33.9 Typemap Examples</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn59">33.9.1 Converting a Python list to a char **</a>
|
|
</li>
|
|
<li><a HREF="#Python_nn60">33.9.2 Expanding a Python object into
|
|
multiple arguments</a></li>
|
|
<li><a HREF="#Python_nn61">33.9.3 Using typemaps to return arguments</a></li>
|
|
<li><a HREF="#Python_nn62">33.9.4 Mapping Python tuples into small
|
|
arrays</a></li>
|
|
<li><a HREF="#Python_nn63">33.9.5 Mapping sequences to C arrays</a></li>
|
|
<li><a HREF="#Python_nn64">33.9.6 Pointer handling</a></li>
|
|
<li><a HREF="#Python_memory_management_member_variables">33.9.7 Memory
|
|
management when returning references to member variables</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn65">33.10 Docstring Features</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn66">33.10.1 Module docstring</a></li>
|
|
<li><a HREF="#Python_nn67">33.10.2 %feature("autodoc")</a>
|
|
<ul>
|
|
<li><a HREF="#Python_nn68">33.10.2.1 %feature("autodoc", "0")</a></li>
|
|
<li><a HREF="#Python_nn69">33.10.2.2 %feature("autodoc", "1")</a></li>
|
|
<li><a HREF="#Python_autodoc2">33.10.2.3 %feature("autodoc", "2")</a></li>
|
|
<li><a HREF="#Python_autodoc3">33.10.2.4 %feature("autodoc", "3")</a></li>
|
|
<li><a HREF="#Python_nn70">33.10.2.5 %feature("autodoc", "docstring")</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn71">33.10.3 %feature("docstring")</a></li>
|
|
<li><a HREF="#Python_doxygen_docstrings">33.10.4 Doxygen comments</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn72">33.11 Python Packages</a>
|
|
<ul>
|
|
<li><a HREF="#Python_modulepackage">33.11.1 Setting the Python package</a>
|
|
</li>
|
|
<li><a HREF="#Python_absrelimports">33.11.2 Absolute and relative
|
|
imports</a></li>
|
|
<li><a HREF="#Python_absimport">33.11.3 Enforcing absolute import
|
|
semantics</a></li>
|
|
<li><a HREF="#Python_importfrominit">33.11.4 Importing from __init__.py</a>
|
|
</li>
|
|
<li><a HREF="#Python_implicit_namespace_packages">33.11.5 Implicit
|
|
namespace packages</a></li>
|
|
<li><a HREF="#Python_package_search">33.11.6 Location of modules</a>
|
|
<ul>
|
|
<li><a HREF="#Python_package_search_both_package_modules">33.11.6.1 Both
|
|
modules in the same package</a></li>
|
|
<li><a HREF="#Python_package_search_both_global_modules">33.11.6.2 Both
|
|
modules are global</a></li>
|
|
<li><a HREF="#Python_package_search_wrapper_split">33.11.6.3 Split
|
|
modules custom configuration</a></li>
|
|
<li><a HREF="#Python_custom_module_import">33.11.6.4 More on customizing
|
|
the module import code</a></li>
|
|
<li><a HREF="#Python_package_search_static">33.11.6.5 Statically linked
|
|
C modules</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_python3support">33.12 Python 3 Support</a>
|
|
<ul>
|
|
<li><a HREF="#Python_annotations">33.12.1 Python function annotations
|
|
and variable annotations</a>
|
|
<ul>
|
|
<li><a HREF="#Python_annotations_c">33.12.1.1 C/C++ annotation types</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_nn75">33.12.2 Buffer interface</a></li>
|
|
<li><a HREF="#Python_nn76">33.12.3 Abstract base classes</a></li>
|
|
<li><a HREF="#Python_nn77">33.12.4 Byte string output conversion</a></li>
|
|
<li><a HREF="#Python_2_unicode">33.12.5 Python 2 Unicode</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Python_multithreaded">33.13 Support for Multithreaded
|
|
Applications</a>
|
|
<ul>
|
|
<li><a HREF="#Python_thread_UI">33.13.1 UI for Enabling Multithreading
|
|
Support</a></li>
|
|
<li><a HREF="#Python_thread_performance">33.13.2 Multithread Performance</a>
|
|
</li>
|
|
</ul>
|
|
</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>
|
|
<ul>
|
|
<li><a HREF="#R_class_examples">34.6.1 Examples</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#R_nn7">34.7 Enumerations</a></li>
|
|
</ul>
|
|
<b><a HREF="#Ruby">35 SWIG and Ruby</a></b>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn2">35.1 Preliminaries</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn3">35.1.1 Running SWIG</a></li>
|
|
<li><a HREF="#Ruby_nn4">35.1.2 Getting the right header files</a></li>
|
|
<li><a HREF="#Ruby_nn5">35.1.3 Compiling a dynamic module</a></li>
|
|
<li><a HREF="#Ruby_nn6">35.1.4 Using your module</a></li>
|
|
<li><a HREF="#Ruby_nn7">35.1.5 Static linking</a></li>
|
|
<li><a HREF="#Ruby_nn8">35.1.6 Compilation of C++ extensions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn9">35.2 Building Ruby Extensions under Windows
|
|
95/NT</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn10">35.2.1 Running SWIG from Developer Studio</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn11">35.3 The Ruby-to-C/C++ Mapping</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn12">35.3.1 Modules</a></li>
|
|
<li><a HREF="#Ruby_nn13">35.3.2 Functions</a></li>
|
|
<li><a HREF="#Ruby_nn14">35.3.3 Variable Linking</a></li>
|
|
<li><a HREF="#Ruby_nn15">35.3.4 Constants</a></li>
|
|
<li><a HREF="#Ruby_nn16">35.3.5 Pointers</a></li>
|
|
<li><a HREF="#Ruby_nn17">35.3.6 Structures</a></li>
|
|
<li><a HREF="#Ruby_nn18">35.3.7 C++ classes</a></li>
|
|
<li><a HREF="#Ruby_nn19">35.3.8 C++ Inheritance</a></li>
|
|
<li><a HREF="#Ruby_nn20">35.3.9 C++ Overloaded Functions</a></li>
|
|
<li><a HREF="#Ruby_nn21">35.3.10 C++ Operators</a></li>
|
|
<li><a HREF="#Ruby_nn22">35.3.11 C++ namespaces</a></li>
|
|
<li><a HREF="#Ruby_nn23">35.3.12 C++ templates</a></li>
|
|
<li><a HREF="#Ruby_nn23_1">35.3.13 C++ Standard Template Library (STL)</a>
|
|
</li>
|
|
<li><a HREF="#Ruby_C_STL_Functors">35.3.14 C++ STL Functors</a></li>
|
|
<li><a HREF="#Ruby_C_Iterators">35.3.15 C++ STL Iterators</a></li>
|
|
<li><a HREF="#Ruby_nn24">35.3.16 C++ Smart Pointers</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_smart_pointers_shared_ptr">35.3.16.1 The shared_ptr
|
|
Smart Pointer</a></li>
|
|
<li><a HREF="#Ruby_smart_pointers_generic">35.3.16.2 Generic Smart
|
|
Pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn25">35.3.17 Cross-Language Polymorphism</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn26">35.3.17.1 Exception Unrolling</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn27">35.4 Naming</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn28">35.4.1 Defining Aliases</a></li>
|
|
<li><a HREF="#Ruby_nn29">35.4.2 Predicate Methods</a></li>
|
|
<li><a HREF="#Ruby_nn30">35.4.3 Bang Methods</a></li>
|
|
<li><a HREF="#Ruby_nn31">35.4.4 Getters and Setters</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn32">35.5 Input and output parameters</a></li>
|
|
<li><a HREF="#Ruby_nn33">35.6 Exception handling</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn34">35.6.1 Using the %exception directive</a></li>
|
|
<li><a HREF="#Ruby_nn34_2">35.6.2 Handling Ruby Blocks</a></li>
|
|
<li><a HREF="#Ruby_nn35">35.6.3 Raising exceptions</a></li>
|
|
<li><a HREF="#Ruby_nn36">35.6.4 Exception classes</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn37">35.7 Typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn38">35.7.1 What is a typemap?</a></li>
|
|
<li><a HREF="#Ruby_Typemap_scope">35.7.2 Typemap scope</a></li>
|
|
<li><a HREF="#Ruby_Copying_a_typemap">35.7.3 Copying a typemap</a></li>
|
|
<li><a HREF="#Ruby_Deleting_a_typemap">35.7.4 Deleting a typemap</a></li>
|
|
<li><a HREF="#Ruby_Placement_of_typemaps">35.7.5 Placement of typemaps</a>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn39">35.7.6 Ruby typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_in_typemap">35.7.6.1 "in" typemap</a></li>
|
|
<li><a HREF="#Ruby_typecheck_typemap">35.7.6.2 "typecheck" typemap</a></li>
|
|
<li><a HREF="#Ruby_out_typemap">35.7.6.3 "out" typemap</a></li>
|
|
<li><a HREF="#Ruby_arginit_typemap">35.7.6.4 "arginit" typemap</a></li>
|
|
<li><a HREF="#Ruby_default_typemap">35.7.6.5 "default" typemap</a></li>
|
|
<li><a HREF="#Ruby_check_typemap">35.7.6.6 "check" typemap</a></li>
|
|
<li><a HREF="#Ruby_argout_typemap_">35.7.6.7 "argout" typemap</a></li>
|
|
<li><a HREF="#Ruby_freearg_typemap_">35.7.6.8 "freearg" typemap</a></li>
|
|
<li><a HREF="#Ruby_newfree_typemap">35.7.6.9 "newfree" typemap</a></li>
|
|
<li><a HREF="#Ruby_memberin_typemap">35.7.6.10 "memberin" typemap</a></li>
|
|
<li><a HREF="#Ruby_varin_typemap">35.7.6.11 "varin" typemap</a></li>
|
|
<li><a HREF="#Ruby_varout_typemap_">35.7.6.12 "varout" typemap</a></li>
|
|
<li><a HREF="#Ruby_throws_typemap">35.7.6.13 "throws" typemap</a></li>
|
|
<li><a HREF="#Ruby_directorin_typemap">35.7.6.14 directorin typemap</a></li>
|
|
<li><a HREF="#Ruby_directorout_typemap">35.7.6.15 directorout typemap</a>
|
|
</li>
|
|
<li><a HREF="#Ruby_directorargout_typemap">35.7.6.16 directorargout
|
|
typemap</a></li>
|
|
<li><a HREF="#Ruby_ret_typemap">35.7.6.17 ret typemap</a></li>
|
|
<li><a HREF="#Ruby_globalin_typemap">35.7.6.18 globalin typemap</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn40">35.7.7 Typemap variables</a></li>
|
|
<li><a HREF="#Ruby_nn41">35.7.8 Useful Functions</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn42">35.7.8.1 C Datatypes to Ruby Objects</a></li>
|
|
<li><a HREF="#Ruby_nn43">35.7.8.2 Ruby Objects to C Datatypes</a></li>
|
|
<li><a HREF="#Ruby_nn44">35.7.8.3 Macros for VALUE</a></li>
|
|
<li><a HREF="#Ruby_nn45">35.7.8.4 Exceptions</a></li>
|
|
<li><a HREF="#Ruby_nn46">35.7.8.5 Iterators</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn47">35.7.9 Typemap Examples</a></li>
|
|
<li><a HREF="#Ruby_nn48">35.7.10 Converting a Ruby array to a char **</a>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn49">35.7.11 Collecting arguments in a hash</a></li>
|
|
<li><a HREF="#Ruby_nn50">35.7.12 Pointer handling</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn51">35.7.12.1 Ruby Datatype Wrapping</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn52">35.7.13 Example: STL Vector to Ruby Array</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn65">35.8 Docstring Features</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn66">35.8.1 Module docstring</a></li>
|
|
<li><a HREF="#Ruby_nn67">35.8.2 %feature("autodoc")</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn68">35.8.2.1 %feature("autodoc", "0")</a></li>
|
|
<li><a HREF="#Ruby_autodoc1">35.8.2.2 %feature("autodoc", "1")</a></li>
|
|
<li><a HREF="#Ruby_autodoc2">35.8.2.3 %feature("autodoc", "2")</a></li>
|
|
<li><a HREF="#Ruby_feature_autodoc3">35.8.2.4 %feature("autodoc", "3")</a>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn70">35.8.2.5 %feature("autodoc", "docstring")</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn71">35.8.3 %feature("docstring")</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn53">35.9 Advanced Topics</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_operator_overloading">35.9.1 Operator overloading</a></li>
|
|
<li><a HREF="#Ruby_nn55">35.9.2 Creating Multi-Module Packages</a></li>
|
|
<li><a HREF="#Ruby_nn56">35.9.3 Specifying Mixin Modules</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ruby_nn57">35.10 Memory Management</a>
|
|
<ul>
|
|
<li><a HREF="#Ruby_nn58">35.10.1 Mark and Sweep Garbage Collector</a></li>
|
|
<li><a HREF="#Ruby_nn59">35.10.2 Object Ownership</a></li>
|
|
<li><a HREF="#Ruby_nn60">35.10.3 Object Tracking</a></li>
|
|
<li><a HREF="#Ruby_nn61">35.10.4 Mark Functions</a></li>
|
|
<li><a HREF="#Ruby_nn62">35.10.5 Free Functions</a></li>
|
|
<li><a HREF="#Ruby_nn63">35.10.6 Embedded Ruby and the C++ Stack</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Scilab">36 SWIG and Scilab</a></b>
|
|
<ul>
|
|
<li><a HREF="#Scilab_preliminaries">36.1 Preliminaries</a></li>
|
|
<li><a HREF="#Scilab_running_swig">36.2 Running SWIG</a>
|
|
<ul>
|
|
<li><a HREF="#Scilab_running_swig_generating_module">36.2.1 Generating
|
|
the module</a></li>
|
|
<li><a HREF="#Scilab_running_swig_building_module">36.2.2 Building the
|
|
module</a></li>
|
|
<li><a HREF="#Scilab_running_swig_loading_module">36.2.3 Loading the
|
|
module</a></li>
|
|
<li><a HREF="#Scilab_running_swig_using_module">36.2.4 Using the module</a>
|
|
</li>
|
|
<li><a HREF="#Scilab_running_swig_options">36.2.5 Scilab command line
|
|
options</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Scilab_wrapping">36.3 A basic tour of C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#Scilab_wrapping_overview">36.3.1 Overview</a></li>
|
|
<li><a HREF="#Scilab_wrapping_identifiers">36.3.2 Identifiers</a></li>
|
|
<li><a HREF="#Scilab_wrapping_functions">36.3.3 Functions</a>
|
|
<ul>
|
|
<li><a HREF="#Scilab_nn13">36.3.3.1 Argument passing</a></li>
|
|
<li><a HREF="#Scilab_nn14">36.3.3.2 Multiple output arguments</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Scilab_wrapping_global_variables">36.3.4 Global variables</a>
|
|
</li>
|
|
<li><a HREF="#Scilab_wrapping_constants_and_enums">36.3.5 Constants and
|
|
enumerations</a>
|
|
<ul>
|
|
<li><a HREF="#Scilab_wrapping_constants">36.3.5.1 Constants</a></li>
|
|
<li><a HREF="#Scilab_wrapping_enums">36.3.5.2 Enumerations</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Scilab_wrapping_pointers">36.3.6 Pointers</a>
|
|
<ul>
|
|
<li><a HREF="#Scilab_wrapping_pointers_utility_functions">36.3.6.1
|
|
Utility functions</a></li>
|
|
<li><a HREF="#Scilab_wrapping_pointers_null_pointers">36.3.6.2 Null
|
|
pointers:</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Scilab_wrapping_structs">36.3.7 Structures</a></li>
|
|
<li><a HREF="#Scilab_wrapping_cpp_classes">36.3.8 C++ classes</a></li>
|
|
<li><a HREF="#Scilab_wrapping_cpp_inheritance">36.3.9 C++ inheritance</a>
|
|
</li>
|
|
<li><a HREF="#Scilab_wrapping_cpp_overloading">36.3.10 C++ overloading</a>
|
|
</li>
|
|
<li><a HREF="#Scilab_wrapping_pointers_references_values_arrays">36.3.11
|
|
Pointers, references, values, and arrays</a></li>
|
|
<li><a HREF="#Scilab_wrapping_cpp_templates">36.3.12 C++ templates</a></li>
|
|
<li><a HREF="#Scilab_wrapping_cpp_operators">36.3.13 C++ operators</a></li>
|
|
<li><a HREF="#Scilab_wrapping_cpp_namespaces">36.3.14 C++ namespaces</a></li>
|
|
<li><a HREF="#Scilab_wrapping_cpp_exceptions">36.3.15 C++ exceptions</a></li>
|
|
<li><a HREF="#Scilab_wrapping_cpp_stl">36.3.16 C++ STL</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Scilab_typemaps">36.4 Type mappings and libraries</a>
|
|
<ul>
|
|
<li><a HREF="#Scilab_typemaps_primitive_types">36.4.1 Default primitive
|
|
type mappings</a></li>
|
|
<li><a HREF="#Scilab_typemaps_arrays">36.4.2 Arrays</a></li>
|
|
<li><a HREF="#Scilab_typemaps_pointer-to-pointers">36.4.3
|
|
Pointer-to-pointers</a></li>
|
|
<li><a HREF="#Scilab_typemaps_matrices">36.4.4 Matrices</a></li>
|
|
<li><a HREF="#Scilab_typemaps_stl">36.4.5 STL</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Scilab_module_initialization">36.5 Module initialization</a>
|
|
</li>
|
|
<li><a HREF="#Scilab_building_modes">36.6 Building modes</a>
|
|
<ul>
|
|
<li><a HREF="#Scilab_building_modes_nobuilder_mode">36.6.1 No-builder
|
|
mode</a></li>
|
|
<li><a HREF="#Scilab_building_modes_builder_mode">36.6.2 Builder mode</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Scilab_generated_scripts">36.7 Generated scripts</a>
|
|
<ul>
|
|
<li><a HREF="#Scilab_generated_scripts_builder_script">36.7.1 Builder
|
|
script</a></li>
|
|
<li><a HREF="#Scilab_generated_scripts_loader_script">36.7.2 Loader
|
|
script</a></li>
|
|
<li><a HREF="#Scilab_generated_scripts_gateway">36.7.3 Gateway XML files</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Scilab_other_resources">36.8 Other resources</a></li>
|
|
</ul>
|
|
<b><a HREF="#Tcl">37 SWIG and Tcl</a></b>
|
|
<ul>
|
|
<li><a HREF="#Tcl_nn2">37.1 Preliminaries</a>
|
|
<ul>
|
|
<li><a HREF="#Tcl_nn3">37.1.1 Getting the right header files</a></li>
|
|
<li><a HREF="#Tcl_nn4">37.1.2 Compiling a dynamic module</a></li>
|
|
<li><a HREF="#Tcl_nn5">37.1.3 Static linking</a></li>
|
|
<li><a HREF="#Tcl_nn6">37.1.4 Using your module</a></li>
|
|
<li><a HREF="#Tcl_nn7">37.1.5 Compilation of C++ extensions</a></li>
|
|
<li><a HREF="#Tcl_nn8">37.1.6 Compiling for 64-bit platforms</a></li>
|
|
<li><a HREF="#Tcl_nn9">37.1.7 Setting a package prefix</a></li>
|
|
<li><a HREF="#Tcl_nn10">37.1.8 Using namespaces</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Tcl_nn11">37.2 Building Tcl/Tk Extensions under Windows
|
|
95/NT</a>
|
|
<ul>
|
|
<li><a HREF="#Tcl_nn12">37.2.1 Running SWIG from Developer Studio</a></li>
|
|
<li><a HREF="#Tcl_nn13">37.2.2 Using NMAKE</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Tcl_nn14">37.3 A tour of basic C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#Tcl_nn15">37.3.1 Modules</a></li>
|
|
<li><a HREF="#Tcl_nn16">37.3.2 Functions</a></li>
|
|
<li><a HREF="#Tcl_nn17">37.3.3 Global variables</a></li>
|
|
<li><a HREF="#Tcl_nn18">37.3.4 Constants and enums</a></li>
|
|
<li><a HREF="#Tcl_nn19">37.3.5 Pointers</a></li>
|
|
<li><a HREF="#Tcl_nn20">37.3.6 Structures</a></li>
|
|
<li><a HREF="#Tcl_nn21">37.3.7 C++ classes</a></li>
|
|
<li><a HREF="#Tcl_nn22">37.3.8 C++ inheritance</a></li>
|
|
<li><a HREF="#Tcl_nn23">37.3.9 Pointers, references, values, and arrays</a>
|
|
</li>
|
|
<li><a HREF="#Tcl_nn24">37.3.10 C++ overloaded functions</a></li>
|
|
<li><a HREF="#Tcl_nn25">37.3.11 C++ operators</a></li>
|
|
<li><a HREF="#Tcl_nn26">37.3.12 C++ namespaces</a></li>
|
|
<li><a HREF="#Tcl_nn27">37.3.13 C++ templates</a></li>
|
|
<li><a HREF="#Tcl_nn28">37.3.14 C++ Smart Pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Tcl_nn29">37.4 Further details on the Tcl class interface</a>
|
|
<ul>
|
|
<li><a HREF="#Tcl_nn30">37.4.1 Proxy classes</a></li>
|
|
<li><a HREF="#Tcl_nn31">37.4.2 Memory management</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Tcl_nn32">37.5 Input and output parameters</a></li>
|
|
<li><a HREF="#Tcl_nn33">37.6 Exception handling</a></li>
|
|
<li><a HREF="#Tcl_nn34">37.7 Typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#Tcl_nn35">37.7.1 What is a typemap?</a></li>
|
|
<li><a HREF="#Tcl_nn36">37.7.2 Tcl typemaps</a></li>
|
|
<li><a HREF="#Tcl_nn37">37.7.3 Typemap variables</a></li>
|
|
<li><a HREF="#Tcl_nn38">37.7.4 Converting a Tcl list to a char **</a></li>
|
|
<li><a HREF="#Tcl_nn39">37.7.5 Returning values in arguments</a></li>
|
|
<li><a HREF="#Tcl_nn40">37.7.6 Useful functions</a></li>
|
|
<li><a HREF="#Tcl_nn41">37.7.7 Standard typemaps</a></li>
|
|
<li><a HREF="#Tcl_nn42">37.7.8 Pointer handling</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Tcl_nn43">37.8 Turning a SWIG module into a Tcl Package.</a>
|
|
</li>
|
|
<li><a HREF="#Tcl_nn44">37.9 Building new kinds of Tcl interfaces (in
|
|
Tcl)</a>
|
|
<ul>
|
|
<li><a HREF="#Tcl_nn45">37.9.1 Proxy classes</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Tcl_nn46">37.10 Tcl/Tk Stubs</a></li>
|
|
</ul>
|
|
<b><a HREF="#C">38 SWIG and C as the target language</a></b>
|
|
<ul>
|
|
<li><a HREF="#C_overview">38.1 Overview</a>
|
|
<ul>
|
|
<li><a HREF="#C_shortcomings">38.1.1 Known C++ Shortcomings in Generated
|
|
C API</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#C_preliminaries">38.2 Preliminaries</a>
|
|
<ul>
|
|
<li><a HREF="#C_running_swig">38.2.1 Running SWIG</a></li>
|
|
<li><a HREF="#C_commandline">38.2.2 Command line options</a></li>
|
|
<li><a HREF="#C_dynamic">38.2.3 Compiling a dynamic module</a></li>
|
|
<li><a HREF="#C_using_module">38.2.4 Using the generated module</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#C_basic_c_wrapping">38.3 Basic C wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#C_functions">38.3.1 Functions</a></li>
|
|
<li><a HREF="#C_variables">38.3.2 Variables</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#C_basic_cpp_wrapping">38.4 Basic C++ wrapping</a>
|
|
<ul>
|
|
<li><a HREF="#C_enums">38.4.1 Enums</a></li>
|
|
<li><a HREF="#C_classes">38.4.2 Classes</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#C_developer">38.5 Backend Developer Documentation</a></li>
|
|
<li><a HREF="#C_typemaps">38.6 Typemaps</a>
|
|
<ul>
|
|
<li><a HREF="#C_typemaps_walkthrough">38.6.1 C Typemaps, a Code
|
|
Generation Walkthrough</a>
|
|
<ul>
|
|
<li><a HREF="#C_walkthrough_interface">38.6.1.1 The Interface</a></li>
|
|
<li><a HREF="#C_walkthrough_wrapper">38.6.1.2 The Wrapper</a></li>
|
|
<li><a HREF="#C_walkthrough_proxy">38.6.1.3 The Proxy</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#C_exceptions">38.7 Exception handling</a></li>
|
|
<li><a HREF="#C_cxx_wrappers">38.8 C++ Wrappers</a>
|
|
<ul>
|
|
<li><a HREF="#C_additional_possibilities">38.8.1 Additional
|
|
customization possibilities</a></li>
|
|
<li><a HREF="#C_exception_handling">38.8.2 Exception handling</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Mzscheme">39 SWIG and MzScheme/Racket</a></b>
|
|
<ul>
|
|
<li><a HREF="#MzScheme_nn2">39.1 Creating native structures</a></li>
|
|
<li><a HREF="#MzScheme_simple">39.2 Simple example</a></li>
|
|
<li><a HREF="#MzScheme_external_docs">39.3 External documentation</a></li>
|
|
</ul>
|
|
<b><a HREF="#Ocaml">40 SWIG and OCaml</a></b>
|
|
<ul>
|
|
<li><a HREF="#Ocaml_nn2">40.1 Preliminaries</a>
|
|
<ul>
|
|
<li><a HREF="#Ocaml_nn3">40.1.1 Running SWIG</a></li>
|
|
<li><a HREF="#Ocaml_nn4">40.1.2 Compiling the code</a></li>
|
|
<li><a HREF="#Ocaml_nn5">40.1.3 The camlp4 module</a></li>
|
|
<li><a HREF="#Ocaml_nn6">40.1.4 Using your module</a></li>
|
|
<li><a HREF="#Ocaml_nn7">40.1.5 Compilation problems and compiling with
|
|
C++</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ocaml_nn8">40.2 The low-level Ocaml/C interface</a>
|
|
<ul>
|
|
<li><a HREF="#Ocaml_nn9">40.2.1 The generated module</a></li>
|
|
<li><a HREF="#Ocaml_nn10">40.2.2 Enums</a>
|
|
<ul>
|
|
<li><a HREF="#Ocaml_nn11">40.2.2.1 Enum typing in Ocaml</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ocaml_nn12">40.2.3 Arrays</a>
|
|
<ul>
|
|
<li><a HREF="#Ocaml_nn13">40.2.3.1 Simple types of bounded arrays</a></li>
|
|
<li><a HREF="#Ocaml_nn14">40.2.3.2 Complex and unbounded arrays</a></li>
|
|
<li><a HREF="#Ocaml_nn15">40.2.3.3 Using an object</a></li>
|
|
<li><a HREF="#Ocaml_nn16">40.2.3.4 Example typemap for a function taking
|
|
float * and int</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ocaml_nn17">40.2.4 C++ Classes</a>
|
|
<ul>
|
|
<li><a HREF="#Ocaml_nn18">40.2.4.1 STL vector and string Example</a></li>
|
|
<li><a HREF="#Ocaml_nn19">40.2.4.2 C++ Class Example</a></li>
|
|
<li><a HREF="#Ocaml_nn20">40.2.4.3 Compiling the example</a></li>
|
|
<li><a HREF="#Ocaml_nn21">40.2.4.4 Sample Session</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ocaml_nn22">40.2.5 Director Classes</a>
|
|
<ul>
|
|
<li><a HREF="#Ocaml_nn23">40.2.5.1 Director Introduction</a></li>
|
|
<li><a HREF="#Ocaml_nn24">40.2.5.2 Overriding Methods in Ocaml</a></li>
|
|
<li><a HREF="#Ocaml_nn25">40.2.5.3 Director Usage Example</a></li>
|
|
<li><a HREF="#Ocaml_nn26">40.2.5.4 Creating director objects</a></li>
|
|
<li><a HREF="#Ocaml_nn27">40.2.5.5 Typemaps for directors, directorin,
|
|
directorout, directorargout</a></li>
|
|
<li><a HREF="#Ocaml_nn28">40.2.5.6 directorin typemap</a></li>
|
|
<li><a HREF="#Ocaml_nn29">40.2.5.7 directorout typemap</a></li>
|
|
<li><a HREF="#Ocaml_nn30">40.2.5.8 directorargout typemap</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ocaml_nn31">40.2.6 Exceptions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Ocaml_nn32">40.3 Documentation Features</a>
|
|
<ul>
|
|
<li><a HREF="#Ocaml_nn33">40.3.1 Module docstring</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<b><a HREF="#Extending">41 Extending SWIG to support new languages</a></b>
|
|
<ul>
|
|
<li><a HREF="#Extending_nn2">41.1 Introduction</a></li>
|
|
<li><a HREF="#Extending_nn3">41.2 Prerequisites</a></li>
|
|
<li><a HREF="#Extending_nn4">41.3 The Big Picture</a></li>
|
|
<li><a HREF="#Extending_nn5">41.4 Execution Model</a>
|
|
<ul>
|
|
<li><a HREF="#Extending_nn6">41.4.1 Preprocessing</a></li>
|
|
<li><a HREF="#Extending_nn7">41.4.2 Parsing</a></li>
|
|
<li><a HREF="#Extending_nn8">41.4.3 Parse Trees</a></li>
|
|
<li><a HREF="#Extending_nn9">41.4.4 Attribute namespaces</a></li>
|
|
<li><a HREF="#Extending_nn10">41.4.5 Symbol Tables</a></li>
|
|
<li><a HREF="#Extending_nn11">41.4.6 The %feature directive</a></li>
|
|
<li><a HREF="#Extending_nn12">41.4.7 Code Generation</a></li>
|
|
<li><a HREF="#Extending_nn13">41.4.8 SWIG and XML</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Extending_nn14">41.5 Primitive Data Structures</a>
|
|
<ul>
|
|
<li><a HREF="#Extending_nn15">41.5.1 Strings</a></li>
|
|
<li><a HREF="#Extending_nn16">41.5.2 Hashes</a></li>
|
|
<li><a HREF="#Extending_nn17">41.5.3 Lists</a></li>
|
|
<li><a HREF="#Extending_nn18">41.5.4 Common operations</a></li>
|
|
<li><a HREF="#Extending_nn19">41.5.5 Iterating over Lists and Hashes</a></li>
|
|
<li><a HREF="#Extending_nn20">41.5.6 I/O</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Extending_nn21">41.6 Navigating and manipulating parse
|
|
trees</a></li>
|
|
<li><a HREF="#Extending_nn22">41.7 Working with attributes</a></li>
|
|
<li><a HREF="#Extending_nn23">41.8 Type system</a>
|
|
<ul>
|
|
<li><a HREF="#Extending_nn24">41.8.1 String encoding of types</a></li>
|
|
<li><a HREF="#Extending_nn25">41.8.2 Type construction</a></li>
|
|
<li><a HREF="#Extending_nn26">41.8.3 Type tests</a></li>
|
|
<li><a HREF="#Extending_nn27">41.8.4 Typedef and inheritance</a></li>
|
|
<li><a HREF="#Extending_nn28">41.8.5 Lvalues</a></li>
|
|
<li><a HREF="#Extending_nn29">41.8.6 Output functions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Extending_nn30">41.9 Parameters</a></li>
|
|
<li><a HREF="#Extending_nn31">41.10 Writing a Language Module</a>
|
|
<ul>
|
|
<li><a HREF="#Extending_nn32">41.10.1 Execution model</a></li>
|
|
<li><a HREF="#Extending_starting_out">41.10.2 Starting out</a></li>
|
|
<li><a HREF="#Extending_nn34">41.10.3 Command line options</a></li>
|
|
<li><a HREF="#Extending_nn35">41.10.4 Configuration and preprocessing</a>
|
|
</li>
|
|
<li><a HREF="#Extending_nn36">41.10.5 Entry point to code generation</a></li>
|
|
<li><a HREF="#Extending_nn37">41.10.6 Module I/O and wrapper skeleton</a>
|
|
</li>
|
|
<li><a HREF="#Extending_nn38">41.10.7 Low-level code generators</a></li>
|
|
<li><a HREF="#Extending_configuration_files">41.10.8 Configuration files</a>
|
|
</li>
|
|
<li><a HREF="#Extending_nn40">41.10.9 Runtime support</a></li>
|
|
<li><a HREF="#Extending_nn41">41.10.10 Standard library files</a></li>
|
|
<li><a HREF="#Extending_nn42">41.10.11 User examples</a></li>
|
|
<li><a HREF="#Extending_test_suite">41.10.12 Test driven development and
|
|
the test-suite</a>
|
|
<ul>
|
|
<li><a HREF="#Extending_running_test_suite">41.10.12.1 Running the
|
|
test-suite</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Extending_nn43">41.10.13 Documentation</a></li>
|
|
<li><a HREF="#Extending_coding_style_guidelines">41.10.14 Coding style
|
|
guidelines</a></li>
|
|
<li><a HREF="#Extending_language_status">41.10.15 Target language status</a>
|
|
<ul>
|
|
<li><a HREF="#Extending_supported_status">41.10.15.1 Supported status</a>
|
|
</li>
|
|
<li><a HREF="#Extending_experimental_status">41.10.15.2 Experimental
|
|
status</a></li>
|
|
<li><a HREF="#Extending_deprecated_status">41.10.15.3 Deprecated status</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Extending_prerequisites">41.10.16 Prerequisites for adding
|
|
a new language module to the SWIG distribution</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a HREF="#Extending_debugging_options">41.11 Debugging Options</a></li>
|
|
<li><a HREF="#Extending_nn46">41.12 Guide to parse tree nodes</a></li>
|
|
<li><a HREF="#Extending_further_info">41.13 Further Development
|
|
Information</a></li>
|
|
</ul>
|
|
<HR NOSHADE>
|
|
<h1><a name="Sections">SWIG-4.3 Documentation</a></h1>
|
|
<p> Last update : SWIG-4.3.0 (20 Oct 2024)</p>
|
|
<h2><a name="Sections_Sections">Sections</a></h2>
|
|
<h3><a name="Sections_core_docs">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="#CPlusPlus11">SWIG and C++11</a></li>
|
|
<li><a href="#CPlusPlus14">SWIG and C++14</a></li>
|
|
<li><a href="#CPlusPlus17">SWIG and C++17</a></li>
|
|
<li><a href="#CPlusPlus20">SWIG and C++20</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="#Doxygen">Doxygen documentation comments</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="Sections_language_modules">Supported Language Modules
|
|
Documentation</a></h3>
|
|
<ul>
|
|
<li><a href="#Android">Android support</a></li>
|
|
<li><a href="#CSharp">C# support</a></li>
|
|
<li><a href="#D">D support</a></li>
|
|
<li><a href="#Go">Go support</a></li>
|
|
<li><a href="#Guile">Guile support</a></li>
|
|
<li><a href="#Java">Java support</a></li>
|
|
<li><a href="#Javascript">Javascript support</a></li>
|
|
<li><a href="#Lua">Lua 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="#Python">Python support</a></li>
|
|
<li><a href="#R">R support</a></li>
|
|
<li><a href="#Ruby">Ruby support</a></li>
|
|
<li><a href="#Scilab">Scilab support</a></li>
|
|
<li><a href="#Tcl">Tcl support</a></li>
|
|
</ul>
|
|
<h3><a name="Sections_experimental_language_modules">Experimental
|
|
Language Modules Documentation</a></h3>
|
|
<ul>
|
|
<li><a href="#C">C target language support</a></li>
|
|
<li><a href="#Ocaml">OCaml support</a></li>
|
|
</ul>
|
|
<h3><a name="Sections_deprecated_language_modules">Deprecated Language
|
|
Modules Documentation</a></h3>
|
|
<ul>
|
|
<li><a href="#Mzscheme">MzScheme/Racket support</a></li>
|
|
</ul>
|
|
<h3><a name="Sections_developers_docs">Developer Documentation</a></h3>
|
|
<ul>
|
|
<li><a href="#Extending">Extending SWIG</a></li>
|
|
</ul>
|
|
<HR NOSHADE>
|
|
<h1><a name="Preface">1 Preface</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Preface_nn2">Introduction</a></li>
|
|
<li><a href="#Preface_nn4">SWIG Versions</a></li>
|
|
<li><a href="#Preface_license">SWIG License</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_release_notes">Release notes</a></li>
|
|
<li><a href="#Preface_nn10">Credits</a></li>
|
|
<li><a href="#Preface_nn11">Bug reports</a></li>
|
|
<li><a href="#Preface_installation">Installation</a>
|
|
<ul>
|
|
<li><a href="#Preface_windows_installation">Windows installation</a></li>
|
|
<li><a href="#Preface_unix_installation">Unix installation</a></li>
|
|
<li><a href="#Preface_osx_installation">Macintosh OS X installation</a></li>
|
|
<li><a href="#Preface_testing">Testing</a></li>
|
|
<li><a href="#Preface_examples">Examples</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<h2><a name="Preface_nn2">1.1 Introduction</a></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_nn4">1.2 SWIG Versions</a></h2>
|
|
<p> In the late 1990's, the most stable version of SWIG was release
|
|
1.1p5. Versions 1.3.x were officially development versions and these
|
|
were released over a period of 10 years starting from the year 2000.
|
|
The final version in the 1.3.x series was 1.3.40, but in truth the
|
|
1.3.x series had been stable for many years. An official stable version
|
|
was released along with the decision to make SWIG license changes and
|
|
this gave rise to version 2.0.0 in 2010. Version 3.0.0 was released in
|
|
2014 focusing on adding C++11 support and C++ nested classes. Version
|
|
4.0.0 was released in 2019 to add in Doxygen support. Some target
|
|
languages were disabled as part of a clean up and others were given a
|
|
new status of either 'Supported' or 'Experimental'.</p>
|
|
<h2><a name="Preface_license">1.3 SWIG License</a></h2>
|
|
<p> The LICENSE file shipped with SWIG in the top level directory
|
|
contains the SWIG license. For further insight into the license
|
|
including the license of SWIG's output code, please visit the SWIG
|
|
legal page - <a href="https://www.swig.org/legal.html">
|
|
https://www.swig.org/legal.html</a>.</p>
|
|
<p> The license was clarified in version 2.0.0 so that the code that
|
|
SWIG generated could be distributed under license terms of the user's
|
|
choice/requirements and at the same time the SWIG source was placed
|
|
under the GNU General Public License version 3.</p>
|
|
<h2><a name="Preface_nn5">1.4 SWIG resources</a></h2>
|
|
<p> The official location of SWIG related material is</p>
|
|
<div class="shell">
|
|
<pre>
|
|
<a href="https://www.swig.org">https://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="https://www.swig.org/mail.html">https://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> Git and Subversion 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="https://www.swig.org/svn.html">SWIG Bleeding Edge</a>
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Preface_nn6">1.5 Prerequisites</a></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> Over time 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">1.6 Organization of this manual</a></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.</p>
|
|
<h2><a name="Preface_nn8">1.7 How to avoid reading the manual</a></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">1.8 Backwards compatibility</a></h2>
|
|
<p> If you are a previous user of SWIG, don't expect SWIG to provide
|
|
complete backwards compatibility. Although the developers strive to the
|
|
utmost to keep backwards compatibility, this isn't always possible as
|
|
the primary goal over time is to make SWIG better---a process that
|
|
would simply be impossible if the developers are constantly bogged down
|
|
with backwards compatibility issues. Potential incompatibilities are
|
|
clearly marked in the detailed <a href="#Preface_release_notes">release
|
|
notes</a>.</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 SWIG feature */
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
<p> Note: The SWIG preprocessor has defined SWIG_VERSION since
|
|
SWIG-1.3.11.</p>
|
|
<p> The SWIG_VERSION macro is also generated into the SWIG wrapper file
|
|
for use by the C preprocessor in the generated code since SWIG-4.1.0.</p>
|
|
<h2><a name="Preface_release_notes">1.9 Release notes</a></h2>
|
|
<p> The CHANGES.current, CHANGES and RELEASENOTES files shipped with
|
|
SWIG in the top level directory contain, respectively, detailed release
|
|
notes for the current version, detailed release notes for previous
|
|
releases and summary release notes from SWIG-1.3.22 onwards.</p>
|
|
<h2><a name="Preface_nn10">1.10 Credits</a></h2>
|
|
<p> SWIG is an unfunded project that would not be possible without the
|
|
contributions of many people working in their spare time. If you have
|
|
benefitted from using SWIG, please consider <a href="https://www.swig.org/donate.html">
|
|
Donating to SWIG</a> to keep development going. There have been a large
|
|
varied number of people who have made contributions at all levels over
|
|
time. Contributors are mentioned either in the COPYRIGHT file or
|
|
CHANGES files shipped with SWIG or in submitted bugs.</p>
|
|
<h2><a name="Preface_nn11">1.11 Bug reports</a></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="https://www.swig.org/mail.html">
|
|
swig-devel mailing list</a> or report a bug at the <a href="https://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>
|
|
<h2><a name="Preface_installation">1.12 Installation</a></h2>
|
|
<h3><a name="Preface_windows_installation">1.12.1 Windows installation</a>
|
|
</h3>
|
|
<p> Please see the dedicated <a href="#Windows">Windows chapter</a> for
|
|
instructions on installing SWIG on Windows and running the examples.
|
|
The Windows distribution is called swigwin and includes a prebuilt SWIG
|
|
executable, swig.exe, included in the top level directory. Otherwise it
|
|
is exactly the same as the main SWIG distribution. There is no need to
|
|
download anything else.</p>
|
|
<h3><a name="Preface_unix_installation">1.12.2 Unix installation</a></h3>
|
|
<p> These installation instructions are for using the distributed
|
|
tarball, for example, <tt>swig-3.0.8.tar.gz</tt>. If you wish to build
|
|
and install from source on Github, extra steps are required. Please see
|
|
the <a href="https://swig.org/svn.html">Bleeding Edge</a> page on the
|
|
SWIG website.</p>
|
|
<p> You must use <a href="https://www.gnu.org/software/make/">GNU make</a>
|
|
to build and install SWIG.</p>
|
|
<p> <a href="https://www.pcre.org/">PCRE2</a> needs to be installed on
|
|
your system to build SWIG, in particular pcre2-config must be
|
|
available. If you have PCRE2 headers and libraries but not pcre2-config
|
|
itself or, alternatively, wish to override the compiler or linker flags
|
|
returned by pcre2-config, you may set PCRE2_LIBS and PCRE2_CFLAGS
|
|
variables to be used instead. And if you don't have PCRE2 at all, the
|
|
configure script will provide instructions for obtaining it.</p>
|
|
<p> To build and install SWIG, simply type the following:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ ./configure
|
|
$ make
|
|
$ make install
|
|
</pre>
|
|
</div>
|
|
<p> By default SWIG installs itself in /usr/local. If you need to
|
|
install SWIG in a different location or in your home directory, use the
|
|
<tt>--prefix</tt> option to <tt>./configure</tt>. For example:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ ./configure --prefix=/home/yourname/projects
|
|
$ make
|
|
$ make install
|
|
</pre>
|
|
</div>
|
|
<p> Note: the directory given to <tt>--prefix</tt> must be an absolute
|
|
pathname. Do<b> not</b> use the ~ shell-escape to refer to your home
|
|
directory. SWIG won't work properly if you do this.</p>
|
|
<p> The INSTALL file shipped in the top level directory details more
|
|
about using configure. Also try</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ ./configure --help.
|
|
</pre>
|
|
</div>
|
|
<p> The configure script will attempt to locate various packages on your
|
|
machine including Tcl, Perl5, Python and all the other target languages
|
|
that SWIG supports. Don't panic if you get 'not found' messages -- SWIG
|
|
does not need these packages to compile or run. The configure script is
|
|
actually looking for these packages so that you can try out the SWIG
|
|
examples contained in the 'Examples' directory without having to hack
|
|
Makefiles. Note that the <tt>--without-xxx</tt> options, where xxx is a
|
|
target language, have minimal effect. All they do is reduce the amount
|
|
of testing done with 'make check'. The SWIG executable and library
|
|
files installed cannot currently be configured with a subset of target
|
|
languages.</p>
|
|
<p> SWIG used to include a set of runtime libraries for some languages
|
|
for working with multiple modules. These are no longer built during the
|
|
installation stage. However, users can build them just like any wrapper
|
|
module as described in the <a href="#Modules">Modules chapter</a>. The
|
|
CHANGES file shipped with SWIG in the top level directory also lists
|
|
some examples which build the runtime library.</p>
|
|
<p> Note:</p>
|
|
<ul>
|
|
<li> If you checked the code out via Git, you will have to run <tt>
|
|
./autogen.sh</tt> before <tt>./configure</tt>. In addition, a full build
|
|
of SWIG requires a number of packages to be installed. Full
|
|
instructions at <a href="https://www.swig.org/svn.html">SWIG bleeding
|
|
edge</a>.</li>
|
|
</ul>
|
|
<h3><a name="Preface_osx_installation">1.12.3 Macintosh OS X
|
|
installation</a></h3>
|
|
<p> SWIG is known to work on various flavors of OS X. Follow the Unix
|
|
installation instructions above. However, as of this writing, there is
|
|
still great deal of inconsistency with how shared libraries are handled
|
|
by various scripting languages on OS X.</p>
|
|
<p> Users of OS X should be aware that Darwin handles shared libraries
|
|
and linking in a radically different way than most Unix systems. In
|
|
order to test SWIG and run the examples, SWIG configures itself to use
|
|
flat namespaces and to allow undefined symbols (<tt>-flat_namespace
|
|
-undefined suppress</tt>). This mostly closely follows the Unix model
|
|
and makes it more likely that the SWIG examples will work with whatever
|
|
installation of software you might have. However, this is generally not
|
|
the recommended technique for building larger extension modules.
|
|
Instead, you should utilize Darwin's two-level namespaces. Some details
|
|
about this can be found here <a href="https://developer.apple.com/library/mac/documentation/Porting/Conceptual/PortingUnix/compiling/compiling.html#//apple_ref/doc/uid/TP40002850-BCIHJBBF">
|
|
Understanding Two-Level Namespaces</a>.</p>
|
|
<p> Needless to say, you might have to experiment a bit to get things
|
|
working at first.</p>
|
|
<h3><a name="Preface_testing">1.12.4 Testing</a></h3>
|
|
<p> If you want to test SWIG after building it, a check can be performed
|
|
on Unix operating systems. Type the following:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ make -k check
|
|
</pre>
|
|
</div>
|
|
<p> This step can be performed either before or after installation. The
|
|
check requires at least one of the target languages to be installed. If
|
|
it fails, it may mean that you have an uninstalled language module or
|
|
that the file 'Examples/Makefile' has been incorrectly configured. It
|
|
may also fail due to compiler issues such as a broken C++ compiler.
|
|
Even if the check fails, there is a pretty good chance SWIG still works
|
|
correctly --- you will just have to mess around with one of the
|
|
examples and some makefiles to get it to work. Some tests may also fail
|
|
due to missing dependency packages, eg PCRE or Boost, but this will
|
|
require careful analysis of the configure output done during
|
|
configuration.</p>
|
|
<p> The test suite executed by the check is designed to stress-test many
|
|
parts of the implementation including obscure corner cases. If some of
|
|
these tests fail or generate warning messages, there is no reason for
|
|
alarm --- the test may be related to some new SWIG feature or a
|
|
difficult bug that we're trying to resolve. Chances are that SWIG will
|
|
work just fine for you. Note that if you have more than one CPU/core,
|
|
then you can use parallel make to speed up the check as it does take
|
|
quite some time to run, for example:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ make -j2 -k check
|
|
</pre>
|
|
</div>
|
|
<p> Also, SWIG's support for C++ is sufficiently advanced that certain
|
|
tests may fail on older C++ compilers (for instance if your compiler
|
|
does not support member templates). These errors are harmless if you
|
|
don't intend to use these features in your own programs.</p>
|
|
<p> Note: The test-suite currently contains over 800 tests. If you have
|
|
many different target languages installed and a slow machine, it might
|
|
take more than an hour to run the test-suite.</p>
|
|
<h3><a name="Preface_examples">1.12.5 Examples</a></h3>
|
|
<p> The Examples directory contains a variety of examples of using SWIG
|
|
and it has some browsable documentation. Simply point your browser to
|
|
the file "Example/index.html".</p>
|
|
<p> The Examples directory also includes Visual C++ project 6 (.dsp)
|
|
files for building some of the examples on Windows. Later versions of
|
|
Visual Studio will convert these old style project files into a current
|
|
solution file.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Introduction">2 Introduction</a></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_target_languages">Target languages</a>
|
|
<ul>
|
|
<li><a href="#Introduction_supported_status">Supported status</a></li>
|
|
<li><a href="#Introduction_experimental_status">Experimental status</a></li>
|
|
<li><a href="#Introduction_deprecated_status">Deprecated status</a></li>
|
|
</ul>
|
|
</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">2.1 What is SWIG?</a></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/C++ declarations and creates the
|
|
wrappers needed to access those declarations from other languages
|
|
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 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. However, nowadays SWIG is known to be used in
|
|
many large open source and commercial projects.</p>
|
|
<h2><a name="Introduction_nn3">2.2 Why use SWIG?</a></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 overflows 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_target_languages">2.3 Target languages</a></h2>
|
|
<p> SWIG in essence is a tool to generate code for making C/C++ code
|
|
available to various other programming languages. These higher level
|
|
programming languages are the target languages for the SWIG code
|
|
generator and C or C++ are the input languages. A single target
|
|
language must be specified when SWIG is run. This results in generating
|
|
code for C/C++ and the specified target language to interface with each
|
|
other. SWIG can be invoked multiple times, but with a different target
|
|
language specified on each invocation. This ability to interface C/C++
|
|
to many different target languages is one of SWIG's core strengths and
|
|
features.</p>
|
|
<p> SWIG is very broadly composed of two components. A core component
|
|
creates a parse tree from the input ISO C/C++ and SWIG directives
|
|
(extensions to the C/C++ standards). The parse tree is then passed to a
|
|
second component, one of the target language modules for generating
|
|
code specific to a higher level language. SWIG supports many different
|
|
target languages. These target languages are given a status of either
|
|
Supported, Experimental or Deprecated. This status is provided to
|
|
indicate the level of maturity to expect when using a particular target
|
|
language as not all target languages are fully developed or being kept
|
|
up to date.</p>
|
|
<p> The second part of the SWIG documentation contains a chapter for
|
|
each target level language. The target language chapters are under one
|
|
of the sections indicating the status (Supported, Experimental or
|
|
Deprecated) for that language.</p>
|
|
<h3><a name="Introduction_supported_status">2.3.1 Supported status</a></h3>
|
|
<p> A target language is given the 'Supported' status when</p>
|
|
<ul>
|
|
<li>It is in a mature, well functioning state.</li>
|
|
<li>It has its own comprehensive chapter in the documentation.</li>
|
|
<li>It passes all of the main SWIG test-suite and has a range of working
|
|
examples.</li>
|
|
<li>It supports the vast majority of SWIG features.</li>
|
|
<li>It provides strong backwards compatibility between releases.</li>
|
|
</ul>
|
|
<p> The above is a short summary and further details are outlined in the
|
|
<a href="#Extending_supported_status">Supported status</a> section in
|
|
the Extending chapter. The good news is that all the well-known and
|
|
most popular languages have this status.</p>
|
|
<h3><a name="Introduction_experimental_status">2.3.2 Experimental status</a>
|
|
</h3>
|
|
<p> A target language is given the 'Experimental' status when</p>
|
|
<ul>
|
|
<li>It is of sub-standard quality, failing to meet the above 'Supported'
|
|
status.</li>
|
|
<li>It is somewhere between the mid to mature stage of development.</li>
|
|
<li>It does not guarantee any backwards compatibility between releases.</li>
|
|
<li>It is in need of help to finish development.</li>
|
|
</ul>
|
|
<p> Anyone using an experimental target language is strongly urged to
|
|
assist with development of the target language module if they wish to
|
|
use it.</p>
|
|
<p> SWIG displays a warning when an experimental target language is used
|
|
in order to set expectations and emphasize the experimental status of
|
|
the target language. The usual <a href="#Warnings_suppression">warning
|
|
suppression</a> techniques can be used if required.</p>
|
|
<p> The above is a short summary and further details are outlined in the
|
|
<a href="#Extending_experimental_status">Experimental status</a>
|
|
section in the Extending chapter.</p>
|
|
<h3><a name="Introduction_deprecated_status">2.3.3 Deprecated status</a></h3>
|
|
<p> A target language that was once 'Supported' or 'Experimental' is
|
|
changed to the 'Deprecated' status when it has been neglected over time
|
|
and become non-functional. It requires interested community member's
|
|
contributions to restore it to its former status.</p>
|
|
<p> Please see the <a href="#Extending_deprecated_status">Deprecated
|
|
status</a> section in the Extending chapter for more details.</p>
|
|
<p> SWIG displays a deprecated warning notice whenever a 'Deprecated'
|
|
language is used. The usual <a href="#Warnings_suppression">warning
|
|
suppression</a> techniques can be used if required.</p>
|
|
<h2><a name="Introduction_nn4">2.4 A SWIG example</a></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">2.4.1 SWIG interface file</a></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 ISO 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, into the generated C wrapper code.</p>
|
|
<h3><a name="Introduction_nn6">2.4.2 The swig command</a></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>
|
|
$ <b>swig -tcl example.i</b>
|
|
$ <b>gcc -c -fPIC example.c example_wrap.c -I/usr/include/tcl8.7</b>
|
|
$ <b>gcc -shared example.o example_wrap.o -o example.so</b>
|
|
$ <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">2.4.3 Building a Perl5 module</a></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">2.4.4 Building a Python module</a></h3>
|
|
<p> Finally, let's build a module for Python (shown for Linux).</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ <b>swig -python example.i</b>
|
|
$ <b>gcc -c -fPIC example.c example_wrap.c -I/usr/include/python3.12</b>
|
|
$ <b>gcc -shared example.o example_wrap.o -o _example.so</b>
|
|
$ <b>python3</b>
|
|
Python 3.12.4 (main, Jun 12 2024, 19:06:53) [GCC 13.2.0] on linux
|
|
Type "help", "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">2.4.5 Shortcuts</a></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">2.5 Supported C/C++ language features</a>
|
|
</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 ISO 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> Most of C++11 is also supported. Details are in the <a href="#CPlusPlus11">
|
|
C++11</a> chapter. C++14 support is covered in the <a href="#CPlusPlus14">
|
|
C++14</a> chapter. C++17 support is covered in the <a href="#CPlusPlus17">
|
|
C++17</a> chapter. C++20 support is covered in the <a href="#CPlusPlus20">
|
|
C++20</a> chapter.</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 to handle C++ code that stresses
|
|
the very limits of many C++ compilers.</p>
|
|
<h2><a name="Introduction_nn11">2.6 Non-intrusive interface building</a></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">2.7 Incorporating SWIG into a
|
|
build system</a></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 popular IDEs such as Microsoft Visual Studio.</p>
|
|
<p> If you are using the GNU Autotools (<a href="https://www.gnu.org/software/autoconf/">
|
|
Autoconf</a>/ <a href="https://www.gnu.org/software/automake/">Automake</a>
|
|
/ <a href="https://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>ax_pkg_swig</tt>, see <a href="https://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig">
|
|
http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig
|
|
</a>. The <tt>ax_python_devel</tt> macro is also helpful for generating
|
|
Python extensions. See the <a href="https://www.gnu.org/software/autoconf-archive/">
|
|
Autoconf 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="https://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 can also generate the custom commands necessary
|
|
for driving SWIG from IDEs 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">2.8 Hands off code generation</a></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">2.9 SWIG and freedom</a></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 its core, SWIG
|
|
tries to distill even the most advanced C++ code down to a small
|
|
well-defined set of interface building techniques based on ISO 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. Dependencies are often
|
|
a source of incompatibilities and problems and so additional third
|
|
party libraries are not used in the generated code. SWIG will also
|
|
generally avoid generating code that introduces a dependency on the C++
|
|
Standard Template Library (STL). SWIG will generate code that depends
|
|
on the C libraries though.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Windows">3 Getting started on Windows</a></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_python">Python</a></li>
|
|
<li><a href="#Windows_tcl">TCL</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_swig_exe">Building swig.exe on Windows</a>
|
|
<ul>
|
|
<li><a href="#Windows_cmake">Building swig.exe using CMake</a></li>
|
|
<li><a href="#Windows_msys2">Building swig.exe using MSYS2 and MinGW-w64</a>
|
|
</li>
|
|
<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>
|
|
<ul>
|
|
<li><a href="#Windows_examples_cygwin">Running the examples on Windows
|
|
using Cygwin</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Windows_interface_file">Microsoft extensions and other
|
|
Windows quirks</a>
|
|
<ul>
|
|
<li><a href="#Windows_msvc_cpp_standards">Visual C++ standards
|
|
compliance</a></li>
|
|
<li><a href="#Windows_calling_conventions">Calling conventions</a></li>
|
|
</ul>
|
|
</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">3.1 Installation on Windows</a></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="https://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">3.1.1 Windows Executable</a></h3>
|
|
<p> The swigwin distribution contains the SWIG Windows 64-bit
|
|
executable, swig.exe, which will only run on 64-bit versions of
|
|
Windows. 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">3.2 SWIG Windows Examples</a></h2>
|
|
<p> Microsoft Visual C++ is used for compiling and linking SWIG's output
|
|
on Windows for some languages. However, MinGW and gcc is often the only
|
|
supported toolchain for a number of target languages. The Examples
|
|
directory has a few Visual C++ project files (.vcxproj files) where the
|
|
target languages are known to work with Visual C++. These were produced
|
|
by Visual Studio 2019. Newer versions of Visual Studio, such as Visual
|
|
Studio 2022, are able to open and convert these project files if
|
|
necessary. Each C# example comes with a Visual Studio 2019 solution in
|
|
addition to the .vcxproj file the C# (.csproj) project file. 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">3.2.1 Instructions for using the
|
|
Examples with Visual Studio</a></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 Studio must be re-started to pick up any changes in
|
|
environment variables. Open up an example .vcxproj file or .sln file,
|
|
Visual Studio will prompt you to upgrade the project if necessary.
|
|
Ensure the Release build is selected then do a Rebuild Solution from
|
|
the Build menu. The required environment variables are displayed with
|
|
their current values during the build.</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">3.2.1.1 C#</a></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 2019 or later, select Release Build, and do a Rebuild
|
|
Solution from the Build menu. The accompanying C# and C++ project files
|
|
are automatically used by the solution file.</p>
|
|
<h4><a name="Windows_java">3.2.1.2 Java</a></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 the openjdk package installed in a Conda environment:
|
|
<br> <tt>JAVA_INCLUDE: C:\miniconda3\envs\java\Library\lib\jvm\include
|
|
<br> JAVA_BIN: C:\miniconda3\envs\java\Library\lib\jvm\bin
|
|
<br></tt></p>
|
|
<h4><a name="Windows_python">3.2.1.3 Python</a></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 3.13 installed in a Conda environment:
|
|
<br> <tt>PYTHON_INCLUDE: C:\miniconda3\envs\python\include
|
|
<br> PYTHON_LIB: C:\miniconda3\envs\python\libs\python313.lib
|
|
<br></tt></p>
|
|
<h4><a name="Windows_tcl">3.2.1.4 TCL</a></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.6
|
|
<br> <tt>TCL_INCLUDE: C:\ActiveTcl\include
|
|
<br> TCL_LIB: C:\ActiveTcl\lib\tcl86t.lib
|
|
<br></tt></p>
|
|
<h3><a name="Windows_other_compilers">3.2.2 Instructions for using the
|
|
Examples with other compilers</a></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_swig_exe">3.3 Building swig.exe on Windows</a></h2>
|
|
<p> The SWIG distribution provides a pre-built swig.exe and so it is not
|
|
necessary for users to build the SWIG executable. However, this section
|
|
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>
|
|
<p> There are various ways to build the SWIG executable including <a href="https://cmake.org/">
|
|
CMake</a> which is able to generate project files for building with <a href="https://visualstudio.microsoft.com/">
|
|
Visual Studio</a> <a href="https://docs.microsoft.com/cpp/">MSVC</a>.
|
|
<br> SWIG can also be compiled and run using <a href="https://www.msys2.org/">
|
|
MSYS2</a> with <a href="https://www.mingw-w64.org/">MinGW-w64</a>, <a href="https://www.cygwin.com">
|
|
Cygwin</a> or <a href="https://osdn.net/projects/mingw/">MinGW</a>, all
|
|
of which provide a Unix like front end to Windows and comes free with
|
|
the <a href="https://gcc.gnu.org/">GCC</a> C/C++ compiler.
|
|
<br> SWIG can also be compiled with MSYS2 using MSVC and SWIG <a href="https://github.com/swig/cccl">
|
|
MSVC wrapper</a>.
|
|
<br></p>
|
|
<h3><a name="Windows_cmake">3.3.1 Building swig.exe using CMake</a></h3>
|
|
<p> SWIG can be built using <a href="https://cmake.org/">CMake</a> and
|
|
Visual Studio rather than autotools. As with the other approaches to
|
|
building SWIG the dependencies need to be installed. The steps below
|
|
are one of a number of ways of installing the dependencies without
|
|
requiring Cygwin or MinGW. For fully working build steps always check
|
|
the Continuous Integration (CI) setups currently detailed in the <a href="https://github.com/swig/swig/tree/master/.github/workflows/nuget.yml">
|
|
GitHub Actions YAML file</a>.</p>
|
|
<ol>
|
|
<li> Install Nuget from <a href="https://www.nuget.org/downloads">
|
|
https://www.nuget.org/downloads</a> (v6.0.0 is used in this example, and
|
|
installed to <tt>C:\Tools</tt>). Nuget is the package manager for .NET,
|
|
but allows us to easily install <a href="https://cmake.org/">CMake</a>
|
|
and other dependencies required by SWIG.</li>
|
|
<li> Install <a href="https://www.nuget.org/packages/CMake-win64/">
|
|
CMake-win64 Nuget package</a> using the following command:
|
|
<pre>C:\Tools\nuget install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake</pre>
|
|
Using PowerShell the equivalent syntax is:
|
|
<pre>& "C:\Tools\nuget" install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake</pre>
|
|
Alternatively you can download CMake from <a href="https://cmake.org/download/">
|
|
https://cmake.org/download/</a>.</li>
|
|
<li> Install the <a href="https://www.nuget.org/packages/bison/">Bison
|
|
Nuget package</a> using the following command:
|
|
<pre>C:\Tools\nuget install Bison -Version 3.7.4 -OutputDirectory C:\Tools\bison</pre>
|
|
Alternatively download Bison from <a href="https://sourceforge.net/projects/winflexbison/files/">
|
|
https://sourceforge.net/projects/winflexbison/files/</a> (Bison 3.7.4 is
|
|
used in this example) and save to a folder e.g. <tt>C:\Tools\Bison</tt></li>
|
|
<li> Install the <a href="https://www.nuget.org/packages/pcre2/">PCRE2
|
|
Nuget package</a> using the following command:
|
|
<pre>C:\Tools\nuget install PCRE2 -Version 10.39 -OutputDirectory C:\Tools\pcre2</pre>
|
|
Note this is a x64 build, if this is not suitable PCRE2 can be built
|
|
from source using <a href="https://github.com/PhilipHazel/pcre2/">
|
|
https://github.com/PhilipHazel/pcre2/</a>. Alternatively, set <tt>
|
|
WITH_PCRE=OFF</tt> to disable PCRE2 support if you are sure you do not
|
|
require it.</li>
|
|
<li> We will also need the SWIG source code. Either download a zipped
|
|
archive from GitHub, or if git is installed clone the latest codebase
|
|
using:
|
|
<pre>git clone https://github.com/swig/swig.git</pre>
|
|
In this example we are assuming the source code is available at <tt>
|
|
C:\swig</tt></li>
|
|
<li>
|
|
<p> Now we have all the required dependencies we can build SWIG using
|
|
PowerShell and the commands below. We are assuming Visual Studio 2019
|
|
is installed. For other versions of Visual Studio change <tt>"Visual
|
|
Studio 16 2019 -A x64"</tt> to the relevant <a href="https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators">
|
|
Visual Studio Generator</a> and architecture. We add the required build
|
|
tools to the system PATH, and then build a Release version of SWIG. If
|
|
all runs successfully a new swig.exe should be generated in the <tt>
|
|
C:/swig/install2/bin</tt> folder.</p>
|
|
</li>
|
|
</ol>
|
|
<div class="shell">
|
|
<pre>
|
|
cd C:\swig
|
|
|
|
$env:PATH="C:\Tools\CMake\CMake-win64.3.15.5\bin;C:\Tools\bison\Bison.3.7.4\bin;" + $env:PATH
|
|
$PCRE_ROOT="C:\Tools\pcre2\PCRE2.10.39.0"
|
|
|
|
cmake -G "Visual Studio 16 2019" -A "x64" `
|
|
-DCMAKE_INSTALL_PREFIX="C:/swig/install2" `
|
|
-DCMAKE_C_FLAGS="/DPCRE2_STATIC" `
|
|
-DCMAKE_CXX_FLAGS="/DPCRE2_STATIC" `
|
|
-DPCRE2_INCLUDE_DIR="$PCRE_ROOT/include" `
|
|
-DPCRE2_LIBRARY="$PCRE_ROOT/lib/pcre2-8-static.lib" `
|
|
-S . -B build
|
|
|
|
cmake --build build --config Release
|
|
cmake --install build --config Release
|
|
|
|
# to test the exe built correctly
|
|
cd install2/bin
|
|
./swig.exe -version
|
|
./swig.exe -help
|
|
</pre>
|
|
</div>
|
|
<p> In addition to Release builds you can create a Debug build using:</p>
|
|
<div class="shell">
|
|
<pre>cmake --build build --config Debug</pre>
|
|
</div>
|
|
<p> A Visual Studio solution file should be generated named swig.sln.
|
|
This can be opened and debugged by running the swig project and setting
|
|
<tt>Properties > Debugging > Command Arguments</tt>. For example to
|
|
debug one of the test-suite .i files included with the SWIG source use
|
|
the following:</p>
|
|
<div class="shell">
|
|
<pre>-python -c++ -o C:\Temp\doxygen_parsing.cpp C:\swig\Examples\test-suite\doxygen_parsing.i</pre>
|
|
</div>
|
|
<h3><a name="Windows_msys2">3.3.2 Building swig.exe using MSYS2 and
|
|
MinGW-w64</a></h3>
|
|
<p> Download and install MSYS2 from <a href="https://www.msys2.org/">
|
|
www.msys2.org</a> (tested with version msys2-x86_64-20201109). Launch
|
|
the MSYS2 shell.</p>
|
|
<p> Install the packages needed to build swig:
|
|
<br></p>
|
|
<div class="shell">
|
|
<pre>
|
|
pacman -S git autoconf automake bison gcc make pcre2-devel
|
|
</pre>
|
|
</div>
|
|
<p> Clone the repository to /usr/src/:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
mkdir /usr/src/
|
|
cd /usr/src/
|
|
git clone https://github.com/swig/swig.git
|
|
</pre>
|
|
</div>
|
|
<p> Configure and build:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
cd /usr/src/swig
|
|
./autogen.sh
|
|
./configure
|
|
make
|
|
</pre>
|
|
</div>
|
|
<p> Finally you may also want to install SWIG:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make install
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Windows_mingw_msys">3.3.3 Building swig.exe using MinGW and
|
|
MSYS</a></h3>
|
|
<p>Warning: These instructions were added in 2006 and have barely
|
|
changed since so are unlikely to work exactly as written.</p>
|
|
<p> The short abbreviated instructions follow...</p>
|
|
<ul>
|
|
<li>Install MinGW and MSYS from the <a href="https://osdn.net/projects/mingw/">
|
|
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 Github
|
|
follow... Note that the instructions for obtaining SWIG from Github are
|
|
also online at <a href="https://www.swig.org/svn.html">SWIG Bleeding
|
|
Edge</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="https://osdn.net/projects/mingw/releases/">
|
|
MinGW 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 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> The very latest development version of SWIG is available from <a href="https://github.com/swig/swig">
|
|
SWIG on Github</a> and can be downloaded as a zip file or if you have
|
|
Git installed, via Git. Either download the latest <a href="https://github.com/swig/swig/archive/master.zip">
|
|
Zip file</a> snapshot and unzip and rename the top level folder to
|
|
/usr/src/swig. Otherwise if using Git, type in the following:<div class="shell">
|
|
<pre>
|
|
mkdir /usr/src
|
|
cd /usr/src
|
|
git clone https://github.com/swig/swig.git
|
|
</pre>
|
|
</div><b> Pitfall note:</b> If you want to place SWIG in 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> The PCRE2 third party library needs to be built next. Download the
|
|
latest PCRE2 source tarball, such as <tt>pcre2-10.39.tar.bz2</tt>, from
|
|
<a href="https://www.pcre.org">www.pcre.org</a> and place in the <tt>
|
|
/usr/src/swig</tt> directory. Build PCRE2 as a static library using the
|
|
Tools/pcre-build.sh script as follows:<div class="shell">
|
|
<pre>
|
|
cd /usr/src/swig
|
|
Tools/pcre-build.sh
|
|
</pre>
|
|
</div></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>
|
|
<h3><a name="Windows_cygwin">3.3.4 Building swig.exe using Cygwin</a></h3>
|
|
<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_examples_cygwin">3.3.4.1 Running the examples on
|
|
Windows using Cygwin</a></h4>
|
|
<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">3.4 Microsoft extensions and other
|
|
Windows quirks</a></h2>
|
|
<h3><a name="Windows_msvc_cpp_standards">3.4.1 Visual C++ standards
|
|
compliance</a></h3>
|
|
<p> The Visual C++ compiler (MSVC) has a long history of not being
|
|
standards compliant, but this has been getting better over the years.</p>
|
|
<p> SWIG's <a href="#SWIGPlus_nn3">approach for C++</a> is to generate
|
|
standards compliant C++98 code along with enhancements for later
|
|
standards if the C++ compiler supports a later standard. Unfortunately
|
|
by default, in 2024, Visual C++ still does not set the <tt>__cplusplus</tt>
|
|
macro correctly to pick up these later C++ standard features. MSVC
|
|
users are urged to ensure this macro is defined correctly by consulting
|
|
the latest Microsoft Visual C++ documentation, in particular, <a href="https://learn.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version">
|
|
/std</a> and <a href="https://learn.microsoft.com/en-us/cpp/build/reference/zc-cplusplus">
|
|
/Zc:__cplusplus</a>.</p>
|
|
<h3><a name="Windows_calling_conventions">3.4.2 Calling conventions</a></h3>
|
|
<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>
|
|
<p>Note that if you follow Microsoft's recommendation of wrapping the <tt>
|
|
__declspec</tt> calls in a preprocessor definition, you will need to
|
|
make sure that the definition is included by SWIG as well, by either
|
|
defining it manually or via a header. For example, if you have
|
|
specified the preprocessor definition in a header named <tt>
|
|
export_lib.h</tt> and include other headers which depend on it, you
|
|
should use the <tt>%include</tt> directive to include the definition
|
|
explicitly. For example, if you had a header file, <tt>bar.h</tt>,
|
|
which depended on <tt>export_lib.h</tt>, your SWIG definition file
|
|
might look like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// bar.i
|
|
%module bar
|
|
%include <windows.i>
|
|
%include "export_lib.h"
|
|
%include "bar.h"
|
|
</pre>
|
|
</div>
|
|
<p> where export_lib.h may contain:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// export_lib.h
|
|
#define BAR_API __declspec(dllexport)
|
|
</pre>
|
|
</div>
|
|
<p> and bar.h may look like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// bar.h
|
|
#include "export_lib.h"
|
|
BAR_API void bar_function(int, double);
|
|
</pre>
|
|
</div>
|
|
<p> Using the preprocessor to remove BAR_API is a popular simpler
|
|
solution:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// bar.i
|
|
%module bar
|
|
#define BAR_API
|
|
%include "bar.h"
|
|
</pre>
|
|
</div><HR NOSHADE>
|
|
<h1><a name="Scripting">4 Scripting Languages</a></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">4.1 The two language view of the world</a></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">4.2 How does a scripting language talk to C?</a>
|
|
</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">4.2.1 Wrapper functions</a></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">4.2.2 Variable linking</a></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">4.2.3 Constants</a></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">4.2.4 Structures and classes</a></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">4.2.5 Proxy classes</a></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 really at 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">4.3 Building scripting language extensions</a>
|
|
</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 of a
|
|
shared library. Alternatively, you can recompile the scripting language
|
|
interpreter with your extensions added to it.</p>
|
|
<h3><a name="Scripting_nn10">4.3.1 Shared libraries and dynamic loading</a>
|
|
</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 platforms is shown below:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
# Build a shared library for Solaris
|
|
gcc -fPIC -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
|
|
</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">4.3.2 Linking with shared libraries</a></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">4.3.3 Static linking</a></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">5 SWIG Basics</a></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="#SWIG_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>
|
|
<li><a href="#SWIG_parse_tree">Parse tree</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 const</a></li>
|
|
<li><a href="#SWIG_nn14">A cautionary tale of char *</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 char *</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>
|
|
<ul>
|
|
<li><a href="#SWIG_nn29">Simple renaming of specific identifiers</a></li>
|
|
<li><a href="#SWIG_ignore">Ignoring identifiers</a></li>
|
|
<li><a href="#SWIG_advanced_renaming">Advanced renaming support</a></li>
|
|
<li><a href="#SWIG_limiting_renaming">Limiting global renaming rules</a></li>
|
|
<li><a href="#SWIG_chosen_unignore">Ignoring everything then wrapping a
|
|
few selected symbols</a></li>
|
|
</ul>
|
|
</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 ISO 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">5.1 Running SWIG</a></h2>
|
|
<p> To run SWIG, use the <tt>swig</tt> command with options and a
|
|
filename like this:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
swig [ options ] filename
|
|
</pre>
|
|
</div>
|
|
<p> where <tt>filename</tt> is a SWIG interface file or a C/C++ header
|
|
file. Full help can be seen by running <tt>swig -help</tt>. Below is
|
|
the common set of options that can be used. Additional options are also
|
|
defined for each target language. A full list can be obtained by
|
|
running <tt>swig<em> -<lang></em> -help</tt> for language<em> <lang></em>
|
|
specific options, for example, <tt>swig -ruby -help</tt> for Ruby.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
Supported Target Language Options
|
|
-csharp - Generate C# wrappers
|
|
-d - Generate D wrappers
|
|
-go - Generate Go wrappers
|
|
-guile - Generate Guile wrappers
|
|
-java - Generate Java wrappers
|
|
-javascript - Generate Javascript wrappers
|
|
-lua - Generate Lua wrappers
|
|
-octave - Generate Octave wrappers
|
|
-perl5 - Generate Perl 5 wrappers
|
|
-php7 - Generate PHP 8 or later wrappers
|
|
-python - Generate Python wrappers
|
|
-r - Generate R (aka GNU S) wrappers
|
|
-ruby - Generate Ruby wrappers
|
|
-scilab - Generate Scilab wrappers
|
|
-tcl8 - Generate Tcl 8 wrappers
|
|
-xml - Generate XML wrappers
|
|
|
|
Experimental Target Language Options
|
|
-c - Generate C wrappers
|
|
-ocaml - Generate OCaml wrappers
|
|
|
|
Deprecated Target Language Options
|
|
-mzscheme - Generate MzScheme/Racket wrappers
|
|
|
|
General Options
|
|
-addextern - Add extra extern declarations
|
|
-c++ - Enable C++ processing
|
|
-co <file> - Check <file> out of the SWIG library
|
|
-copyctor - Automatically generate copy constructors wherever possible
|
|
-cpperraswarn - Treat the preprocessor #error statement as #warning (default)
|
|
-cppext <ext> - Change file extension of generated C++ files to <ext>
|
|
(default is cxx)
|
|
-copyright - Display copyright notices
|
|
-debug-classes - Display information about the classes found in the interface
|
|
-debug-module <n>- Display module parse tree at stages 1-4, <n> is a csv list of stages
|
|
-debug-symtabs - Display symbol tables information
|
|
-debug-symbols - Display target language symbols in the symbol tables
|
|
-debug-csymbols - Display C symbols in the symbol tables
|
|
-debug-lsymbols - Display target language layer symbols
|
|
-debug-quiet - Display less parse tree node debug info when using other -debug options
|
|
-debug-tags - Display information about the tags found in the interface
|
|
-debug-template - Display information for debugging templates
|
|
-debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages
|
|
-debug-typedef - Display information about the types and typedefs in the interface
|
|
-debug-typemap - Display typemap debugging information
|
|
-debug-tmsearch - Display typemap search debugging information
|
|
-debug-tmused - Display typemaps used debugging information
|
|
-directors - Turn on director mode for all the classes, mainly for testing
|
|
-dirprot - Turn on wrapping of protected members for director classes (default)
|
|
-D<symbol>[=<value>] - Define symbol <symbol> (for conditional compilation)
|
|
-E - Preprocess only, does not generate wrapper code
|
|
-external-runtime [file] - Export the SWIG runtime stack
|
|
-fakeversion <v>- Make SWIG fake the program version number to <v>
|
|
-fcompact - Compile in compact mode
|
|
-features <list>- Set global features, where <list> is a comma separated list of
|
|
features, eg -features directors,autodoc=1
|
|
If no explicit value is given to the feature, a default of 1 is used
|
|
-fastdispatch - Enable fast dispatch mode to produce faster overload dispatcher code
|
|
-Fmicrosoft - Display error/warning messages in Microsoft format
|
|
-Fstandard - Display error/warning messages in commonly used format
|
|
-fvirtual - Compile in virtual elimination mode
|
|
-help - Display help
|
|
-I- - Don't search the current directory
|
|
-I<dir> - Look for SWIG files in directory <dir>
|
|
-ignoremissing - Ignore missing include files
|
|
-importall - Follow all #include statements as imports
|
|
-includeall - Follow all #include statements
|
|
-l<ifile> - Include SWIG library file <ifile>
|
|
-macroerrors - Report errors inside macros
|
|
-M - List all dependencies
|
|
-MD - Is equivalent to `-M -MF <file>', except `-E' is not implied
|
|
-MF <file> - Generate dependencies into <file> and continue generating wrappers
|
|
-MM - List dependencies, but omit files in SWIG library
|
|
-MMD - Like `-MD', but omit files in SWIG library
|
|
-module <name> - Set module name to <name>
|
|
-MP - Generate phony targets for all dependencies
|
|
-MT <target> - Set the target of the rule emitted by dependency generation
|
|
-nocontract - Turn off contract checking
|
|
-nocpperraswarn - Do not treat the preprocessor #error statement as #warning
|
|
-nodefaultctor - Do not generate implicit default constructors
|
|
-nodefaultdtor - Do not generate implicit default destructors
|
|
-nodirprot - Do not wrap director protected members
|
|
-noexcept - Do not wrap exception specifiers
|
|
-nofastdispatch - Disable fast dispatch mode (default)
|
|
-nopreprocess - Skip the preprocessor step
|
|
-notemplatereduce - Disable reduction of the typedefs in templates
|
|
-O - Enable the optimization options:
|
|
-fastdispatch -fvirtual
|
|
-o <outfile> - Set name of C/C++ output file to <outfile>
|
|
-oh <headfile> - Set name of C++ output header file for directors to <headfile>
|
|
-outcurrentdir - Set default output dir to current dir instead of input file's path
|
|
-outdir <dir> - Set language specific files output directory to <dir>
|
|
-pcreversion - Display PCRE2 version information
|
|
-small - Compile in virtual elimination and compact mode
|
|
-std=<standard> - Set the C or C++ language <standard> for inputs
|
|
-swiglib - Report location of SWIG library and exit
|
|
-templatereduce - Reduce all the typedefs in templates
|
|
-U<symbol> - Undefine symbol <symbol>
|
|
-v - Run in verbose mode
|
|
-version - Display SWIG version number
|
|
-Wall - Remove all warning suppression, also implies -Wextra
|
|
-Wallkw - Enable keyword warnings for all the supported languages
|
|
-Werror - Treat warnings as errors
|
|
-Wextra - Adds the following additional warnings: 309,403,405,512,321,322
|
|
-w<list> - Suppress/add warning messages, eg -w401,+321 - see Warnings.html
|
|
-xmlout <file> - Write XML version of the parse tree to <file> after normal processing
|
|
</pre>
|
|
</div>
|
|
<p> Arguments may also be passed in a command-line options file (also
|
|
known as a response file) which is useful if they exceed the system
|
|
command line length limit. To do this, put the arguments in a file,
|
|
then provide the file name prefixed with <tt>@</tt> like so:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
swig @<em>file</em>
|
|
</pre>
|
|
</div>
|
|
<p> The options read from the file are inserted in place of the file
|
|
option. If the file does not exist, or cannot be read, then the option
|
|
will be treated literally and not removed.</p>
|
|
<p> Options in the file are separated by whitespace. A whitespace
|
|
character may be included in an option by surrounding the entire option
|
|
in either single or double quotes. Any character (including a
|
|
backslash) may be included by prefixing the character to be included
|
|
with a backslash. The file may itself contain additional <tt>@file</tt>
|
|
options; any such options will be processed recursively.</p>
|
|
<h3><a name="SWIG_nn3">5.1.1 Input format</a></h3>
|
|
<p> As input, SWIG expects a file containing ISO 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 ISO 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="SWIG_output">5.1.2 SWIG output</a></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 C/C++
|
|
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 an 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> For many target languages SWIG 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 overridden
|
|
with <tt>-outdir</tt>.</p>
|
|
<h3><a name="SWIG_nn5">5.1.3 Comments</a></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. Doxygen comments can now be used to generate target language
|
|
specific documentation, see the <a href="Doxygen.html">Doxygen</a>
|
|
chapter.</p>
|
|
<h3><a name="SWIG_nn6">5.1.4 C Preprocessor</a></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">5.1.5 SWIG directives</a></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">5.1.6 Parser limitations</a></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>
|
|
<p> Non-conventional type declarations. For example, SWIG does not
|
|
support declarations such as the following (even though this is legal
|
|
C):</p>
|
|
<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>
|
|
<p> Running SWIG on C++ source files (the code in a .C, .cpp or .cxx
|
|
file) is not recommended. The usual approach is to feed SWIG header
|
|
files for parsing C++ definitions and declarations. The main reason is
|
|
if SWIG parses a scoped definition or declaration (as is normal for C++
|
|
source files), it is ignored, unless a declaration for the symbol was
|
|
parsed earlier. For example</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* bar not wrapped unless foo has been defined and
|
|
the declaration of bar within foo has already been parsed */
|
|
int foo::bar(int) {
|
|
... whatever ...
|
|
}
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p> Certain advanced features of C++ such as nested classes are not yet
|
|
fully supported. Please see the C++ <a href="#SWIGPlus_nested_classes">
|
|
Nested classes</a> section for more information.</p>
|
|
</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>
|
|
<h3><a name="SWIG_parse_tree">5.1.7 Parse tree</a></h3>
|
|
<p> SWIG can dump its parse tree in either a simple text or XML format.
|
|
This can be useful for advanced development or debugging purposes.
|
|
Details are covered in the developer documentation <a href="#Extending">
|
|
Extending SWIG</a> chapter.</p>
|
|
<h2><a name="SWIG_nn9">5.2 Wrapping simple C declarations</a></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 describe various aspects of
|
|
this mapping.</p>
|
|
<h3><a name="SWIG_nn10">5.2.1 Basic type handling</a></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">5.2.2 Global variables</a></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">5.2.3 Constants</a></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 point constant with cast
|
|
</pre>
|
|
</div>
|
|
<p> This logic can lead to false attempts at converting <tt>#define</tt>
|
|
into <tt>%constant</tt> though. For example the following case does not
|
|
have any undefined symbols within the macro:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// For indicating pure virtual functions such as: virtual void f() PURE;
|
|
#define PURE = 0
|
|
</pre>
|
|
</div>
|
|
<p> A warning is issued:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
pure.h:1: Warning 305: Bad constant value (ignored).
|
|
</pre>
|
|
</div>
|
|
<p> In such cases simply ignore the warning or suppress it using the
|
|
normal warning suppression techniques.</p>
|
|
<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 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">5.2.4 A brief word about const</a></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> Please note that for const parameters or return types used in a
|
|
function, SWIG pretty much ignores the fact that these are const, see
|
|
the section on <a href="#SWIGPlus_const">const-correctness</a> for more
|
|
information.</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">5.2.5 A cautionary tale of char *</a></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
|
|
to 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">5.3 Pointers and complex objects</a></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">5.3.1 Simple pointers</a></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">5.3.2 Run time pointer type checking</a></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">5.3.3 Derived types, structs, and classes</a></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">5.3.4 Undefined datatypes</a></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">5.3.5 Typedef</a></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">5.4 Other Practicalities</a></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">5.4.1 Passing structures by value</a></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">5.4.2 Return by value</a></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_product(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_product(Vector *v1, Vector *v2) {
|
|
Vector x = *v1;
|
|
Vector y = *v2;
|
|
Vector *result = new Vector(cross_product(x, y)); // Uses default copy or move 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">5.4.3 Linking to structure variables</a></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">5.4.4 Linking to char *</a></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) {
|
|
free(foo);
|
|
foo = (char *) malloc(strlen(value)+1);
|
|
strcpy(foo, value);
|
|
}
|
|
|
|
/* C++ mode. When -c++ option is used */
|
|
void foo_set(char *value) {
|
|
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">5.4.5 Arrays</a></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 to 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">5.4.6 Creating read-only variables</a>
|
|
</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="#Customization_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> SWIG will also create read-only variables for non-assignable types,
|
|
more details in the <a href="#SWIGPlus_member_data">Member data</a>
|
|
section in the C++ chapter.</p>
|
|
<h3><a name="SWIG_rename_ignore">5.4.7 Renaming and ignoring
|
|
declarations</a></h3>
|
|
<h4><a name="SWIG_nn29">5.4.7.1 Simple renaming of specific identifiers</a>
|
|
</h4>
|
|
<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(const 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> A new <tt>%rename</tt> for the same name will replace the current <tt>
|
|
%rename</tt> for all uses after it in the file, and setting the new name
|
|
to "" will remove the rename. So, for instance, if you wanted to rename
|
|
some things in one file and not in another, you could do:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(print1) print;
|
|
%include "header1.h" //Anything "print" in here will become "print1"
|
|
%rename(print2) print;
|
|
%include "header2.h" //Anything "print" in here will become "print2"
|
|
%rename("") print;
|
|
%include "header3.h" //Anything "print" in here will remain "print"
|
|
</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> When wrapping C code, simple use of identifiers/symbols with <tt>
|
|
%rename</tt> usually suffices. When wrapping C++ code, simple use of
|
|
simple identifiers/symbols with <tt>%rename</tt> might be too limiting
|
|
when using C++ features such as function overloading, default
|
|
arguments, namespaces, template specialization etc. If you are using
|
|
the <tt>%rename</tt> directive and C++, make sure you read the <a href="#SWIGPlus">
|
|
SWIG and C++</a> chapter and in particular the section on <a href="#SWIGPlus_ambiguity_resolution_renaming">
|
|
Renaming and ambiguity resolution</a> for method overloading and default
|
|
arguments.</p>
|
|
<h4><a name="SWIG_ignore">5.4.7.2 Ignoring identifiers</a></h4>
|
|
<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 MYMACRO; // Ignore a macro
|
|
...
|
|
#define MYMACRO 123
|
|
void print(const char *);
|
|
...
|
|
</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>
|
|
<h4><a name="SWIG_advanced_renaming">5.4.7.3 Advanced renaming support</a>
|
|
</h4>
|
|
<p> While writing <tt>%rename</tt> for specific declarations is simple
|
|
enough, sometimes the same renaming rule needs to be applied to many,
|
|
maybe all, identifiers in the SWIG input. For example, it may be
|
|
necessary to apply some transformation to all the names in the target
|
|
language to better follow its naming conventions, like adding a
|
|
specific prefix to all wrapped functions. Doing it individually for
|
|
each function is impractical so SWIG supports applying a renaming rule
|
|
to all declarations if the name of the identifier to be renamed is not
|
|
specified:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("myprefix_%s") ""; // print -> myprefix_print
|
|
</pre>
|
|
</div>
|
|
<p> This also shows that the argument of <tt>%rename</tt> doesn't have
|
|
to be a literal string but can be a <tt>printf()</tt>-like format
|
|
string. In the simplest form, <tt>"%s"</tt> is replaced with the name
|
|
of the original declaration, as shown above. However this is not always
|
|
enough and SWIG provides extensions to the usual format string syntax
|
|
to allow applying a (SWIG-defined) function to the argument. For
|
|
example, to wrap all C functions <tt>do_something_long()</tt> as more
|
|
Java-like <tt>doSomethingLong()</tt> you can use the <tt>
|
|
"lowercamelcase"</tt> extended format specifier like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("%(lowercamelcase)s") ""; // foo_bar -> fooBar; FooBar -> fooBar
|
|
</pre>
|
|
</div>
|
|
<p> Some functions can be parametrized, for example the <tt>"strip"</tt>
|
|
one strips the provided prefix from its argument. The prefix is
|
|
specified as part of the format string, following a colon after the
|
|
function name:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("%(strip:[wx])s") ""; // wxHello -> Hello; FooBar -> FooBar
|
|
</pre>
|
|
</div>
|
|
<p> Below is the table summarizing all currently defined functions with
|
|
an example of applying each one. Note that some of them have two names,
|
|
a shorter one and a more descriptive one, but the two functions are
|
|
otherwise equivalent:</p>
|
|
<table border="1" cellpadding="5" summary="Format string functions">
|
|
<tr><th>Function</th><th>Returns</th><th colspan="2">Example (in/out)</th>
|
|
</tr>
|
|
<tr><td><tt>uppercase</tt> or <tt>upper</tt></td><td>Upper case version
|
|
of the string.</td><td><tt>Print</tt></td><td><tt>PRINT</tt></td></tr>
|
|
<tr><td><tt>lowercase</tt> or <tt>lower</tt></td><td>Lower case version
|
|
of the string.</td><td><tt>Print</tt></td><td><tt>print</tt></td></tr>
|
|
<tr><td><tt>title</tt></td><td>String with first letter capitalized and
|
|
the rest in lower case.</td><td><tt>print</tt></td><td><tt>Print</tt></td>
|
|
</tr>
|
|
<tr><td><tt>firstuppercase</tt></td><td>String with the first letter
|
|
capitalized and the rest unchanged.</td><td><tt>printIt</tt></td><td><tt>
|
|
PrintIt</tt></td></tr>
|
|
<tr><td><tt>firstlowercase</tt></td><td>String with the first letter in
|
|
lower case and the rest unchanged.</td><td><tt>PrintIt</tt></td><td><tt>
|
|
printIt</tt></td></tr>
|
|
<tr><td><tt>camelcase</tt> or <tt>ctitle</tt></td><td>String with
|
|
capitalized first letter and any letter following an underscore (which
|
|
are removed in the process) and rest in lower case.</td><td><tt>
|
|
print_it</tt></td><td><tt>PrintIt</tt></td></tr>
|
|
<tr><td><tt>lowercamelcase</tt> or <tt>lctitle</tt></td><td>String with
|
|
every letter following an underscore (which is removed in the process)
|
|
capitalized and rest, including the first letter, in lower case.</td><td>
|
|
<tt>print_it</tt></td><td><tt>printIt</tt></td></tr>
|
|
<tr><td><tt>undercase</tt> or <tt>utitle</tt></td><td>Lower case string
|
|
with underscores inserted before every upper case letter in the
|
|
original string and any number not at the end of string. Logically,
|
|
this is the reverse of <tt>camelcase</tt>.</td><td><tt>PrintIt</tt></td><td>
|
|
<tt>print_it</tt></td></tr>
|
|
<tr><td><tt>schemify</tt></td><td>String with all underscores replaced
|
|
with dashes, resulting in more Lispers/Schemers-pleasing name.</td><td><tt>
|
|
print_it</tt></td><td><tt>print-it</tt></td></tr>
|
|
<tr><td><tt>strip:[prefix]</tt></td><td>String without the given prefix
|
|
or the original string if it doesn't start with this prefix. Note that
|
|
square brackets should be used literally, e.g. <tt>
|
|
%rename("strip:[wx]")</tt></td><td><tt>wxPrint</tt></td><td><tt>Print</tt>
|
|
</td></tr>
|
|
<tr><td><tt>rstrip:[suffix]</tt></td><td>String without the given suffix
|
|
or the original string if it doesn't end with this suffix. Note that
|
|
square brackets should be used literally, e.g. <tt>
|
|
%rename("rstrip:[Cls]")</tt></td><td><tt>PrintCls</tt></td><td><tt>Print</tt>
|
|
</td></tr>
|
|
<tr><td><span style="white-space: nowrap;"><tt>regex:/pattern/subst/</tt>
|
|
</span></td><td>String after (Perl-like) regex substitution operation.
|
|
This function allows applying arbitrary regular expressions to the
|
|
identifier names. The<i> pattern</i> part is a regular expression in
|
|
Perl syntax (as supported by the <a href="https://www.pcre.org/">Perl
|
|
Compatible Regular Expressions</a>) (PCRE2 library) and the<i> subst</i>
|
|
string can contain back-references of the form <tt>\N</tt> where <tt>N</tt>
|
|
is a digit from 0 to 9, or one of the following escape sequences: <tt>
|
|
\l</tt>, <tt>\L</tt>, <tt>\u</tt>, <tt>\U</tt> or <tt>\E</tt>. The
|
|
back-references are replaced with the contents of the corresponding
|
|
capture group while the escape sequences perform the case conversion in
|
|
the substitution string: <tt>\l</tt> and <tt>\L</tt> convert to the
|
|
lower case, while <tt>\u</tt> and <tt>\U</tt> convert to the upper
|
|
case. The difference between the elements of each pair is that <tt>\l</tt>
|
|
and <tt>\u</tt> change the case of the next character only, while <tt>
|
|
\L</tt> and <tt>\U</tt> do it for all the remaining characters or until <tt>
|
|
\E</tt> is encountered. Finally please notice that backslashes need to
|
|
be escaped in C strings, so in practice <tt>"\\"</tt> must be used in
|
|
all these escape sequences. For example, to remove any alphabetic
|
|
prefix before an underscore and capitalize the remaining part you could
|
|
use the following directive: <tt>%rename("regex:/(\\w+)_(.*)/\\u\\2/")</tt>
|
|
</td><td><tt>prefix_print</tt></td><td><tt>Print</tt></td></tr>
|
|
</table>
|
|
<p> The most general function of all of the above ones is the <tt>regex</tt>
|
|
one. Here are some more examples of its use:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// Strip the wx prefix from all identifiers except those starting with wxEVT
|
|
%rename("%(regex:/wx(?!EVT)(.*)/\\1/)s") ""; // wxSomeWidget -> SomeWidget
|
|
// wxEVT_PAINT -> wxEVT_PAINT
|
|
|
|
// Apply a rule for renaming the enum elements to avoid the common prefixes
|
|
// which are redundant in C#/Java
|
|
%rename("%(regex:/^([A-Z][a-z]+)+_(.*)/\\2/)s", %$isenumitem) ""; // Colour_Red -> Red
|
|
|
|
// Remove all "Set/Get" prefixes.
|
|
%rename("%(regex:/^(Set|Get)(.*)/\\2/)s") ""; // SetValue -> Value
|
|
// GetValue -> Value
|
|
</pre>
|
|
</div>
|
|
<p> As before, everything that was said above about <tt>%rename</tt>
|
|
also applies to <tt>%ignore</tt>. In fact, the latter is just a special
|
|
case of the former and ignoring an identifier is the same as renaming
|
|
it to the special <tt>"$ignore"</tt> value. So the following snippets</p>
|
|
<div class="code">
|
|
<pre>
|
|
%ignore print;
|
|
</pre>
|
|
</div>
|
|
<p> and</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("$ignore") print;
|
|
</pre>
|
|
</div>
|
|
<p> are exactly equivalent and <tt>%rename</tt> can be used to
|
|
selectively ignore multiple declarations using the previously described
|
|
matching possibilities.</p>
|
|
<h4><a name="SWIG_limiting_renaming">5.4.7.4 Limiting global renaming
|
|
rules</a></h4>
|
|
<p> As explained in the previous sections, it is possible to either
|
|
rename individual declarations or apply a rename rule to all of them at
|
|
once. In practice, the latter is however rarely appropriate as there
|
|
are always some exceptions to the general rules. To deal with them, the
|
|
scope of an unnamed <tt>%rename</tt> can be limited using subsequent <tt>
|
|
match</tt> parameters. They can be applied to any of the attributes
|
|
associated by SWIG with the declarations appearing in its input. For
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("foo", match$name="bar") "";
|
|
</pre>
|
|
</div>
|
|
<p> can be used to achieve the same effect as the simpler</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("foo") bar;
|
|
</pre>
|
|
</div>
|
|
<p> and so is not very interesting on its own. However <tt>match</tt>
|
|
can also be applied to the declaration type, for example <tt>
|
|
match="class"</tt> restricts the match to class declarations only (in
|
|
C++) and <tt>match="enumitem"</tt> restricts it to the enum elements.
|
|
SWIG also provides convenience macros for such match expressions, for
|
|
example</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("%(title)s", %$isenumitem) "";
|
|
// same as:
|
|
%rename("%(title)s", match="enumitem") "";
|
|
</pre>
|
|
</div>
|
|
<p> will capitalize the names of all the enum elements but not change
|
|
the case of the other declarations. Similarly, <tt>%$isclass</tt>, <tt>
|
|
%$isfunction</tt>, <tt>%$isconstructor</tt>, <tt>%$isunion</tt>, <tt>
|
|
%$istemplate</tt>, and <tt>%$isvariable</tt> can be used. Many other
|
|
checks are possible and this documentation is not exhaustive, see the
|
|
"%rename predicates" section in <tt>swig.swg</tt> for the full list of
|
|
supported match expressions.</p>
|
|
<p> A logical not is also possible by using <tt>notmatch</tt>. For
|
|
example, <tt>notmatch="enumitem"</tt> will restrict the match to all
|
|
items that are not enum elements. There is also a <tt>%$not</tt> macro
|
|
which simply expands to "not". Be careful using this as some of the
|
|
other macros in <tt>swig.swg</tt> are complex expressions and so it
|
|
will only "notmatch" the first part of the expression.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("%(title)s", %$not %$isenumitem) "";
|
|
// same as:
|
|
%rename("%(title)s", notmatch="enumitem") "";
|
|
</pre>
|
|
</div>
|
|
<p> For a comprehensive understanding of how the matching works, the
|
|
internal <a href="#Extending_nn8">parse tree</a> needs to be examined
|
|
using the command line option: <tt>-debug-module 1 -debug-quiet</tt>. A
|
|
snippet of the resulting output might be:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
+++ destructor ----------------------------------------
|
|
| access - "public"
|
|
| decl - "f()."
|
|
| ismember - "1"
|
|
| name - "~Shape"
|
|
| storage - "virtual"
|
|
| sym:name - "~Shape"
|
|
</pre>
|
|
</div>
|
|
<p> Here the node type is a "destructor" and in order to match all
|
|
destructor nodes, use <tt>match="destructor"</tt>. To match one of the
|
|
listed attributes in the node, such as when the storage is virtual, use
|
|
<tt>match$storage="virtual"</tt>. This will match all nodes that have a
|
|
storage attribute set to "virtual". To match only virtual destructors,
|
|
combine them and use <tt>match="destructor", match$storage="virtual"</tt>
|
|
.</p>
|
|
<p> While the vast majority of these internal parse tree nodes are
|
|
unlikely to change from one version of SWIG to the next,<b> use these
|
|
matching rules at your own risk</b> as there are no guarantees that
|
|
they will not change.</p>
|
|
<p> In addition to literally matching some string with <tt>match</tt>
|
|
you can also use <tt>regexmatch</tt> or <tt>notregexmatch</tt> to match
|
|
a string against a regular expression. For example, to ignore all
|
|
functions having "Old" as a suffix you could use</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("$ignore", regexmatch$name="Old$") "";
|
|
</pre>
|
|
</div>
|
|
<p> For simple cases like this, specifying the regular expression for
|
|
the declaration name directly can be preferable and can also be done
|
|
using <tt>regextarget</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("$ignore", regextarget=1) "Old$";
|
|
</pre>
|
|
</div>
|
|
<p> Notice that the check is done only against the name of the
|
|
declaration itself, if you need to match the full name of a C++
|
|
declaration you must use <tt>fullname</tt> attribute:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("$ignore", regextarget=1, fullname=1) "NameSpace::ClassName::.*Old$";
|
|
</pre>
|
|
</div>
|
|
<p> As for <tt>notregexmatch</tt>, it restricts the match only to the
|
|
strings not matching the specified regular expression. So to rename all
|
|
declarations to lower case except those consisting of capital letters
|
|
only:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("$(lower)s", notregexmatch$name="^[A-Z]+$") "";
|
|
</pre>
|
|
</div>
|
|
<p> Finally, 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="#SWIGPlus_ambiguity_resolution_renaming">Renaming and
|
|
ambiguity resolution</a> section in the C++ chapter.</p>
|
|
<h4><a name="SWIG_chosen_unignore">5.4.7.5 Ignoring everything then
|
|
wrapping a few selected symbols</a></h4>
|
|
<p> Using the techniques described above it is possible to ignore
|
|
everything in a header and then selectively wrap a few chosen methods
|
|
or classes. For example, consider a header, <tt>myheader.h</tt> which
|
|
has many classes in it and just the one class called <tt>Star</tt> is
|
|
wanted within this header, the following approach could be taken:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%ignore ""; // Ignore everything
|
|
|
|
// Unignore chosen class 'Star'
|
|
%rename("%s") Star;
|
|
|
|
// As the ignore everything will include the constructor, destructor, methods etc
|
|
// in the class, these have to be explicitly unignored too:
|
|
%rename("%s") Star::Star;
|
|
%rename("%s") Star::~Star;
|
|
%rename("%s") Star::shine; // named method
|
|
|
|
%include "myheader.h"
|
|
|
|
%rename("%s") ""; // Undo the %ignore
|
|
</pre>
|
|
</div>
|
|
<p> If <tt>Star</tt> was in the <tt>Galaxy</tt> namespace, you would
|
|
need to unignore the namespace, too, and add the namespace to all the
|
|
renames:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("%s") Galaxy;
|
|
%rename("%s") Galaxy::Star;
|
|
%rename("%s") Galaxy::Star::Star;
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> Another approach which might be more suitable as it does not require
|
|
naming all the methods in the chosen class is to begin by ignoring just
|
|
the classes. This does not add an explicit ignore to any members of the
|
|
class, so when the chosen class is unignored, all of its methods will
|
|
be wrapped.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename($ignore, %$isclass) ""; // Only ignore all classes
|
|
%rename("%s") Star; // Unignore 'Star'
|
|
%include "myheader.h"
|
|
%rename("%s", %$isclass) ""; // Stop ignoring all classes
|
|
</pre>
|
|
</div>
|
|
<h3><a name="SWIG_default_args">5.4.8 Default/optional arguments</a></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 ISO 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">5.4.9 Pointers to functions and callbacks</a></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 when 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> are 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("%(uppercase)s");
|
|
int add(int, int);
|
|
int sub(int, int);
|
|
int mul(int, int);
|
|
%nocallback;
|
|
</pre>
|
|
</div>
|
|
<p> A format string of <tt>"%(lowercase)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. See the <a href="#Typemaps">Typemaps chapter</a>
|
|
for more about typemaps and individual target language chapters for
|
|
more on callbacks. The 'director' feature can be used to make callbacks
|
|
from C/C++ into the target language, see <a href="#SWIGPlus_target_language_callbacks">
|
|
Callbacks to the target language</a>.</p>
|
|
<h2><a name="SWIG_nn31">5.5 Structures and unions</a></h2>
|
|
<p> This section describes the behavior of SWIG when processing ISO C
|
|
structures and union declarations. Extensions to handle C++ are
|
|
described in the next section.</p>
|
|
<p> ISO C has a separate tag name space in which the names of
|
|
structures, unions and enumerated types are put, which is separate from
|
|
the name space for ordinary identifiers (function names, object names,
|
|
typedef names, enumeration constants). For example, this is valid ISO C
|
|
because <tt>Foo</tt> the struct tag and <tt>Foo</tt> the function name
|
|
are in different name spaces:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct Foo {
|
|
int bar;
|
|
};
|
|
|
|
int Foo(void) { return 42; }
|
|
</pre>
|
|
</div>
|
|
<p> SWIG doesn't currently implement this separate tag name space and
|
|
for the above example you'll get:</p>
|
|
<div class="code">
|
|
<pre>
|
|
foo.i:5: Warning 302: Redefinition of identifier 'Foo' as Foo(void) ignored,
|
|
foo.i:1: Warning 302: previous definition of 'Foo'.
|
|
|
|
</pre>
|
|
</div>
|
|
<p> In practice this rarely actually causes problems, particular because
|
|
SWIG has special handling for <tt>typedef</tt> so cases such as this
|
|
work:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef struct Foo {
|
|
int bar;
|
|
} Foo;
|
|
</pre>
|
|
</div>
|
|
<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
|
|
makes 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">5.5.1 Typedef and structures</a></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">5.5.2 Character strings and structures</a></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 previous 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) {
|
|
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">5.5.3 Array members</a></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">5.5.4 Structure data members</a>
|
|
</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 are
|
|
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> If you have accessor methods that you want to use as attributes in
|
|
the target language, you can make them appear as data members using <a href="#Library_attributes">
|
|
attributes.i</a>.</p>
|
|
<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">5.5.5 C constructors and destructors</a></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 time
|
|
produces 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. 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 is also the <tt>%nodefault</tt> directive, which
|
|
disables both the default or implicit destructor generation. This could
|
|
lead to memory leaks across the target languages, and it is highly
|
|
recommended you don't use them.</p>
|
|
<h3><a name="SWIG_adding_member_functions">5.5.6 Adding member functions
|
|
to C structures</a></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 Vector {
|
|
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 Vector {
|
|
double x, y, z;
|
|
%extend {
|
|
Vector(double x, double y, double z) { ... }
|
|
~Vector() { ... }
|
|
...
|
|
}
|
|
} Vector;
|
|
</pre>
|
|
</div>
|
|
<p> Note that <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 Vector {
|
|
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> You'll also need to use these names if you want to directly call
|
|
methods added using <tt>%extend</tt> from other C/C++ code.</p>
|
|
<p> The name used for %extend should be the name of the struct and not
|
|
the name of any typedef to the struct. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef struct Integer {
|
|
int value;
|
|
} Int;
|
|
%extend Integer { ... } /* Correct name */
|
|
%extend Int { ... } /* Incorrect name */
|
|
|
|
struct Float {
|
|
float value;
|
|
};
|
|
typedef struct Float FloatValue;
|
|
%extend Float { ... } /* Correct name */
|
|
%extend FloatValue { ... } /* Incorrect name */
|
|
</pre>
|
|
</div>
|
|
<p> There is one exception to this rule and that is when the struct is
|
|
anonymously named such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef struct {
|
|
double value;
|
|
} Double;
|
|
%extend Double { ... } /* Okay */
|
|
</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) 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 data members that
|
|
you want to process. For example, consider this interface:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef struct Person {
|
|
char name[50];
|
|
...
|
|
} Person;
|
|
</pre>
|
|
</div>
|
|
<p> Say you wanted to ensure <tt>name</tt> was always upper case, you
|
|
can rewrite the interface as follows to ensure this occurs whenever a
|
|
name is read or written to:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef struct Person {
|
|
%extend {
|
|
char name[50];
|
|
}
|
|
...
|
|
} Person;
|
|
|
|
%{
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
void make_upper(char *name) {
|
|
char *c;
|
|
for (c = name; *c; ++c)
|
|
*c = (char)toupper((int)*c);
|
|
}
|
|
|
|
/* Specific implementation of set/get functions forcing capitalization */
|
|
|
|
char *Person_name_get(Person *p) {
|
|
make_upper(p->name);
|
|
return p->name;
|
|
}
|
|
|
|
void Person_name_set(Person *p, char *val) {
|
|
strncpy(p->name, val, 50);
|
|
make_upper(p->name);
|
|
}
|
|
%}
|
|
</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 or
|
|
obtained elsewhere).</p>
|
|
<h3><a name="SWIG_nested_structs">5.5.7 Nested structures</a></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 of 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>
|
|
<p> Finally, note that nesting is handled differently in C++ mode, see <a
|
|
href="#SWIGPlus_nested_classes">Nested classes</a>.</p>
|
|
<h3><a name="SWIG_nn39">5.5.8 Other things to note about structure
|
|
wrapping</a></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">5.6 Code Insertion</a></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">5.6.1 The output of SWIG</a></h3>
|
|
<p> When SWIG creates its output C/C++ file, it is broken up into five
|
|
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 for users to put code at the beginning of the C/C++
|
|
wrapper file. This is most often used to define preprocessor macros
|
|
that are used in later sections.</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">5.6.2 Code insertion blocks</a></h3>
|
|
<p> The <tt>%insert</tt> directive enables inserting blocks of code into
|
|
a given section of the generated code. It can be used in one of two
|
|
ways:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%insert("section") "filename"
|
|
%insert("section") %{ ... %}
|
|
</pre>
|
|
</div>
|
|
<p> The first will dump the contents of the file in the given <tt>
|
|
filename</tt> into the named <tt>section</tt>. The second inserts the
|
|
code between the braces into the named <tt>section</tt>. For example,
|
|
the following adds code into the runtime section:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%insert("runtime") %{
|
|
... code in runtime section ...
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> There are the 5 sections, however, some target languages add in
|
|
additional sections and some of these result in code being generated
|
|
into a target language file instead of the C/C++ wrapper file. These
|
|
are documented when available in the target language chapters. Macros
|
|
named after the code sections are available as additional directives
|
|
and these macro directives are normally used instead of <tt>%insert</tt>
|
|
. For example, <tt>%runtime</tt> is used instead of <tt>
|
|
%insert("runtime")</tt>. The valid sections and order of the sections in
|
|
the generated C/C++ 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">5.6.3 Inlined code blocks</a></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> This is the same as writing:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
/* Create a new vector */
|
|
Vector *new_Vector() {
|
|
return (Vector *) malloc(sizeof(Vector));
|
|
}
|
|
%}
|
|
|
|
/* Create a new vector */
|
|
Vector *new_Vector() {
|
|
return (Vector *) malloc(sizeof(Vector));
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> In other words, 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>
|
|
<p><b> Note:</b> The usual SWIG C preprocessor rules apply to code in <tt>
|
|
%apply</tt> blocks when SWIG parses this code. For example, as mentioned
|
|
earlier, <a href="#SWIG_nn6">SWIG's C Preprocessor</a> does not follow <tt>
|
|
#include</tt> directives by default.</p>
|
|
<h3><a name="SWIG_nn44">5.6.4 Initialization blocks</a></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>
|
|
<p> Please note that some language backends (e.g. C# or Java) don't have
|
|
any initialization function, hence you should define a global object
|
|
performing the necessary initialization for them instead:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%init %{
|
|
static struct MyInit { MyInit() { init_variables(); } } myInit;
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<h2><a name="SWIG_nn45">5.7 An Interface Building Strategy</a></h2>
|
|
<p> This section describes the general approach for building interfaces
|
|
with SWIG. The specifics related to a particular scripting language are
|
|
found in later chapters.</p>
|
|
<h3><a name="SWIG_nn46">5.7.1 Preparing a C program for SWIG</a></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 of a C program--thus, a
|
|
little forethought can dramatically simplify the resulting scripting
|
|
language interface. C header files are a 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 ISO 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 uncompilable 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="https://www.swig.org/mail.html">
|
|
swig-devel mailing list</a> or to the <a href="https://www.swig.org/bugs.html">
|
|
SWIG bug tracker</a>.</p>
|
|
<h3><a name="SWIG_nn47">5.7.2 The SWIG interface file</a></h3>
|
|
<p> The preferred method of using SWIG is to generate a 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">5.7.3 Why use separate interface files?</a></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">5.7.4 Getting the right header files</a></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 the rest of the declarations here
|
|
...
|
|
</pre>
|
|
</div>
|
|
<h3><a name="SWIG_nn50">5.7.5 What to do with main()</a></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> In 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">6 SWIG and C++</a></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_nn15">Protection</a></li>
|
|
<li><a href="#SWIGPlus_nn16">Enums and constants</a></li>
|
|
<li><a href="#SWIGPlus_nn17">Friends</a>
|
|
<ul>
|
|
<li><a href="#SWIGPlus_friend_classes">Friend classes</a></li>
|
|
<li><a href="#SWIGPlus_friend_function_definitions">Friend function
|
|
definitions</a></li>
|
|
<li><a href="#SWIGPlus_friend_function_declarations">Friend function
|
|
declarations</a></li>
|
|
<li><a href="#SWIGPlus_friends_unqualified">Unqualified friend functions</a>
|
|
</li>
|
|
</ul>
|
|
</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_default_args">Default arguments</a></li>
|
|
<li><a href="#SWIGPlus_overloaded_methods">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="#SWIGPlus_ambiguity_resolution_renaming">Renaming and
|
|
ambiguity resolution</a></li>
|
|
<li><a href="#SWIGPlus_nn27">Comments on overloading</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#SWIGPlus_nn28">Overloaded operators</a></li>
|
|
<li><a href="#SWIGPlus_class_extension">Class extension</a>
|
|
<ul>
|
|
<li><a href="#SWIGPlus_replacing_methods">Replacing class methods</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#SWIGPlus_nn30">Templates</a>
|
|
<ul>
|
|
<li><a href="#SWIGPlus_template_directive">The %template directive</a></li>
|
|
<li><a href="#SWIGPlus_template_functions">Function templates</a></li>
|
|
<li><a href="#SWIGPlus_template_classes">Default template arguments</a></li>
|
|
<li><a href="#SWIGPlus_template_class_inheritance">Template base classes</a>
|
|
</li>
|
|
<li><a href="#SWIGPlus_template_empty">Empty template instantiation</a></li>
|
|
<li><a href="#SWIGPlus_template_specialization">Template specialization</a>
|
|
</li>
|
|
<li><a href="#SWIGPlus_template_member">Member templates</a></li>
|
|
<li><a href="#SWIGPlus_template_scoping">Scoping and templates</a></li>
|
|
<li><a href="#SWIGPlus_template_more">More on templates</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#SWIGPlus_namespaces">Namespaces</a>
|
|
<ul>
|
|
<li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
|
|
<ul>
|
|
<li><a href="#SWIGPlus_nspace_feature_flag">%nspace for mirroring
|
|
namespace hierarchies</a></li>
|
|
<li><a href="#SWIGPlus_nspacemove">%nspacemove for modifying namespace
|
|
hierarchies</a></li>
|
|
<li><a href="#SWIGPlus_nspace_more">More about the nspace feature</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</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_smart_pointers">Smart pointers and operator->()</a>
|
|
</li>
|
|
<li><a href="#SWIGPlus_ref_unref">C++ reference counted objects -
|
|
ref/unref feature</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_const">A brief rant about const-correctness</a></li>
|
|
<li><a href="#SWIGPlus_target_language_callbacks">Callbacks to the
|
|
target language</a>
|
|
<ul>
|
|
<li><a href="#SWIGPlus_director_classes_introduction">Introduction to
|
|
director classes</a></li>
|
|
<li><a href="#SWIGPlus_directors_for_function_pointers">Using directors
|
|
and target language callbacks</a></li>
|
|
</ul>
|
|
</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++. It is mostly
|
|
concerned about C++ as defined by the C++ 98 and 03 standards. For
|
|
additions to the original C++ standard, please read the <a href="#CPlusPlus11">
|
|
SWIG and C++11</a>, <a href="#CPlusPlus14">SWIG and C++14</a>, <a href="#CPlusPlus17">
|
|
SWIG and C++17</a> and <a href="#CPlusPlus20">SWIG and C++20</a>
|
|
chapters. As a prerequisite, you should first read the chapter <a href="#SWIG">
|
|
SWIG Basics</a> to see how SWIG wraps ISO C. Support for C++ builds upon
|
|
ISO C wrapping and that material will be useful in understanding this
|
|
chapter.</p>
|
|
<h2><a name="SWIGPlus_nn2">6.1 Comments on C++ Wrapping</a></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">6.2 Approach</a></h2>
|
|
<p> To wrap C++, SWIG uses a layered approach to code generation. At the
|
|
lowest level, SWIG generates a collection of procedural ISO 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> This approach results in generated code that uses just the most
|
|
basic of C and C++ features, no matter how complex the input C++ is.
|
|
SWIG will not force a newer standard of C++ to be required as the
|
|
generated code complies with ISO standard C++98. However, there are a
|
|
few features in later C++ standards that can be advantageous to use.
|
|
For example, C++11 move semantics are available to provide performance
|
|
improvements. So in some instances, SWIG will use features from newer
|
|
C++ standards provided they are available. This is made possible via
|
|
the <tt>__cplusplus</tt> macro, which is set by the C++ compiler to an
|
|
appropriate standards defined value. This means that if your compiler
|
|
is configured to support say the C++11 standard, then there may be some
|
|
C++11 benefits available in the generated code, such as C++11 move
|
|
semantics.</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">6.3 Supported C++ features</a></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>
|
|
</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">6.4 Command line options and compilation</a></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++ -fPIC -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 some target languages
|
|
and will generate just this interface as in earlier versions.
|
|
<h2><a name="SWIGPlus_nn38">6.5 Proxy classes</a></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">6.5.1 Construction of proxy classes</a></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">6.5.2 Resource management in proxies</a></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">6.5.3 Language specific details</a></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">6.6 Simple C++ wrapping</a></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">6.6.1 Constructors and destructors</a></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">6.6.2 Default constructors, copy constructors
|
|
and implicit destructors</a></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 <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>. 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 described above,
|
|
which disables both the default constructor and the implicit
|
|
destructors, could lead to memory leaks, and so it is strongly
|
|
recommended to not use it.</p>
|
|
<h3><a name="SWIGPlus_nn9">6.6.3 When constructor wrappers aren't
|
|
created</a></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">6.6.4 Copy constructors</a></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>
|
|
%rename(CopyFoo) Foo::Foo(const Foo &);
|
|
|
|
class Foo {
|
|
public:
|
|
Foo();
|
|
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">6.6.5 Member functions</a></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">6.6.6 Static members</a></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">6.6.7 Member data</a></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> By default, SWIG uses the const reference typemaps for members that
|
|
are primitive types. There are some subtle issues when wrapping data
|
|
members that are not primitive types, such as 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
|
|
in the <a href="#SWIG_structure_data_members">Structure data members</a>
|
|
and <a href="#SWIG_readonly_variables">Creating read-only variables</a>
|
|
sections.</p>
|
|
<p> Additionally, any C++ type that is not assignable is also wrapped as
|
|
a read-only member. Consider the class below which is non-assignable
|
|
due to the private assignment operator:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class NonAssignable {
|
|
private:
|
|
NonAssignable & operator=(const NonAssignable &);
|
|
public:
|
|
NonAssignable();
|
|
};
|
|
|
|
struct ImmutableVars {
|
|
NonAssignable non_assignable;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>non_assignable</tt> member variable is immutable by default
|
|
as SWIG detects that <tt>NonAssignable</tt> is not assignable. SWIG
|
|
must of course see the full type information in order to get this
|
|
correct, otherwise you may have to use <tt>%immutable</tt> to make the
|
|
variable read-only.</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
|
|
naturalvar feature and can be used to effectively change 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> The <tt>%naturalvar</tt> directive is a macro for, and hence
|
|
equivalent to, <tt>%feature("naturalvar")</tt>. It can be 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 non-primitive types 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 but with some extra flexibility. The first of the example
|
|
usages above shows <tt>%naturalvar</tt> attaching to the <tt>myList</tt>
|
|
's variable type, that is the <tt>List</tt> class. The second usage
|
|
shows <tt>%naturalvar</tt> attaching to the variable name. Hence the
|
|
naturalvar feature can be used on either the variable's name or type.
|
|
Note that using the naturalvar feature on a variable's name overrides
|
|
any naturalvar feature attached to the variable's type.</p>
|
|
<p> 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> The naturalvar behavior can also be turned on as a global setting
|
|
via the <tt>-naturalvar</tt> commandline option or the module mode
|
|
option, <tt>%module(naturalvar=1)</tt>. However, any use of <tt>
|
|
%feature("naturalvar")</tt> will override the global setting.</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> 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_nn15">6.7 Protection</a></h2>
|
|
<p> SWIG wraps class members that are public following the C++
|
|
conventions, i.e., by explicit public declaration or by the use of <tt>
|
|
using</tt> declarations. 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">6.8 Enums and constants</a></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">6.9 Friends</a></h2>
|
|
<h3><a name="SWIGPlus_friend_classes">6.9.1 Friend classes</a></h3>
|
|
<p> Friend classes are a C++ feature that do not affect SWIG wrappers.
|
|
SWIG simply parses the friend class declarations, but they are
|
|
effectively ignored as they have no meaningful effect for wrappers. An
|
|
example of friend classes:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class X;
|
|
class Y;
|
|
class C {
|
|
// Friend classes have no effect on generated wrappers
|
|
friend class X;
|
|
friend Y;
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<h3><a name="SWIGPlus_friend_function_definitions">6.9.2 Friend function
|
|
definitions</a></h3>
|
|
<p> A friend function definition in a C++ class defines a non-member
|
|
function of the class and simultaneously makes it a friend of the
|
|
class. For example, if you have this code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class Buddy {
|
|
int val;
|
|
friend int blah(Buddy *b) { return b->val; }
|
|
public:
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> then the <tt>friend</tt> function definition results in wrapper code
|
|
equivalent to one generated for the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class Buddy {
|
|
int val;
|
|
friend int blah(Buddy *b);
|
|
public:
|
|
...
|
|
};
|
|
|
|
int blah(Buddy *b) { return b->val; }
|
|
</pre>
|
|
</div>
|
|
<p> Access from target languages is thus as if <tt>blah</tt> was wrapped
|
|
as a non-member function. The function is available and wrapped even if
|
|
the friend is defined with private or protected access.</p>
|
|
<p> A friend definition, as in C++, is understood to be in the same
|
|
scope that the class is defined in, hence the scoping required for SWIG
|
|
directives, such as <tt>%ignore</tt>, is as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%ignore bar::blah(Buddy *b);
|
|
// Not: %ignore bar::Buddy::blah(Buddy *b);
|
|
|
|
namespace bar {
|
|
class Buddy {
|
|
int val;
|
|
friend int blah(Buddy *b) { return b->val; }
|
|
public:
|
|
...
|
|
};
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> and a wrapper for <tt>blah</tt> will not be generated.</p>
|
|
<h3><a name="SWIGPlus_friend_function_declarations">6.9.3 Friend
|
|
function declarations</a></h3>
|
|
<p> A C++ class can specify friends via friend function declarations.
|
|
These functions are allowed access to the private and protected members
|
|
of a class. This is pure C++ functionality and these friend function
|
|
declarations are hence quietly ignored by SWIG and do not result in any
|
|
wrappers. Well, not always! The C++ rules for friends that SWIG needs
|
|
to follow are not that simple. Technically, only qualified function
|
|
declarations are silently ignored by SWIG. Below are some examples of
|
|
qualified friend declarations in <tt>A</tt> that are quietly ignored:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct B {
|
|
int f();
|
|
B();
|
|
~B();
|
|
...
|
|
};
|
|
|
|
int g();
|
|
|
|
class A {
|
|
public:
|
|
// The following friend function-declarations are silently ignored (including constructor and destructor friends)
|
|
friend B::B();
|
|
friend B::~B();
|
|
friend int B::f();
|
|
friend int ::g();
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> In the example above, if SWIG parses the struct <tt>B</tt> and
|
|
global function <tt>g()</tt>, then they are of course wrapped as
|
|
normal.</p>
|
|
<h3><a name="SWIGPlus_friends_unqualified">6.9.4 Unqualified friend
|
|
functions</a></h3>
|
|
<p> Further clarification is required regarding both friend function
|
|
definitions and declarations. In C++, friend function definitions can
|
|
only be unqualified, whereas, friend function declarations can be
|
|
either unqualified or qualified. Qualified friend function declarations
|
|
are silently ignored by SWIG as covered in the previous section. SWIG
|
|
does generate wrappers for any unqualified friend functions that it
|
|
parses. This section goes through some of the complexities of wrapping
|
|
unqualified friend functions.</p>
|
|
<p> Consider an unqualified friend function definition:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class Chum {
|
|
int val;
|
|
friend int blah() { Chum c; c.private_function(); return c.val; }
|
|
void private_function();
|
|
public:
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>Chum::blah()</tt> friend is very similar to the <tt>
|
|
Buddy::blah(Buddy *)</tt> friend presented earlier. However, the
|
|
generated code to call <tt>blah()</tt> may not compile unlike the code
|
|
to call <tt>blah(Buddy *)</tt>. The compiler error will be something
|
|
like:<div class="shell">
|
|
<pre>
|
|
error: 'blah' was not declared in this scope
|
|
</pre>
|
|
</div></p>
|
|
<p> The reason one works and the other doesn't is due to the rules
|
|
around unqualified friend definitions/declarations. Broadly, friends
|
|
are not visible for lookup except via argument dependent lookup that
|
|
considers the class that the friend is defined/declared in, unless
|
|
there is a<i> matching declaration</i> at namespace scope. This will
|
|
probably only make sense if you are conversant with this C++ concept,
|
|
which is covered quite well at <a href="https://en.cppreference.com/w/cpp/language/adl">
|
|
Argument-dependent lookup</a>. In our examples, <tt>blah(Buddy *)</tt>
|
|
is visible via argument dependent lookup, but <tt>blah()</tt> is not.
|
|
The solution is thus to provide a<i> matching declaration</i> in order
|
|
to make the function visible to the compiler. Simply add:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int blah();
|
|
</pre>
|
|
</div>
|
|
<p> SWIG does<b> not</b> have to parse it. In all likelihood, your code
|
|
already has the<i> matching declaration</i> as it is required in order
|
|
for the friend function definition to be usable from pure C++ code.</p>
|
|
<p> The same potential problem applies to unqualified friend function
|
|
declarations, such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class Mate {
|
|
int val;
|
|
friend int blah(); // Unqualified friend function declaration
|
|
void private_function();
|
|
public:
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Again, the actual function declaration needs to be visible to the
|
|
compiler. Or just the actual function definition as shown below. This
|
|
must be defined in the same scope as <tt>Mate</tt>. Of course the
|
|
function definition is necessary in order to avoid linking issues too.</p>
|
|
<div class="code">
|
|
<pre>
|
|
int blah() { Mate m; m.private_function(); return m.val; }
|
|
</pre>
|
|
</div>
|
|
<h2><a name="SWIGPlus_nn18">6.10 References and pointers</a></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">6.11 Pass and return by value</a></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;
|
|
Vector y;
|
|
Vector r;
|
|
x = *a;
|
|
y = *b;
|
|
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 default constructor and a copy assignment operator (and/or a
|
|
move assignment operator for C++11 and later). The <a href="#CPlusPlus11_move_only">
|
|
Movable and move-only types</a> section should be read regarding C++11
|
|
move semantics and return by value.</p>
|
|
<p> If <tt>Vector</tt> is defined as a class in the interface, but it
|
|
does not support a default constructor and an assignment operator, 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;
|
|
SwigValueWrapper<Vector> y;
|
|
SwigValueWrapper<Vector> r;
|
|
x = *a;
|
|
y = *b;
|
|
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 is not default constructible nor
|
|
assignable 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">6.12 Inheritance</a></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 constructors 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">6.13 A brief discussion of multiple
|
|
inheritance, pointers, and type checking</a></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_default_args">6.14 Default arguments</a></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 in the next section <a
|
|
href="#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>
|
|
. 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="#SWIGPlus_ambiguity_resolution_renaming">
|
|
Renaming and ambiguity resolution</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> For C# please see the <a href="#CSharp_named_arguments">C# named and
|
|
optional arguments</a> section for information on special handling of
|
|
default arguments available specifically for C#.</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 uncompilable 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> The <tt>compactdefaultargs</tt> feature is automatically turned on
|
|
when wrapping <a href="#SWIG_default_args">C code with default
|
|
arguments</a>. Some target languages will also automatically turn on
|
|
this feature if the keyword arguments feature (kwargs) is specified for
|
|
either C or C++ functions, and the target language supports kwargs, the
|
|
<tt>compactdefaultargs</tt> feature is also automatically turned on.
|
|
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_overloaded_methods">6.15 Overloaded functions and
|
|
methods</a></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">6.15.1 Dispatch function generation</a></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">6.15.2 Ambiguity in overloading</a></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 method foo(long) effectively ignored,
|
|
example.i:3: Warning 509: as it is shadowed by foo(int).
|
|
</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,
|
|
example.i:3: Warning 516: using foo(int) instead.
|
|
</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 a warning message like this:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:3: Warning 467: Overloaded foo(int) not supported (incomplete type checking rule -
|
|
no precedence level in typecheck typemap 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="https://www.swig.org/bugs.html">
|
|
SWIG bug tracking database</a> if this is due to one of the typemaps
|
|
supplied with SWIG.</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="SWIGPlus_ambiguity_resolution_renaming">6.15.3 Renaming and
|
|
ambiguity resolution</a></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="https://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 (and foo in any derived classes)
|
|
%ignore Spam::foo(double); // Ignore foo(double) in class Spam (and foo in any derived classes)
|
|
%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> Renaming a class member, using an unparameterized but qualified
|
|
name, such as <tt>Spam::foo</tt>, also applies to members in all
|
|
derived classes that have members with the same name. This can be used
|
|
to simply rename a method, across an entire class hierarchy for all
|
|
overloaded and non-overloaded methods. This also applies to methods
|
|
introduced via <tt>using</tt> declarations, see <a href="#SWIGPlus_nn35">
|
|
Using declarations and inheritance</a>. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(foo_new) Spam::foo;
|
|
|
|
class Spam {
|
|
public:
|
|
virtual void foo(int); // Renamed to foo_new
|
|
};
|
|
|
|
class Bar : public Spam {
|
|
public:
|
|
virtual void foo(int); // Renamed to foo_new
|
|
void foo(bool, short, int); // Renamed to foo_new
|
|
};
|
|
|
|
class Grok : public Bar {
|
|
public:
|
|
virtual void foo(int); // Renamed to foo_new
|
|
void foo(bool, int); // Renamed to foo_new
|
|
void foo(const char *); // Renamed to foo_new
|
|
void foo(Bar *); // Renamed to foo_new
|
|
};
|
|
|
|
class Spok : public Grok {
|
|
public:
|
|
void foo(); // Renamed to foo_new
|
|
};
|
|
|
|
class Knock : public Spok {
|
|
public:
|
|
using Grok::foo; // Introduced methods renamed to foo_new
|
|
};
|
|
</pre>
|
|
</div></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 qualifier rules. For
|
|
example, if you have a class and member with a member that is const
|
|
qualified 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 the rename as the qualifier matches correctly:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(name) Spam::bar() const;
|
|
</pre>
|
|
</div>
|
|
<p> Similarly for combinations of cv-qualifiers and ref-qualifiers, all
|
|
the qualifiers must be specified to match correctly:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(name) Jam::bar(); // will not match
|
|
%rename(name) Jam::bar() &; // will not match
|
|
%rename(name) Jam::bar() const; // will not match
|
|
%rename(name) Jam::bar() const &; // ok, will match
|
|
|
|
class Jam {
|
|
public:
|
|
...
|
|
void 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 qualifier. 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:</p>
|
|
<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></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:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(newbar) Spam::bar(int i, double d);
|
|
</pre>
|
|
</div>
|
|
<p> then only one of the three equivalent overloaded methods will be
|
|
renamed and wrapped as if SWIG parsed:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void Spam::newbar(int i, double d);
|
|
void Spam::bar(int i);
|
|
void Spam::bar();
|
|
</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).</p>
|
|
<p> 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">6.15.4 Comments on overloading</a></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">6.16 Overloaded operators</a></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 and
|
|
index operators. A warning such as the one below is shown:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:12: Warning 503: Can't wrap 'operator []' unless renamed to a valid identifier.
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>The index operator, <tt>operator[]</tt>, is particularly difficult to
|
|
overload due to differences in C++ implementations. Specifically, the
|
|
get and set operators in other languages typically are separated into
|
|
two methods such that additional logic can be packed into the
|
|
operations; C# uses <tt>this[type key] { get { ... } set { ... }}</tt>,
|
|
Python uses <tt>__getitem__</tt> and <tt>__setitem__</tt>, etc. In C++
|
|
if the return type of <tt>operator[]</tt> is a reference and the method
|
|
is const, it is often indicative of the<i> setter</i>, and the<i>
|
|
getter</i> is usually a const function return an object by value. In
|
|
the absence of any hard and fast rules and the fact that there may be
|
|
multiple index operators, it is up to the user to choose the getter and
|
|
setter to use by using %rename as shown earlier.</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">6.17 Class extension</a></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 following special variables are expanded if used within a
|
|
%extend block: $name, $symname, $overname, $decl, $fulldecl,
|
|
$parentclassname and $parentclasssymname. The <a href="#Customization_exception_special_variables">
|
|
Special variables</a> section provides more information each of these
|
|
special variables.</p>
|
|
<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>
|
|
<h3><a name="SWIGPlus_replacing_methods">6.17.1 Replacing class methods</a>
|
|
</h3>
|
|
<p> Suppose there is a method in a class that you need to replace and
|
|
keep the method name the same. This can be achieved combining the <tt>
|
|
%extend</tt> and <tt>%ignore</tt> directives covered earlier. Here is an
|
|
example to replace the <tt>MyClass::mymethod()</tt>:<div class="code">
|
|
<pre>
|
|
%extend MyClass {
|
|
void mymethod() {
|
|
std::cout << "swig mymethod" << std::endl;
|
|
}
|
|
}
|
|
|
|
%ignore MyClass::mymethod;
|
|
|
|
%inline %{
|
|
class MyClass {
|
|
public:
|
|
void mymethod() {
|
|
std::cout << "class mymethod" << std::endl;
|
|
}
|
|
};
|
|
%}
|
|
</pre>
|
|
</div></p>
|
|
<p> Or if your code organization makes more sense to put the <tt>%extend</tt>
|
|
after the class definition, you would need the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename("") MyClass::mymethod; // unignores the method
|
|
</pre>
|
|
</div>
|
|
<p> before the <tt>%extend</tt> or SWIG will continue to ignore <tt>
|
|
mymethod()</tt>, even in an <tt>%extend</tt>.</p>
|
|
<p> Note that you can call the class method from the method in <tt>
|
|
%extend</tt>, just use <tt>self->mymethod()</tt> and it will call the
|
|
class method, not the one in <tt>%extend</tt>.</p>
|
|
<h2><a name="SWIGPlus_nn30">6.18 Templates</a></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(std::array<int, 100> *x);
|
|
</pre>
|
|
</div>
|
|
<p> There are some restrictions on the use of non-type arguments. Simple
|
|
literals are supported, and so are most constant expressions. However,
|
|
there are some limitations on the use of '<' and '>' in constant
|
|
expressions (but note that '<=' and '>=' are fully supported). For
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void bar(std::array<int, 100> *x); // OK
|
|
void bar(std::array<int, 2*50> *x); // OK
|
|
void bar(std::array<int, (1<2 ? 100 : 50)> *x) // OK
|
|
void bar(std::array<int, 1<2 ? 100 : 50> *x) // Not supported
|
|
void bar(std::array<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>
|
|
<h3><a name="SWIGPlus_template_directive">6.18.1 The %template directive</a>
|
|
</h3>
|
|
<p> There are a couple of important points 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>.</p>
|
|
<p> To illustrate, consider the following class 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 class template is useless--SWIG simply ignores it
|
|
because it doesn't know how to generate any code unless a definition of
|
|
<tt>T</tt> is provided. The <tt>%template</tt> directive is required to
|
|
instantiate the template for use in a target language. The directive
|
|
requires an identifier name for use in the target language plus the
|
|
template for instantiation. The example below instantiates <tt>
|
|
List<int></tt> for use as a class named <tt>intList</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%template(intList) List<int>;
|
|
</pre>
|
|
</div>
|
|
<p> The instantiation expands the template code as a C++ compiler would
|
|
do and then makes it available under the given identifier name.
|
|
Essentially it is the same as wrapping the following concept code where
|
|
the class template definition has <tt>T</tt> expanded to <tt>int</tt>
|
|
(note that this is not entirely valid syntax):</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 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> The <tt>%template</tt> directive must always appear<em> after</em>
|
|
the definition of the template to be expanded, so the following will
|
|
work:</p>
|
|
<div class="code">
|
|
<pre>
|
|
template<class T> class List { ... };
|
|
%template(intList) List<int>;
|
|
</pre>
|
|
</div>
|
|
<p> but if %template is used before the template definition, such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%template(intList) List<int>;
|
|
template<class T> class List { ... };
|
|
</pre>
|
|
</div>
|
|
<p> SWIG will generate an error:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:3: Error: Template 'List' undefined.
|
|
</pre>
|
|
</div>
|
|
<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) List<int>;
|
|
typedef int Integer;
|
|
...
|
|
void foo(List<Integer> *x);
|
|
</pre>
|
|
</div>
|
|
<p> In this case, <tt>List<Integer></tt> is exactly the same type as <tt>
|
|
List<int></tt>. Any use of <tt>List<Integer></tt> is mapped back to the
|
|
instantiation of <tt>List<int></tt> created earlier. Therefore, it is
|
|
not correct to instantiate a new class for the type <tt>Integer</tt>.
|
|
An attempt to do so such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%template(intList) List<int>;
|
|
%template(IntegerList) List<Integer>; // Ignored
|
|
</pre>
|
|
</div>
|
|
<p> will result in the duplicate instantiation being ignored with a
|
|
warning:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:48: Warning 404: Duplicate template instantiation of 'List< Integer >' with name 'IntegerList' ignored,
|
|
example.i:47: Warning 404: previous instantiation of 'List< int >' with name 'intList'.
|
|
</pre>
|
|
</div>
|
|
<p> The template provided to <tt>%template</tt> for instantiation must
|
|
be the actual template and not a typedef to a template.</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef List<int> ListOfInt;
|
|
|
|
%template(intList) List<int>; // ok
|
|
%template(intList) ListOfInt; // illegal - Syntax error
|
|
</pre>
|
|
</div>
|
|
<h3><a name="SWIGPlus_template_functions">6.18.2 Function templates</a></h3>
|
|
<p> SWIG can also generate wrappers for function templates using a
|
|
similar technique to that shown above for class templates. 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> 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>
|
|
<h3><a name="SWIGPlus_template_classes">6.18.3 Default template
|
|
arguments</a></h3>
|
|
<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 <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. This also applies to default
|
|
parameters where a template parameter specified in the instantiation is
|
|
the same as the default parameter. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%template(vec) vector<double>; // OK
|
|
%template(vec100) vector<double, 100>; // Ignored
|
|
</pre>
|
|
</div>
|
|
<p> will warn:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:59: Warning 404: Duplicate template instantiation of 'vector< double,100 >' with name 'vec100' ignored,
|
|
example.i:58: Warning 404: previous instantiation of 'vector< double >' with name 'vec'.
|
|
</pre>
|
|
</div>
|
|
<p> If this was not ignored, the template expansion would result in two
|
|
identical classes. An identical instantiation is only wrapped once in
|
|
order to reduce code bloat.</p>
|
|
<p><b> Compatibility Note</b>: Versions prior to SWIG-4.2.0 would
|
|
sometimes not detect and prevent duplicate instantiations, such as when
|
|
the wrapped name was different.</p>
|
|
<h3><a name="SWIGPlus_template_class_inheritance">6.18.4 Template base
|
|
classes</a></h3>
|
|
<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: Warning 401. Nothing known about class 'List< int >'. Ignored.
|
|
example.h:42: Warning 401. Maybe you forgot to instantiate 'List< int >' using %template.
|
|
</pre>
|
|
</div>
|
|
<p> If a class template inherits from another class template, 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> 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>
|
|
<h3><a name="SWIGPlus_template_empty">6.18.5 Empty template
|
|
instantiation</a></h3>
|
|
<p> Occasionally, you may need to tell SWIG about 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>, that is the empty template instantiation that omits
|
|
providing a name. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
template<typename T> struct Traits {
|
|
typedef T type;
|
|
};
|
|
%}
|
|
|
|
%template() Traits<int>; // instantiate Traits<int>, but don't wrap it
|
|
|
|
void traitor(Traits<int>::type val);
|
|
</pre>
|
|
</div>
|
|
<p> Without a template instantiation, SWIG does not know that the first
|
|
parameter to the <tt>traitor</tt> function is type int and passing an
|
|
integer to this function from any target language won't work. The empty
|
|
template instantiation adds the appropriate type information into
|
|
SWIG's type system, without forcing one to wrap the <tt>Traits</tt>
|
|
class.</p>
|
|
<p> Duplicate template instantiation are not allowed, as described in
|
|
the <a href="#SWIGPlus_template_classes">Default template arguments</a>
|
|
section above. There is one exception where a named template
|
|
instantiation can be followed by an empty template instantiation.
|
|
Duplicate empty template instantiations are silently ignored, unlike
|
|
duplicate named template instantiations.</p>
|
|
<p> Unlike template class instantiations, template function
|
|
instantiations must have a name. Consider the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
template<class T> T tfunc(T x) { };
|
|
%template() tfunc<double>;
|
|
</pre>
|
|
</div>
|
|
<p> The empty template instantiation will be ignored with:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:9: Warning 519: %template() contains no name. Template method ignored: tfunc< double >(double)
|
|
</pre>
|
|
</div>
|
|
<h3><a name="SWIGPlus_template_specialization">6.18.6 Template
|
|
specialization</a></h3>
|
|
<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(T obj);
|
|
int length();
|
|
T get(int n);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> SWIG supports both template explicit specialization and partial
|
|
specialization. Consider:</p>
|
|
<div class="code">
|
|
<pre>
|
|
template<class T1, class T2> class Foo { }; // (1) primary template
|
|
template<> class Foo<double *, int *> { }; // (2) explicit specialization
|
|
template<class T1, class T2> class Foo<T1, T2 *> { }; // (3) partial specialization
|
|
</pre>
|
|
</div>
|
|
<p> SWIG is able to properly match explicit instantiations:</p>
|
|
<div class="code">
|
|
<pre>
|
|
<tt>Foo<double *, int *></tt> // explicit specialization matching (2)
|
|
</pre>
|
|
</div>
|
|
<p> SWIG implements template argument deduction so that the following
|
|
partial specialization examples work just like they would with a C++
|
|
compiler:</p>
|
|
<div class="code">
|
|
<pre>
|
|
<tt>Foo<int *, int *></tt> // partial specialization matching (3)
|
|
<tt>Foo<int *, const int *></tt> // partial specialization matching (3)
|
|
<tt>Foo<int *, int **></tt> // partial specialization matching (3)
|
|
</pre>
|
|
</div>
|
|
<h3><a name="SWIGPlus_template_member">6.18.7 Member templates</a></h3>
|
|
<p> Member 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
|
|
function 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 exactly the same job, i.e., it adds two new methods
|
|
to the Foo class.</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 class template. 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
|
|
class template 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, double>; // 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, double>; // 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>
|
|
<h3><a name="SWIGPlus_template_scoping">6.18.8 Scoping and templates</a></h3>
|
|
<p> The <tt>%template</tt> directive for a class template is the
|
|
equivalent to an explicit instantiation of a C++ class template. The
|
|
scope for a valid <tt>%template</tt> instantiation is the same as the
|
|
scope required for a valid explicit instantiation of a C++ template. A
|
|
definition of the template for the explicit instantiation must be in
|
|
scope where the instantiation is declared and must not be enclosed
|
|
within a different namespace.</p>
|
|
<p> For example, a few <tt>%template</tt> instantiations and C++
|
|
explicit instantiations are shown below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
namespace N {
|
|
template<typename T> class C {};
|
|
}
|
|
|
|
// valid
|
|
%template(cin) N::C<int>;
|
|
template class N::C<int>;
|
|
|
|
// valid
|
|
namespace N {
|
|
%template(cin) C<int>;
|
|
template class C<int>;
|
|
}
|
|
|
|
// valid
|
|
using namespace N;
|
|
%template(cin) C<int>;
|
|
template class C<int>;
|
|
|
|
// valid
|
|
using N::C;
|
|
%template(cin) C<int>;
|
|
template class C<int>;
|
|
|
|
// ill-formed
|
|
namespace unrelated {
|
|
using N::C;
|
|
%template(cin) C<int>;
|
|
template class C<int>;
|
|
}
|
|
|
|
// ill-formed
|
|
namespace unrelated {
|
|
using namespace N;
|
|
%template(cin) C<int>;
|
|
template class C<int>;
|
|
}
|
|
|
|
// ill-formed
|
|
namespace unrelated {
|
|
namespace N {
|
|
%template(cin) C<int>;
|
|
template class C<int>;
|
|
}
|
|
}
|
|
|
|
// ill-formed
|
|
namespace unrelated {
|
|
%template(cin) N::C<int>;
|
|
template class N::C<int>;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> When the scope is incorrect, such as for the ill-formed examples
|
|
above, an error occurs:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
cpp_template_scope.i:34: Error: 'C' resolves to 'N::C' and was incorrectly instantiated
|
|
in scope 'unrelated' instead of within scope 'N'.
|
|
</pre>
|
|
</div>
|
|
<p> A note for the C++ standard geeks out there; a valid instantiation
|
|
is one which conforms to the C++03 standard as C++11 made a change to
|
|
disallow using declarations and using directives to find a template.</p>
|
|
<div class="code">
|
|
<pre>
|
|
// valid C++03, ill-formed C++11
|
|
using N::C;
|
|
template class C<int>;
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility Note</b>: Versions prior to SWIG-4.0.0 did not
|
|
error out with incorrectly scoped <tt>%template</tt> declarations, but
|
|
this led to numerous subtle template scope problems.</p>
|
|
<h3><a name="SWIGPlus_template_more">6.18.9 More on templates</a></h3>
|
|
<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 class
|
|
template. 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> It is even possible to extend a class via <tt>%extend</tt> with
|
|
template methods, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_string.i>
|
|
|
|
%inline %{
|
|
class ExtendMe {
|
|
public:
|
|
template <typename T>
|
|
T do_stuff_impl(int a, T b, double d) {
|
|
return b;
|
|
}
|
|
};
|
|
%}
|
|
|
|
%extend ExtendMe {
|
|
template<typename T>
|
|
T do_overloaded_stuff(T b) {
|
|
return $self->do_stuff_impl(0, b, 4.0);
|
|
}
|
|
}
|
|
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff<std::string>;
|
|
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff<double>;
|
|
</pre>
|
|
</div>
|
|
<p> The wrapped <tt>ExtendMe</tt> class will then have two (overloaded)
|
|
methods called <tt>do_overloaded_stuff</tt>.</p>
|
|
<p><b> Compatibility Note</b>: Extending a class with template methods
|
|
was added in version 3.0.12</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 checks this when it compiles the
|
|
resulting wrapper file, there is no practical reason for SWIG to
|
|
duplicate this functionality.</p>
|
|
<a name="SWIGPlus_template_nested_class_example"></a>
|
|
<p> As SWIG's template support does not perform type checking <tt>
|
|
%template</tt> can be used as early as after a template declaration. You
|
|
can, and rarely have to, use <tt>%template</tt> before the template
|
|
parameters have been declared. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
template <class T> class OuterTemplateClass {};
|
|
|
|
// The nested class OuterClass::InnerClass inherits from the class template
|
|
// OuterTemplateClass<OuterClass::InnerStruct> and thus the template needs
|
|
// to be expanded with %template before the OuterClass declaration.
|
|
%template(OuterTemplateClass_OuterClass__InnerStruct)
|
|
OuterTemplateClass<OuterClass::InnerStruct>
|
|
|
|
|
|
// Don't forget to use %feature("flatnested") for OuterClass::InnerStruct and
|
|
// OuterClass::InnerClass if the target language doesn't support nested classes.
|
|
class OuterClass {
|
|
public:
|
|
// Forward declarations:
|
|
struct InnerStruct;
|
|
class InnerClass;
|
|
};
|
|
|
|
struct OuterClass::InnerStruct {};
|
|
|
|
// Expanding the template at this point with %template is too late as the
|
|
// OuterClass::InnerClass declaration is processed inside OuterClass.
|
|
|
|
class OuterClass::InnerClass : public OuterTemplateClass<InnerStruct> {};
|
|
</pre>
|
|
</div>
|
|
<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_namespaces">6.19 Namespaces</a></h2>
|
|
<p> Support for C++ namespaces is comprehensive, but by default simple,
|
|
however, some target languages can turn on more advanced namespace
|
|
support via the <a href="#SWIGPlus_nspace">nspace feature</a>,
|
|
described later. Code within unnamed namespaces is ignored as there is
|
|
no external access to symbols declared within the unnamed namespace.
|
|
Before detailing the default implementation for named namespaces, 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 a <tt>using</tt> declaration:</p>
|
|
<div class="code">
|
|
<pre>
|
|
using math::Complex; // Using declaration
|
|
double magnitude(Complex *c); // Namespace prefix stripped
|
|
</pre>
|
|
</div>
|
|
<p> Similarly, the contents of an entire namespace can be made available
|
|
via a <tt>using</tt> directive:</p>
|
|
<div class="code">
|
|
<pre>
|
|
using namespace math; // Using directive
|
|
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. Note that the default handling of
|
|
flattening all the namespace scopes in the target language can be
|
|
changed via the <a href="#SWIGPlus_nspace">nspace feature</a>.</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 target language module.
|
|
example.i:23: Error: 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> C++ <tt>using</tt> directives and <tt>using</tt> declarations do not
|
|
add any code to the generated wrapper code. However, there is an
|
|
exception in one context, see <a href="#SWIGPlus_nn35">Using
|
|
declarations and inheritance</a> for introducing members of a base
|
|
class into a derived class definition. C++ <tt>using</tt> declarations
|
|
and directives<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. More advanced handling of
|
|
namespaces is discussed next.</p>
|
|
<h3><a name="SWIGPlus_nspace">6.19.1 The nspace feature for namespaces</a>
|
|
</h3>
|
|
<p> The <tt>nspace</tt> feature operates in two modes. Firstly, in a
|
|
simple enable/disable mode to mirror the C++ namespaces into the target
|
|
language specific concept of a C++ namespace. Secondly, a complex mode
|
|
for modifying, renaming or moving the hierarchies of the language
|
|
specific concept of a C++ namespace.</p>
|
|
<p> The types of symbols that the feature can be applied to are any
|
|
class, struct, union or enum declared within a named namespace. This
|
|
also includes templates of the aforementioned types. The feature wraps
|
|
the type within the target language specific concept of a namespace,
|
|
such as a Java package or C# namespace. Only some target languages
|
|
provide support for the <tt>nspace</tt> feature. Please see the target
|
|
language specific sections to see if the language you are interested in
|
|
supports the nspace feature.</p>
|
|
<h4><a name="SWIGPlus_nspace_feature_flag">6.19.1.1 %nspace for
|
|
mirroring namespace hierarchies</a></h4>
|
|
<p> In this simple mode the <tt>nspace</tt> feature works as a <a href="#Customization_feature_flags">
|
|
feature flag</a> to enable or disable the feature for a given C++
|
|
symbol. As described earlier, all namespace are flattened by default,
|
|
hence the <tt>nspace</tt> feature is disabled by default. When the
|
|
feature is enabled, the C++ namespace hierarchies are mirrored into the
|
|
target language concept of a namespace.</p>
|
|
<p> The feature flag is demonstrated below using the following example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("nspace") MyWorld::Material::Color;
|
|
%nspace MyWorld::Wrapping::Color; // %nspace is a macro for %feature("nspace")
|
|
|
|
namespace MyWorld {
|
|
namespace Material {
|
|
class Color {
|
|
...
|
|
};
|
|
}
|
|
namespace Wrapping {
|
|
class Color {
|
|
...
|
|
};
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> By default, without the above <tt>nspace</tt> feature flags (or an
|
|
appropriate <tt>%rename</tt>), SWIG outputs the following warning
|
|
resulting in just one of the <tt>Color</tt> classes being available for
|
|
use from the target language:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:9: Error: 'Color' is multiply defined in the generated target language module.
|
|
example.i:5: Error: Previous declaration of 'Color'
|
|
</pre>
|
|
</div>
|
|
<p> Let's consider C# as the target language. With the two <tt>nspace</tt>
|
|
feature flags, the two C# <tt>Color</tt> proxy classes are generated
|
|
into the equivalent C# namespaces that mirror the C++ namespace
|
|
hierarchies. A fully qualified constructor call of each these two types
|
|
in C# is then:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
var materialColor = new MyWorld.Material.Color();
|
|
var wrappingColor = new MyWorld.Wrapping.Color();
|
|
</pre>
|
|
</div>
|
|
<p> Without the <tt>nspace</tt> feature flag, no namespaces are
|
|
available in C# and the fully qualified constructor call of the type in
|
|
C# would simply be:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
var materialColor = new Color();
|
|
</pre>
|
|
</div>
|
|
<p> Note that the <tt>nspace</tt> feature does not apply to variables
|
|
and functions simply declared in a namespace. For example, the
|
|
following symbols cannot co-exist in the target language without
|
|
renaming. This may change in a future version.</p>
|
|
<div class="code">
|
|
<pre>
|
|
namespace MyWorld {
|
|
namespace Material {
|
|
int quantity;
|
|
void dispatch();
|
|
}
|
|
namespace Wrapping {
|
|
int quantity;
|
|
void dispatch();
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility Note:</b> The simple <tt>%nspace</tt> feature flag
|
|
was first introduced in SWIG-2.0.0.</p>
|
|
<h4><a name="SWIGPlus_nspacemove">6.19.1.2 %nspacemove for modifying
|
|
namespace hierarchies</a></h4>
|
|
<p> The more complex mode for <tt>nspace</tt> provides the ability to
|
|
move a type into a differently named target language equivalent of a
|
|
namespace. This allows a fully flexible approach to mapping C++
|
|
namespaces into a target language equivalent of a namespace, such as:</p>
|
|
<ul>
|
|
<li> Renaming a namespace.</li>
|
|
<li> Renaming any number of sub-namespaces of a namespace.</li>
|
|
<li> Moving a type to a completely different namespace.</li>
|
|
<li> Splitting many types in one namespace into multiple different
|
|
namespaces.</li>
|
|
<li> Adding nested sub-namespaces to a namespace.</li>
|
|
<li> Removing nested sub-namespaces of namespace.</li>
|
|
<li> Combinations of the above.</li>
|
|
</ul>
|
|
<p> The <tt>nspace</tt> feature attaches to a C++ symbol and provides a
|
|
target language namespace for that symbol to move to. The <tt>
|
|
%nspacemove</tt> directive is a macro for the <tt>nspace</tt> feature as
|
|
follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#define %nspacemove(NAMESPACE) %feature("nspace", #NAMESPACE)
|
|
</pre>
|
|
</div>
|
|
<p> where the target namespace is provided in <tt>NAMESPACE</tt> and is
|
|
specified in valid C++ syntax, such as <tt>A::B::C</tt>. Internally,
|
|
SWIG converts the C++ namespace into a target language equivalent, so
|
|
this might for example, result in a C# namespace called <tt>A.B.C</tt>
|
|
or a Java package named <tt>A.B.C</tt>. Note that the target namespace
|
|
does not have to actually exist in any of the C++ code that SWIG
|
|
parses; it could be entirely made-up.</p>
|
|
<p> Either the <tt>%nspacemove</tt> macro or the more verbose <tt>
|
|
%feature</tt> syntax can be used. Please see the <a href="#Customization_features">
|
|
Features and the %feature directive</a> section for more details of SWIG
|
|
features.</p>
|
|
<p> An example follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// Enable the nspace feature flag for all symbols
|
|
%nspace;
|
|
|
|
// Override the nspace feature for a subset of symbols by moving them into different namespaces
|
|
%nspacemove(A) A::B::C::Struct1;
|
|
%feature("nspace", "A::B::X") A::B::C::Struct2;
|
|
%nspacemove(A::B::C::D) A::B::C::Struct4;
|
|
%nspacemove(Somewhere::Else) A::B::C::Struct5;
|
|
|
|
%inline %{
|
|
namespace A {
|
|
namespace B {
|
|
namespace C {
|
|
struct Struct1 {
|
|
// ...
|
|
};
|
|
struct Struct2 {
|
|
// ...
|
|
};
|
|
struct Struct3 {
|
|
// ...
|
|
};
|
|
struct Struct4 {
|
|
// ...
|
|
};
|
|
struct Struct5 {
|
|
// ...
|
|
};
|
|
}
|
|
}
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The C# code below constructs each of the above classes. It shows the
|
|
namespaces that the C# proxy classes have been moved into, noting
|
|
though that <tt>Struct4</tt> merely exactly mirrors the C++ namespace
|
|
hierarchy as it has the <tt>nspace</tt> feature flag attached to it.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
var s1 = new A.Struct1();
|
|
var s2 = new A.B.X.Struct2();
|
|
var s3 = new A.B.C.Struct3();
|
|
var s4 = new A.B.C.D.Struct4();
|
|
var s5 = new Somewhere.Else.Struct5();
|
|
</pre>
|
|
</div>
|
|
<h4><a name="SWIGPlus_nspace_more">6.19.1.3 More about the nspace
|
|
feature</a></h4>
|
|
<p> When the <tt>nspace</tt> feature is attached to a class or enum, all
|
|
contained symbols (members) are also automatically moved into the
|
|
target language namespace. Contained symbols include all enum values,
|
|
static and non-static class members as well as nested classes. There is
|
|
no need for additional <tt>nspace</tt> features to be specified for all
|
|
the contained symbols. Below is an example showing this. It also shows
|
|
the nspace feature working for templates.</p>
|
|
<div class="code">
|
|
<pre>
|
|
// Easy way to move all the Structure template instantiations into a different namespace
|
|
%nspacemove(A::Different::Space) Space::Structure;
|
|
|
|
%inline %{
|
|
namespace Space {
|
|
template<typename T>
|
|
struct Structure {
|
|
static int Count;
|
|
static void StaticMethod(T t) {
|
|
// ...
|
|
}
|
|
struct NestedStruct {
|
|
// ...
|
|
};
|
|
};
|
|
template<typename T>
|
|
int Structure<T>::Count = 0;
|
|
}
|
|
%}
|
|
%template(StructureInt) Space::Structure<int>;
|
|
%template(StructureString) Space::Structure<const char *>;
|
|
</pre>
|
|
</div>
|
|
<p> The C# code below shows the full C# namespace <tt>A.Different.Space</tt>
|
|
being used as one would expect for all the contained symbols within a
|
|
C# class.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
var s = new A.Different.Space.StructureInt();
|
|
int count = A.Different.Space.StructureInt.Count;
|
|
var n = new A.Different.Space.StructureInt.NestedStruct();
|
|
A.Different.Space.StructureInt.StaticMethod(99);
|
|
A.Different.Space.StructureString.StaticMethod("hi");
|
|
</pre>
|
|
</div>
|
|
<p> Any attempt to give a different namespace value to a nested class or
|
|
enum will issue a warning. For example, adding the following to the
|
|
above in an attempt to move one of the instantiated nested classes into
|
|
another namespace like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%nspacemove(Bad::Space) Space::Structure<int>::NestedStruct;
|
|
... rest of example above ...
|
|
</pre>
|
|
</div>
|
|
<p> will result in the following warning:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
Warning 406: Ignoring nspace setting (Bad::Space) for 'Space::Structure< int >::NestedStruct',
|
|
Warning 406: as it conflicts with the nspace setting (A::Different::Space) for outer class 'Space::Structure< int >'.
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility Note:</b> Modifying namespace hierarchies via <tt>
|
|
%nspacemove</tt> was first introduced in SWIG-4.3.0.</p>
|
|
<h2><a name="SWIGPlus_renaming_templated_types_namespaces">6.20 Renaming
|
|
templated types in namespaces</a></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">6.21 Exception
|
|
specifications</a></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="#Typemaps_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="#Customization_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">6.22 Exception handling with %catches</a></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="#Typemaps_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">6.23 Pointers to Members</a></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_smart_pointers">6.24 Smart pointers and
|
|
operator->()</a></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 class template 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:
|
|
SmartPtr(T *p) : pointee(p) { ... }
|
|
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<Foo_Impl>(new Foo_Impl());
|
|
}
|
|
|
|
// Do something with smart pointer Foo
|
|
void do_something(Foo f) {
|
|
printf("x = %d\n", f->x);
|
|
f->bar();
|
|
}
|
|
|
|
// Call the wrapped smart pointer proxy class in the target language 'Foo'
|
|
%template(Foo) SmartPtr<Foo_Impl>;
|
|
</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_ref_unref">6.25 C++ reference counted objects -
|
|
ref/unref feature</a></h2>
|
|
<p> Another similar idiom in C++ is the use of reference counted
|
|
objects. Consider for example:</p>
|
|
<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(); // (count: 0)
|
|
a->ref(); // 'a' ref here (count: 1)
|
|
|
|
B *b1 = new B(a); // 'a' ref here (count: 2)
|
|
if (1 + 1 == 2) {
|
|
B *b2 = new B(a); // 'a' ref here (count: 3)
|
|
delete b2; // 'a' unref, but not deleted (count: 2)
|
|
}
|
|
|
|
delete b1; // 'a' unref, but not deleted (count: 1)
|
|
a->unref(); // 'a' unref and deleted (count: 0)
|
|
}
|
|
</pre>
|
|
</div>
|
|
<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 a<i> Reference
|
|
Counted Object</i> 'RCObj', which implements the ref/unref idiom.</p>
|
|
<p> To tell SWIG that 'RCObj' and all its derived classes are reference
|
|
counted objects, use the "ref" and "unref" <a href="#Customization_features">
|
|
features</a>. These are also available as <tt>%refobject</tt> and <tt>
|
|
%unrefobject</tt>, respectively. 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>
|
|
<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 proxy object instance, respectively.</p>
|
|
<p> On the Python side, the use of a reference counted object is no
|
|
different to any other regular instance:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
def create_A():
|
|
a = A() # SWIG ref 'a' - new object is passed to Python (count: 1)
|
|
b1 = B(a) # C++ ref 'a (count: 2)
|
|
if 1 + 1 == 2:
|
|
b2 = B(a) # C++ ref 'a' (count: 3)
|
|
return a # 'b1' and 'b2' are released and deleted, C++ unref 'a' twice (count: 1)
|
|
|
|
a = create_A() # (count: 1)
|
|
exit # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0)
|
|
</pre>
|
|
</div>
|
|
<p> Note that the user doesn't explicitly need to call 'a->ref()' nor
|
|
'a->unref()' (and neither 'delete a'). Instead, SWIG takes cares of
|
|
executing the "ref" and "unref" calls as needed. If the user doesn't
|
|
specify the "ref/unref" feature for a type, SWIG will produce code
|
|
equivalent to defining these features:</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 underlying object
|
|
when Python releases the proxy instance.</p>
|
|
<p> The <a href="#Customization_ownership">%newobject feature</a> is
|
|
designed to indicate to the target language that it should take
|
|
ownership of the returned object. When used in conjunction with a type
|
|
that has the "ref" feature associated with it, it additionally emits
|
|
the code in the "ref" feature into the C++ wrapper. Consider wrapping
|
|
the following factory function in addition to the above:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%newobject AFactory;
|
|
A *AFactory() {
|
|
return new A();
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>AFactory</tt> function now acts much like a call to the <tt>
|
|
A</tt> constructor with respect to memory handling:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
a = AFactory() # SWIG ref 'a' due to %newobject (count: 1)
|
|
exit # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0)
|
|
</pre>
|
|
</div>
|
|
<h2><a name="SWIGPlus_nn35">6.26 Using declarations and inheritance</a></h2>
|
|
<p> C++ <tt>using</tt> declarations are sometimes used to introduce
|
|
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> The C++11 standard supports using declarations for inheriting
|
|
constructors and this is covered in <a href="CPlusPlus11_object_construction_improvement">
|
|
Object construction improvement</a>.</p>
|
|
<p> C++ <tt>using</tt> declarations can also be used to change access
|
|
when applicable. For example, protected methods in a base class can be
|
|
made public in a derived class:</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, because a single <tt>
|
|
using</tt> declaration may introduce multiple methods, 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 modify the C++ code to handle SWIG
|
|
differently such as:</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> If the C++ code being wrapped cannot be changed, make judicious
|
|
usage of <tt>%extend</tt> and <tt>%rename</tt> to ignore and unignore
|
|
declarations. The example below is effectively the same as above:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%extend FooBar {
|
|
int blah(int x) { return $self->Foo::blah(x); }
|
|
double blah(double x) { return $self->Bar::blah(x); }
|
|
}
|
|
%ignore FooBar::blah; // ignore all FooBar::blah below
|
|
%rename("") FooBar::blah(const char *x); // parameterized unignore
|
|
|
|
class FooBar : public Foo, public Bar {
|
|
public:
|
|
using Foo::blah;
|
|
using Bar::blah;
|
|
char *blah(const char *x);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p><b> Notes:</b></p>
|
|
<ul>
|
|
<li>
|
|
<p>If a derived class introduces a method defined in a base class via a <tt>
|
|
using</tt> declaration, there won't be a conflict due to incorrect
|
|
additional methods. 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 introduces blah(double);
|
|
int blah(int);
|
|
};
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>Renaming methods may prevent methods from being introduced into the
|
|
derived class via <tt>using</tt> declarations. 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 introduces blah(int)
|
|
double blah(double x);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The problem here is <tt>Foo::blah</tt> is renamed to <tt>blah_long</tt>
|
|
in the target language, but the <tt>using</tt> declaration in Bar is
|
|
not renamed in the target language and thinks all introduced methods
|
|
should simply be called <tt>blah</tt>. It is not clear what target
|
|
language names should be used in Bar and so the conflicting names are
|
|
effectively ignored as they are not introduced into the derived class
|
|
for the target language wrappers. In such situations SWIG will emit a
|
|
warning:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:15: Warning 526: Using declaration Foo::blah, with name 'blah', is not actually using
|
|
example.i:10: Warning 526: the method from Foo::blah(long), with name 'blah_long', as the names are different.
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility Note:</b> This warning message was introduced in
|
|
SWIG-4.1.0. Prior versions also effectively ignored the using
|
|
declaration for the same reasons, but were silent about it.</p>
|
|
<p> If methods really need different names, please use of combinations
|
|
of <tt>%rename</tt>, <tt>%ignore</tt> and <tt>%extend</tt> to achieve
|
|
the desired outcome.</p>
|
|
</li>
|
|
</ul>
|
|
<h2><a name="SWIGPlus_nested_classes">6.27 Nested classes</a></h2>
|
|
<p> If the target language supports the nested classes concept (like
|
|
Java), the nested C++ classes are wrapped as nested target language
|
|
proxy classes. (In case of Java - "static" nested classes.) Only public
|
|
nested classes are wrapped. Otherwise there is little difference
|
|
between nested and normal classes.</p>
|
|
<p> If the target language doesn't support nested classes directly, or
|
|
the support is not implemented in the language module (like for Python
|
|
currently), then the visible nested classes are moved to the same name
|
|
space as the containing class (nesting hierarchy is "flattened"). The
|
|
same behaviour may be turned on for C# and Java by the %feature
|
|
("flatnested"); If there is a class with the same name in the outer
|
|
namespace the inner class (or the global one) may be renamed or
|
|
ignored:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename (Bar_Foo) Bar::Foo;
|
|
class Foo {};
|
|
class Bar {
|
|
public:
|
|
class Foo {};
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> If a nested class, within an outer class, has to be used as a
|
|
template parameter within the outer class, then the template will have
|
|
to be instantiated with <tt>%template</tt> before the beginning of the
|
|
outer class. An example can be found in the <a href="#SWIGPlus_template_nested_class_example">
|
|
Templates</a> section.</p>
|
|
<p><b> Compatibility Note:</b> Prior to SWIG-3.0.0, there was limited
|
|
nested class support. Nested classes were treated as opaque pointers.
|
|
However, there was a workaround for nested class support in these older
|
|
versions requiring the user to replicate the nested class in the global
|
|
scope, adding in a typedef for the nested class in the global scope and
|
|
using the "nestedworkaround" feature on the nested class. This resulted
|
|
in approximately the same behaviour as the "flatnested" feature. With
|
|
proper nested class support now available in SWIG-3.0.0, this feature
|
|
was deprecated and has now been removed. If you see the following
|
|
error:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:8: Error: Unknown directive '%nestedworkaround'
|
|
</pre>
|
|
</div>
|
|
<p> consider using the "flatnested" feature discussed above which
|
|
generates a non-nested proxy class, like the "nestedworkaround" feature
|
|
did. Alternatively, use the default nested class code generation, which
|
|
may generate an equivalent to a nested proxy class in the target
|
|
language, depending on the target language support.</p>
|
|
<p> SWIG-1.3.40 and earlier versions did not have the <tt>
|
|
nestedworkaround</tt> feature and the generated code resulting from
|
|
parsing nested classes did not always compile. Nested class warnings
|
|
could also not be suppressed using %warnfilter.</p>
|
|
<h2><a name="SWIGPlus_const">6.28 A brief rant about const-correctness</a>
|
|
</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_target_language_callbacks">6.29 Callbacks to the
|
|
target language</a></h2>
|
|
<p> C/C++ function pointers are often used for callbacks and this is
|
|
discussed in the <a href="#SWIG_nn30">Pointers to functions and
|
|
callbacks</a> section. The callback techniques described therein
|
|
provide a way to control callbacks to a C/C++ function but not
|
|
callbacks into the target language. The techniques described below show
|
|
how the director feature can be used to support callbacks from C/C++ to
|
|
the target language.</p>
|
|
<h3><a name="SWIGPlus_director_classes_introduction">6.29.1 Introduction
|
|
to director classes</a></h3>
|
|
<p> The director feature enables the ability for a target language class
|
|
to derive from a wrapped C++ class. The target language can override
|
|
virtual methods of a wrapped C++ class, thereby supporting
|
|
cross-language polymorphism. Code can 'call up' from C++ into the
|
|
target language by simply calling a virtual method overridden in a
|
|
derived class in the target language. The wrapped C++ classes that have
|
|
this ability are termed 'director' classes. The director feature is
|
|
documented individually in each target language and the reader should
|
|
locate and read this to obtain a full understanding of directors.</p>
|
|
<h3><a name="SWIGPlus_directors_for_function_pointers">6.29.2 Using
|
|
directors and target language callbacks</a></h3>
|
|
<p> SWIG's primary goal is to make it possible to call C/C++ code from a
|
|
target language, however, the director feature enables the reverse.
|
|
While there isn't simple direct support for calling target language
|
|
code from C, the director feature makes this possible. It does require
|
|
some work and additional wrapper code to be provided by the user. The
|
|
additional code required must be C++ and not C code and hence may
|
|
introduce a small dependency on C++ if using a pure C project. In a
|
|
nutshell, the user must create a C++ base class and turn it into a
|
|
director class. A virtual method in the director base class is
|
|
required. SWIG generates the code to call up into the target language
|
|
when wrapping the director virtual method.</p>
|
|
<p> Let's look at some details next. Consider the same function pointer
|
|
for a callback called <tt>binary_op</tt> from the <a href="#SWIG_nn30">
|
|
Pointers to functions and callbacks</a> section. For completeness, the
|
|
code required for the module and director feature is also shown:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(directors="1") example
|
|
|
|
%{
|
|
int binary_op(int a, int b, int (*op)(int, int)) {
|
|
return op(a, b);
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The goal is to have a target language function that gets called by <tt>
|
|
binary_op</tt>. The target language function should have the equivalent
|
|
signature as the C/C++ function pointer <tt>int (*op)(int, int)</tt>.
|
|
As we are using directors, we need a C++ virtual method with this
|
|
signature, so let's define the C++ class and pure virtual method first
|
|
and make it a director class via the director feature:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director") BinaryOp;
|
|
|
|
%inline %{
|
|
struct BinaryOp {
|
|
virtual int handle(int a, int b) = 0;
|
|
virtual ~BinaryOp() {}
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The following <tt>handler_helper</tt> function and <tt>
|
|
binary_op_wrapper</tt> function completes the code needed in the
|
|
C++/SWIG layer. The <tt>binary_op_wrapper</tt> function is wrapped by
|
|
SWIG and is very similar to the <tt>binary_op</tt> function, however,
|
|
it takes a pointer to the director base class <tt>BinaryOp</tt> instead
|
|
of a C/C++ function pointer.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
static BinaryOp *handler_ptr = NULL;
|
|
static int handler_helper(int a, int b) {
|
|
// Make the call up to the target language when handler_ptr
|
|
// is an instance of a target language director class
|
|
return handler_ptr->handle(a, b);
|
|
}
|
|
// If desired, handler_ptr above could be changed to a thread-local variable in order to make thread-safe
|
|
%}
|
|
|
|
%inline %{
|
|
int binary_op_wrapper(int a, int b, BinaryOp *handler) {
|
|
handler_ptr = handler;
|
|
int result = binary_op(a, b, &handler_helper);
|
|
handler = NULL;
|
|
return result;
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> On the target language side, we need to derive a class from <tt>
|
|
BinaryOp</tt> and override the <tt>handle</tt> method. In Python this
|
|
could be as simple as:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
import example
|
|
|
|
# PythonBinaryOp class is defined and derived from C++ class BinaryOp
|
|
class PythonBinaryOp(example.BinaryOp):
|
|
|
|
# Define Python class 'constructor'
|
|
def __init__(self):
|
|
# Call C++ base class constructor
|
|
example.BinaryOp.__init__(self)
|
|
|
|
# Override C++ method: virtual int handle(int a, int b) = 0;
|
|
def handle(self, a, b):
|
|
# Return the product
|
|
return a * b
|
|
</pre>
|
|
</div>
|
|
<p> For this to work from Python, an instance of the <tt>PythonBinaryOp</tt>
|
|
class is created and then passed to <tt>binary_op_wrapper</tt>. The net
|
|
result is the <tt>binary_op</tt> function will in turn be called which
|
|
will call <tt>handler_helper</tt> which will call the virtual <tt>
|
|
handle</tt> method, that is, the Python method <tt>handle</tt> in the
|
|
PythonBinaryOp class. The result will be the product of 10 and 20 and
|
|
make its way back to Python and hence 200 will be printed with the
|
|
following code:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
handler = PythonBinaryOp()
|
|
result = example.binary_op_wrapper(10, 20, handler)
|
|
print(result)
|
|
</pre>
|
|
</div>
|
|
<p> This has thus demonstrated a C/C++ function pointer calling back
|
|
into a target language function. The code could be made a little more
|
|
user friendly by using <tt>%rename</tt> to provide the original <tt>
|
|
binary_op</tt> name from the target language instead of <tt>
|
|
binary_op_wrapper</tt>. A C++ functor base class and Python functor
|
|
class could also be used instead, but these are left as exercises for
|
|
the reader.</p>
|
|
<h2><a name="SWIGPlus_nn42">6.30 Where to go for more information</a></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="CPlusPlus11">7 SWIG and C++11</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#CPlusPlus11_introduction">Introduction</a></li>
|
|
<li><a href="#CPlusPlus11_core_language_changes">Core language changes</a>
|
|
<ul>
|
|
<li><a href="#CPlusPlus11_rvalue_reference_and_move_semantics">Rvalue
|
|
reference and move semantics</a>
|
|
<ul>
|
|
<li><a href="#CPlusPlus11_rvalue_reference_inputs">Rvalue reference
|
|
inputs</a></li>
|
|
<li><a href="#CPlusPlus11_rvalue_reference_outputs">Rvalue reference
|
|
outputs</a></li>
|
|
<li><a href="#CPlusPlus11_move_only">Movable and move-only types by
|
|
value</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#CPlusPlus11_generalized_constant_expressions">Generalized
|
|
constant expressions</a></li>
|
|
<li><a href="#CPlusPlus11_extern_template">Extern template</a></li>
|
|
<li><a href="#CPlusPlus11_initializer_lists">Initializer lists</a></li>
|
|
<li><a href="#CPlusPlus11_uniform_initialization">Uniform initialization</a>
|
|
</li>
|
|
<li><a href="#CPlusPlus11_type_inference">Type inference</a></li>
|
|
<li><a href="#CPlusPlus11_range_based_for_loop">Range-based for-loop</a></li>
|
|
<li><a href="#CPlusPlus11_lambda_functions_and_expressions">Lambda
|
|
functions and expressions</a></li>
|
|
<li><a href="#CPlusPlus11_alternate_function_syntax">Alternate function
|
|
syntax</a></li>
|
|
<li><a href="#CPlusPlus11_object_construction_improvement">Object
|
|
construction improvement</a></li>
|
|
<li><a href="#CPlusPlus11_explicit_overrides_final">Explicit overrides
|
|
and final</a></li>
|
|
<li><a href="#CPlusPlus11_null_pointer_constant">Null pointer constant</a>
|
|
</li>
|
|
<li><a href="#CPlusPlus11_strongly_typed_enumerations">Strongly typed
|
|
enumerations</a></li>
|
|
<li><a href="#CPlusPlus11_double_angle_brackets">Double angle brackets</a>
|
|
</li>
|
|
<li><a href="#CPlusPlus11_explicit_conversion_operators">Explicit
|
|
conversion operators</a></li>
|
|
<li><a href="#CPlusPlus11_alias_templates">Type alias and alias
|
|
templates</a></li>
|
|
<li><a href="#CPlusPlus11_unrestricted_unions">Unrestricted unions</a></li>
|
|
<li><a href="#CPlusPlus11_variadic_templates">Variadic templates</a></li>
|
|
<li><a href="#CPlusPlus11_new_char_literals">New character literals</a></li>
|
|
<li><a href="#CPlusPlus11_new_string_literals">New string literals</a></li>
|
|
<li><a href="#CPlusPlus11_user_defined_literals">User-defined literals</a>
|
|
</li>
|
|
<li><a href="#CPlusPlus11_thread_local_storage">Thread-local storage</a></li>
|
|
<li><a href="#CPlusPlus11_defaulted_deleted">Explicitly defaulted
|
|
functions and deleted functions</a></li>
|
|
<li><a href="#CPlusPlus11_type_long_long_int">Type long long int</a></li>
|
|
<li><a href="#CPlusPlus11_static_assertions">Static assertions</a></li>
|
|
<li><a href="#CPlusPlus11_sizeof">Allow sizeof to work on members of
|
|
classes without an explicit object</a></li>
|
|
<li><a href="#CPlusPlus11_noexcept">Exception specifications and
|
|
noexcept</a></li>
|
|
<li><a href="#CPlusPlus11_alignment">Control and query object alignment</a>
|
|
</li>
|
|
<li><a href="#CPlusPlus11_attributes">Attributes</a></li>
|
|
<li><a href="#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#CPlusPlus11_standard_library_changes">Standard library
|
|
changes</a>
|
|
<ul>
|
|
<li><a href="#CPlusPlus11_threading_facilities">Threading facilities</a></li>
|
|
<li><a href="#CPlusPlus11_tuple_types">Tuple types</a></li>
|
|
<li><a href="#CPlusPlus11_hash_tables">Hash tables</a></li>
|
|
<li><a href="#CPlusPlus11_regular_expressions">Regular expressions</a></li>
|
|
<li><a href="#CPlusPlus11_general_purpose_smart_pointers">
|
|
General-purpose smart pointers</a></li>
|
|
<li><a href="#CPlusPlus11_extensible_random_number_facility">Extensible
|
|
random number facility</a></li>
|
|
<li><a href="#CPlusPlus11_wrapper_reference">Wrapper reference</a></li>
|
|
<li><a href="#CPlusPlus11_polymorphous_wrappers_for_function_objects">
|
|
Polymorphic wrappers for function objects</a></li>
|
|
<li><a href="#CPlusPlus11_type_traits_for_metaprogramming">Type traits
|
|
for metaprogramming</a></li>
|
|
<li><a href="#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">
|
|
Uniform method for computing return type of function objects</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<h2><a name="CPlusPlus11_introduction">7.1 Introduction</a></h2>
|
|
<p>This chapter gives you a brief overview about the SWIG implementation
|
|
of the C++11 standard.</p>
|
|
<p>SWIG supports the new C++ syntax changes with some minor limitations
|
|
in some areas such as decltype expressions and variadic templates.
|
|
Wrappers for the new STL types (unordered_ containers, result_of,
|
|
tuples) are incomplete. The wrappers for the new containers would work
|
|
much like the C++03 containers and users are welcome to help by
|
|
adapting the existing container interface files and submitting them as
|
|
a patch for inclusion in future versions of SWIG.</p>
|
|
<h2><a name="CPlusPlus11_core_language_changes">7.2 Core language
|
|
changes</a></h2>
|
|
<h3><a name="CPlusPlus11_rvalue_reference_and_move_semantics">7.2.1
|
|
Rvalue reference and move semantics</a></h3>
|
|
<p> SWIG correctly parses the rvalue reference syntax '&&', for example
|
|
the typical usage of it in the move constructor and move assignment
|
|
operator below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class MyClass {
|
|
...
|
|
std::vector<int> numbers;
|
|
public:
|
|
MyClass() : numbers() {}
|
|
MyClass(MyClass &&other) : numbers(std::move(other.numbers)) {}
|
|
MyClass & operator=(MyClass &&other) {
|
|
numbers = std::move(other.numbers);
|
|
return *this;
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Rvalue references are designed for C++ temporaries and are not
|
|
particularly useful when used from non-C++ target languages. One option
|
|
is to just ignore them via <tt>%ignore</tt>. For example, ignore the
|
|
move constructor:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%ignore MyClass::MyClass(MyClass &&);
|
|
</pre>
|
|
</div>
|
|
<h4><a name="CPlusPlus11_rvalue_reference_inputs">7.2.1.1 Rvalue
|
|
reference inputs</a></h4>
|
|
<p> Rvalue reference parameters are useful as input parameters in C++
|
|
for implementing move semantics, such as, in the move constructor and
|
|
move assignment operator. This type of usage can be useful from target
|
|
languages too to avoid copying large objects.</p>
|
|
<p> If you do wrap a function/constructor with an rvalue reference
|
|
parameter and pass a proxy class to it, SWIG will assume that after the
|
|
call, the rvalue reference parameter object will have been 'moved'. The
|
|
proxy class passed as the rvalue reference, will own the underlying C++
|
|
object up until it is used as an rvalue reference parameter.
|
|
Afterwards, the proxy class will have the underlying C++ pointer set to
|
|
the nullptr so that the proxy class instance cannot be used again and
|
|
the underlying (moved from) C++ object will be deleted after the
|
|
function/constructor call has returned.</p>
|
|
<p> In this way, the SWIG proxy class works much like an exclusively
|
|
owned smart pointer (think of <tt>std::unique_ptr</tt>), passing
|
|
ownership to the called C++ function/constructor. Let's consider an
|
|
example in Java using the wrapped proxy class from above:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
MyClass mc = new MyClass();
|
|
MyClass mc1 = new MyClass(mc); // move constructor
|
|
MyClass mc2 = new MyClass(mc); // move constructor fails
|
|
</pre>
|
|
</div>
|
|
<p> The second call to the move constructor will fail as the <tt>mc</tt>
|
|
proxy instance has been moved. Each target language handles the moved
|
|
proxy class slightly differently when attempting to move it again, but
|
|
typically you'll get an exception such as in Java:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
Exception in thread "main" java.lang.RuntimeException: Cannot release ownership as memory is not owned
|
|
at MyClass.swigRelease(MyClass.java:27)
|
|
at MyClass.<init>(MyClass.java:55)
|
|
at runme.main(runme.java:18)
|
|
</pre>
|
|
</div>
|
|
<p> Note that both normal copy assignment operators as well as move
|
|
assignment operators are ignored by default in the target languages
|
|
with the following warning:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:18: Warning 503: Can't wrap 'operator =' unless renamed to a valid identifier.
|
|
</pre>
|
|
</div>
|
|
<p> Using a <tt>%rename</tt> will remove the warning and also makes the
|
|
move assignment operator available from the target language:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(MoveAssign) MyClass::operator=(MyClass &&);
|
|
</pre>
|
|
</div>
|
|
<p> You can then use it, but like the move constructor example above,
|
|
you cannot use a proxy class once it has already been moved:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
MyClass mc = new MyClass();
|
|
MyClass mc2 = mc.MoveAssign(mc);
|
|
MyClass mc3 = mc.MoveAssign(mc); // Use of mc again will fail
|
|
</pre>
|
|
</div>
|
|
<p> It is of course perfectly possible in C++ for a function/constructor
|
|
to not move an object passed to it in an rvalue reference parameter.
|
|
The assumption that SWIG makes would then not hold and customisation of
|
|
the appropriate input typemaps would be required. For scripting
|
|
languages, this would be for the 'in' typemap and for the non-scripting
|
|
languages additional typemaps such as the 'javain' typemap, which is
|
|
used to set the memory ownership of the underlying C++ object for Java,
|
|
would also need copying and modifying appropriately.</p>
|
|
<p><b> Compatibility note:</b> SWIG-4.1.0 changed the way that rvalue
|
|
reference parameters were handled and implemented typemaps assuming
|
|
that the proxy class owns the underlying C++ object and transfers
|
|
ownership of the object when a function/constructor with an rvalue
|
|
reference parameter is called.</p>
|
|
<h4><a name="CPlusPlus11_rvalue_reference_outputs">7.2.1.2 Rvalue
|
|
reference outputs</a></h4>
|
|
<p> While rvalue reference parameter inputs are not uncommon in C++ and
|
|
can be usefully utilised from target languages, this cannot be said for
|
|
rvalue reference outputs. Firstly, it is quite unusual in C++ to have
|
|
functions that return an rvalue reference. Secondly, these cases are
|
|
nigh on impossible to use from a target language. The main problem is
|
|
these references are for C++ compiler temporaries used on the stack and
|
|
the target languages use objects on the heap and the concept of
|
|
compiler temporary objects doesn't make sense from another language.</p>
|
|
<p> Using <tt>MyClass</tt> from earlier and this C++ code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void use(MyClass &&mc);
|
|
MyClass && get1();
|
|
MyClass & get2();
|
|
</pre>
|
|
</div>
|
|
<p> SWIG wraps the <tt>get1</tt> and <tt>get2</tt> functions more or
|
|
less identically. The returned references are converted into pointers
|
|
that are not owned by the target language. It means that the following
|
|
perfectly valid C++ has no equivalent in any of the target languages:</p>
|
|
<div class="code">
|
|
<pre>
|
|
use(get1());
|
|
use(std::move(get2()));
|
|
</pre>
|
|
</div>
|
|
<p> An attempt to call the equivalent <tt>use(get1())</tt> from one of
|
|
the target languages will result in the ownership failure mentioned in
|
|
the previous section as the object being passed to the <tt>use</tt>
|
|
function is not owned by the proxy class. In order to own the object,
|
|
it would need to be cloned for the object to move from the stack to the
|
|
heap, for which an appropriate clone function would be required, but
|
|
may not even be available. Note that a move constructor or copy
|
|
constructor may slice the object when inheritance is involved.
|
|
Alternatively, customising the input rvalue reference typemap, as
|
|
mentioned in the previous section, could remove the ownership
|
|
requirement. Another alternative would be to modify the output rvalue
|
|
reference typemap to always clone the rvalue reference object.
|
|
Fortunately you're highly unlikely to have to solve any of these
|
|
issues!</p>
|
|
<h4><a name="CPlusPlus11_move_only">7.2.1.3 Movable and move-only types
|
|
by value</a></h4>
|
|
<p> SWIG has traditionally relied on wrapped C++ types to be copy
|
|
constructible or copy assignable, either via an explicit or implicit
|
|
copy constructor and copy assignment operator. Prior to C++11, a
|
|
function could not return nor take a type by value that was not
|
|
copyable. In C++11 this is no longer the case. A type can also be
|
|
movable if it has has a move constructor and a move assignment
|
|
operator. A move-only type is movable but not copyable; it has both the
|
|
copy constructor and copy assignment operator deleted. Movable types
|
|
can appear in function signatures for passing 'by value' and in C++11
|
|
the object can then be moved rather than copied.</p>
|
|
<p> SWIG has support for both copyable and/or movable types. Support for
|
|
move semantics is quite seamless when returning by value from a
|
|
function. Support for move semantics is less so and may require some
|
|
customisation when passing by value to a function. First let's consider
|
|
returning by value from a function.</p>
|
|
<p> The support for function return values is generically implemented in
|
|
the "out" <tt>SWIGTYPE</tt> typemap which supports any type, including
|
|
copyable, movable and move-only types. The typemap code is very simple
|
|
and written so that the compiler will call the move constructor if
|
|
possible, otherwise the copy constructor:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(out) SWIGTYPE %{
|
|
$result = new $1_ltype($1);
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The above typemap is for C# and when used to wrap a move-only type
|
|
such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct MoveOnly {
|
|
int val;
|
|
MoveOnly(): val(0) {}
|
|
|
|
MoveOnly(const MoveOnly &) = delete;
|
|
MoveOnly(MoveOnly &&) = default;
|
|
|
|
MoveOnly & operator=(const MoveOnly &) = delete;
|
|
MoveOnly & operator=(MoveOnly &&) = default;
|
|
|
|
static MoveOnly create() { return MoveOnly(); }
|
|
static void take(MoveOnly mo);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> will generate wrapper code for the <tt>create</tt> factory method:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIGEXPORT void * SWIGSTDCALL CSharp_MoveOnly_create() {
|
|
void * jresult ;
|
|
SwigValueWrapper< MoveOnly > result;
|
|
|
|
result = MoveOnly::create();
|
|
jresult = new MoveOnly(result);
|
|
return jresult;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> <tt>SwigValueWrapper</tt> is covered in <a href="#SWIGPlus_nn19">
|
|
Pass and return by value</a> and is automatically generated in this case
|
|
as <tt>MoveOnly</tt> is not assignable. Note that the generated code
|
|
could be optimised further using the <a href="#Typemaps_optimal">
|
|
"optimal" attribute</a> in the "out" typemap, so if the above typemap is
|
|
customised as follows (note that this is C# specific):</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(out, optimal="1") MoveOnly %{
|
|
$result = new $1_ltype($1);
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> then the generated code will result in the object being optimally
|
|
moved:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIGEXPORT void * SWIGSTDCALL CSharp_MoveOnly_create() {
|
|
void * jresult ;
|
|
jresult = new MoveOnly(MoveOnly::create());
|
|
return jresult;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Now let's consider passing by value. We'll consider three cases;
|
|
namely types that are:</p>
|
|
<ol>
|
|
<li> Copyable and not movable - <tt>CopyOnly</tt>.</li>
|
|
<li> Copyable and movable - <tt>MovableCopyable</tt>.</li>
|
|
<li> Movable and not copyable - <tt>MoveOnly</tt>.</li>
|
|
</ol>
|
|
<p> and for clarification, define these two additional types as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct CopyOnly {
|
|
int val;
|
|
CopyOnly(): val(0) {}
|
|
|
|
CopyOnly(const CopyOnly &) = default;
|
|
CopyOnly & operator=(const CopyOnly &) = default;
|
|
|
|
static CopyOnly create() { return CopyOnly(); }
|
|
static void take(CopyOnly co);
|
|
};
|
|
|
|
struct MovableCopyable {
|
|
int val;
|
|
MovableCopyable(): val(0) {}
|
|
|
|
MovableCopyable(const MovableCopyable &) = default;
|
|
MovableCopyable(MovableCopyable &&) = default;
|
|
MovableCopyable & operator=(const MovableCopyable &) = default;
|
|
MovableCopyable & operator=(MovableCopyable &&) = default;
|
|
|
|
static MovableCopyable create() { return MovableCopyable(); }
|
|
static void take(MovableCopyable mc);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The generated code is shown below for <tt>CopyOnly::take</tt> (with
|
|
additional comments for when constructors and assignment operators are
|
|
called). While the code shown is C# specific, the generated constructor
|
|
and/or assignment operator calls are ultimately the same for all target
|
|
languages.</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIGEXPORT void SWIGSTDCALL CSharp_CopyOnly_take(void * jarg1) {
|
|
CopyOnly arg1 ; // (a) Default constructor
|
|
CopyOnly *argp1 ;
|
|
|
|
argp1 = (CopyOnly *)jarg1;
|
|
if (!argp1) {
|
|
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null CopyOnly", 0);
|
|
return ;
|
|
}
|
|
arg1 = *argp1; // (b) Copy assignment
|
|
CopyOnly::take(SWIG_STD_MOVE(arg1)); // (c) Copy constructor
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Note that <tt>SWIG_STD_MOVE</tt> is a macro defined as shown below
|
|
to use <tt>std::move</tt> which is only available from C++11 onwards:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#if __cplusplus >=201103L
|
|
# define SWIG_STD_MOVE(OBJ) std::move(OBJ)
|
|
#else
|
|
# define SWIG_STD_MOVE(OBJ) OBJ
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
<p> Also note:<i> (c) Copy constructor</i>. Yes, when passing by value
|
|
the copy constructor is called for all versions of C++, even C++11 and
|
|
later even though std::move is specified. It's a C++ language feature
|
|
for types that don't have move semantics!</p>
|
|
<p> The generated code for <tt>MovableCopyable::take</tt> is the same as
|
|
for <tt>CopyOnly::take</tt>, however, the C++ compiler will choose the
|
|
move constructor this time where commented<i> (c) Move constructor</i>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIGEXPORT void SWIGSTDCALL CSharp_MovableCopyable_take(void * jarg1) {
|
|
MovableCopyable arg1 ; // (a) Default constructor
|
|
MovableCopyable *argp1 ;
|
|
|
|
argp1 = (MovableCopyable *)jarg1;
|
|
if (!argp1) {
|
|
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null MovableCopyable", 0);
|
|
return ;
|
|
}
|
|
arg1 = *argp1; // (b) Copy assignment
|
|
MovableCopyable::take(SWIG_STD_MOVE(arg1)); // (c) Move constructor
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> There are two optimisation opportunities available.</p>
|
|
<ol>
|
|
<li> Remove the default constructor call with the <tt>
|
|
%feature("valuewrapper")</tt> covered in <a href="#SWIGPlus_nn19">Pass
|
|
and return by value</a> and replace it with <tt>SwigValueWrapper</tt>.</li>
|
|
<li> Apply the SWIGTYPE MOVE typemaps which are designed specifically to
|
|
implement full move semantics when passing parameters by value. They
|
|
replace the copy assignment with a call to <tt>SwigValueWrapper::reset</tt>
|
|
, which works much like <tt>std::unique_ptr::reset</tt>. These typemaps
|
|
could alternatively have replaced the copy assignment with a move
|
|
assignment, but this is not maximally optimal.</li>
|
|
</ol>
|
|
<p> Simply add the following before the <tt>MovableCopyable::take</tt>
|
|
method is parsed:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%valuewrapper MovableCopyable;
|
|
%include <swigmove.i>
|
|
%apply SWIGTYPE MOVE { MovableCopyable }
|
|
</pre>
|
|
</div>
|
|
<p> will result in this optimal code where just one move constructor is
|
|
invoked:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIGEXPORT void SWIGSTDCALL CSharp_MovableCopyable_take(void * jarg1) {
|
|
SwigValueWrapper< MovableCopyable > arg1 ; // (a) No constructors invoked
|
|
MovableCopyable *argp1 ;
|
|
|
|
argp1 = (MovableCopyable *)jarg1;
|
|
if (!argp1) {
|
|
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null MovableCopyable", 0);
|
|
return ;
|
|
}
|
|
SwigValueWrapper< MovableCopyable >::reset(arg1, argp1); // (b) No constructor or assignment operator invoked
|
|
MovableCopyable::take(SWIG_STD_MOVE(arg1)); // (c) Move constructor
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Note that <tt>SwigValueWrapper</tt> will call the destructor for the
|
|
pointer passed to it in the <tt>reset</tt> function. This pointer is
|
|
the underlying C++ object that the proxy class owns. The details aren't
|
|
shown, but the 'csin' typemap also generates C# code to ensure that the
|
|
proxy class releases ownership of the object. Please see the 'SWIGTYPE
|
|
MOVE' typemaps in the swigmove.i file provided for each target
|
|
language. Therefore full move semantics are implemented; ownership is
|
|
moved from the proxy class into the C++ layer and the net effect is the
|
|
same as using an <a href="#CPlusPlus11_rvalue_reference_inputs">rvalue
|
|
reference parameter</a> discussed earlier.</p>
|
|
<p> Lastly, let's consider the <tt>MoveOnly::take</tt> function defined
|
|
earlier. By default the generated code fails to compile as <tt>MoveOnly</tt>
|
|
does not have a copy assignment operator. SWIG is not designed to
|
|
select a different typemap automatically for move-only types and the
|
|
user must apply the SWIGTYPE MOVE typemaps to ensure that only
|
|
move-only semantics are used. However, SWIG is able to automatically
|
|
use <tt>%feature("valuewrapper")</tt> for move-only types so it is not
|
|
necessary to explicitly use this feature. So in this move-only case,
|
|
simply add the following before <tt>MoveOnly::take</tt> is parsed,
|
|
which results in the same optimal code shown above for <tt>
|
|
MovableCopyable</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <swigmove.i>
|
|
%apply SWIGTYPE MOVE { MoveOnly }
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> SWIG-4.1.0 introduced support for taking
|
|
advantage of types with move semantics and making it possible to easily
|
|
use move only types.</p>
|
|
<h3><a name="CPlusPlus11_generalized_constant_expressions">7.2.2
|
|
Generalized constant expressions</a></h3>
|
|
<p>SWIG parses and identifies the keyword <tt>constexpr</tt>, but cannot
|
|
fully utilise it. These C++ compile time constants are usable as
|
|
runtime constants from the target languages. Below shows example usage
|
|
for assigning a C++ compile time constant from a compile time constant
|
|
function:</p>
|
|
<div class="code">
|
|
<pre>
|
|
constexpr int XXX() { return 10; }
|
|
constexpr int YYY = XXX() + 100;
|
|
</pre>
|
|
</div>
|
|
<p> When either of these is used from a target language, a runtime call
|
|
is made to obtain the underlying constant.</p>
|
|
<h3><a name="CPlusPlus11_extern_template">7.2.3 Extern template</a></h3>
|
|
<p>SWIG correctly parses <tt>extern template</tt> explicit instantiation
|
|
declarations. However, this template instantiation suppression in a
|
|
translation unit has no relevance outside of the C++ compiler and so is
|
|
not used by SWIG. SWIG only uses <tt>%template</tt> for instantiating
|
|
and wrapping templates. Consider the class template below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// Class template
|
|
template class std::vector<int>; // C++03 template explicit instantiation definition in C++
|
|
extern template class std::vector<int>; // C++11 template explicit instantiation declaration (extern template)
|
|
%template(VectorInt) std::vector<int>; // SWIG template instantiation
|
|
</pre>
|
|
</div>
|
|
<p> The above result in warnings:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:2: Warning 320: Explicit template instantiation ignored.
|
|
example.i:3: Warning 327: Extern template ignored.
|
|
</pre>
|
|
</div>
|
|
<p> Similarly for the function template below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// Function template
|
|
template void Func<int>(); // C++03 template explicit instantiation definition in C++
|
|
extern template void Func<int>(); // C++11 template explicit instantiation declaration (extern template)
|
|
%template(FuncInt) Func<int>; // SWIG template instantiation
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_initializer_lists">7.2.4 Initializer lists</a></h3>
|
|
<p> Initializer lists are very much a C++ compiler construct and are not
|
|
very accessible from wrappers as they are intended for compile time
|
|
initialization of classes using the special <tt>std::initializer_list</tt>
|
|
type. SWIG detects usage of initializer lists and will emit a special
|
|
informative warning each time one is used:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:33: Warning 476: Initialization using std::initializer_list.
|
|
</pre>
|
|
</div>
|
|
<p> Initializer lists usually appear in constructors but can appear in
|
|
any function or method. They often appear in constructors which are
|
|
overloaded with alternative approaches to initializing a class, such as
|
|
the std container's push_back method for adding elements to a
|
|
container. The recommended approach then is to simply ignore the
|
|
initializer-list constructor, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%ignore Container::Container(std::initializer_list<int>);
|
|
class Container {
|
|
public:
|
|
Container(std::initializer_list<int>); // initializer-list constructor
|
|
Container();
|
|
void push_back(const int &);
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p>Alternatively you could modify the class and add another constructor
|
|
for initialization by some other means, for example by a <tt>
|
|
std::vector</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_vector.i>
|
|
class Container {
|
|
public:
|
|
Container(const std::vector<int> &);
|
|
Container(std::initializer_list<int>); // initializer-list constructor
|
|
Container();
|
|
void push_back(const int &);
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p>And then call this constructor from your target language, for
|
|
example, in Python, the following will call the constructor taking the <tt>
|
|
std::vector</tt>:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> c = Container( [1, 2, 3, 4] )
|
|
</pre>
|
|
</div>
|
|
<p> If you are unable to modify the class being wrapped, consider
|
|
ignoring the initializer-list constructor and using %extend to add in
|
|
an alternative constructor:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_vector.i>
|
|
%extend Container {
|
|
Container(const std::vector<int> &elements) {
|
|
Container *c = new Container();
|
|
for (int element : elements)
|
|
c->push_back(element);
|
|
return c;
|
|
}
|
|
}
|
|
|
|
%ignore Container::Container(std::initializer_list<int>);
|
|
|
|
class Container {
|
|
public:
|
|
Container(std::initializer_list<int>); // initializer-list constructor
|
|
Container();
|
|
void push_back(const int &);
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The above makes the wrappers look is as if the class had been
|
|
declared as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_vector.i>
|
|
class Container {
|
|
public:
|
|
Container(const std::vector<int> &);
|
|
// Container(std::initializer_list<int>); // initializer-list constructor (ignored)
|
|
Container();
|
|
void push_back(const int &);
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> <tt>std::initializer_list</tt> is simply a container that can only
|
|
be initialized at compile time. As it is just a C++ type, it is
|
|
possible to write typemaps for a target language container to map onto <tt>
|
|
std::initializer_list</tt>. However, this can only be done for a fixed
|
|
number of elements as initializer lists are not designed to be
|
|
constructed with a variable number of arguments at runtime. The example
|
|
below is a very simple approach which ignores any parameters passed in
|
|
and merely initializes with a fixed list of fixed integer values chosen
|
|
at compile time:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) std::initializer_list<int> {
|
|
$1 = {10, 20, 30, 40, 50};
|
|
}
|
|
class Container {
|
|
public:
|
|
Container(std::initializer_list<int>); // initializer-list constructor
|
|
Container();
|
|
void push_back(const int &);
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Any attempt at passing in values from the target language will be
|
|
ignored and be replaced by <tt>{10, 20, 30, 40, 50}</tt>. Needless to
|
|
say, this approach is very limited, but could be improved upon, but
|
|
only slightly. A typemap could be written to map a fixed number of
|
|
elements on to the <tt>std::initializer_list</tt>, but with values
|
|
decided at runtime. The typemaps would be target language specific.</p>
|
|
<p> Note that the default typemap for <tt>std::initializer_list</tt>
|
|
does nothing but issue the warning and hence any user supplied typemaps
|
|
will override it and suppress the warning.</p>
|
|
<h3><a name="CPlusPlus11_uniform_initialization">7.2.5 Uniform
|
|
initialization</a></h3>
|
|
<p>The curly brackets {} for member initialization are fully supported
|
|
by SWIG:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct BasicStruct {
|
|
int x;
|
|
double y;
|
|
};
|
|
|
|
struct AltStruct {
|
|
AltStruct(int x, double y) : x_{x}, y_{y} {}
|
|
|
|
int x_;
|
|
double y_;
|
|
};
|
|
|
|
BasicStruct var1{5, 3.2}; // only fills the struct components
|
|
AltStruct var2{2, 4.3}; // calls the constructor
|
|
</pre>
|
|
</div>
|
|
<p>Uniform initialization does not affect usage from the target
|
|
language, for example in Python:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> a = AltStruct(10, 142.15)
|
|
>>> a.x_
|
|
10
|
|
>>> a.y_
|
|
142.15
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_type_inference">7.2.6 Type inference</a></h3>
|
|
<p><tt>decltype()</tt> is supported with a few limitations. SWIG can
|
|
parse all uses, but can't deduce the type in every situation where a
|
|
C++ compiler can. The cases SWIG can deduce have expanded with time and
|
|
hopefully will continue to. For example, for the code</p>
|
|
<div class="code">
|
|
<pre>
|
|
int i;
|
|
decltype(i) j;
|
|
decltype(i+j) k;
|
|
</pre>
|
|
</div>
|
|
<p>SWIG is able to deduce that the variable <tt>i</tt> and the
|
|
expression <tt>i+j</tt> both have type <tt>int</tt>.</p>
|
|
<p> Using an expression for the decltype which SWIG can't handle results
|
|
in a warning:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int foo(int);
|
|
decltype(foo(0)) k; // Warning 344: Unable to deduce decltype for 'foo(0)'.
|
|
</pre>
|
|
</div>
|
|
<p> This warning should be viewed as a prompt to add in a manual ignore
|
|
of the variable/function as in most cases the generated code will not
|
|
compile. For the example above, ignore the symbol that is declared
|
|
using <tt>decltype</tt> and perhaps additionally suppress the warning
|
|
as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#pragma SWIG nowarn=SWIGWARN_CPP11_DECLTYPE
|
|
%ignore k;
|
|
</pre>
|
|
</div>
|
|
<p> If an ignore is not acceptable, a workaround is to redefine the
|
|
symbol with the actual type, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int k; // define k with the actual type
|
|
%ignore k; // ignore the real definition of k
|
|
</pre>
|
|
</div>
|
|
<p>You would typically put one of these workarounds in your interface
|
|
file before using <tt>%include</tt> to get SWIG to parse the header
|
|
which defines <tt>k</tt>.</p>
|
|
<p>SWIG supports <tt>auto</tt> as a type specifier for variables (with
|
|
the same limitations for actually deducing the type as for <tt>
|
|
decltype()</tt>), and for specifying the return type of <a href="#CPlusPlus11_lambda_functions_and_expressions">
|
|
lambdas</a> and <a href="#CPlusPlus11_alternate_function_syntax">
|
|
functions</a>.</p>
|
|
<h3><a name="CPlusPlus11_range_based_for_loop">7.2.7 Range-based
|
|
for-loop</a></h3>
|
|
<p>This feature is part of the implementation block only. SWIG ignores
|
|
it.</p>
|
|
<h3><a name="CPlusPlus11_lambda_functions_and_expressions">7.2.8 Lambda
|
|
functions and expressions</a></h3>
|
|
<p>SWIG correctly parses most of the Lambda functions syntax. For
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
auto val = [] { return something; };
|
|
auto sum = [](int x, int y) { return x+y; };
|
|
auto sum = [](int x, int y) -> int { return x+y; };
|
|
</pre>
|
|
</div>
|
|
<p>The lambda functions are removed from the wrappers for now, because
|
|
of the lack of support for closures (scope of the lambda functions) in
|
|
the target languages.</p>
|
|
<p> Lambda functions used to create variables can also be parsed, but
|
|
due to limited support of <tt>auto</tt> when the type is deduced from
|
|
the expression, the variables are simply ignored.</p>
|
|
<div class="code">
|
|
<pre>
|
|
auto six = [](int x, int y) { return x+y; }(4, 2);
|
|
</pre>
|
|
</div>
|
|
<p> Better support should be available in a later release.</p>
|
|
<h3><a name="CPlusPlus11_alternate_function_syntax">7.2.9 Alternate
|
|
function syntax</a></h3>
|
|
<p>SWIG fully supports the new definition of functions. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct SomeStruct {
|
|
int FuncName(int x, int y);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p>can now be written as in C++11:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct SomeStruct {
|
|
auto FuncName(int x, int y) -> int;
|
|
};
|
|
|
|
auto SomeStruct::FuncName(int x, int y) -> int {
|
|
return x + y;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p>The usage in the target languages remains the same, for example in
|
|
Python:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> a = SomeStruct()
|
|
>>> a.FuncName(10, 5)
|
|
15
|
|
</pre>
|
|
</div>
|
|
<p>SWIG will also deal with type inference for the return type, as per
|
|
the limitations described earlier. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
auto square(float a, float b) -> decltype(a);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_object_construction_improvement">7.2.10 Object
|
|
construction improvement</a></h3>
|
|
<p> There are three parts to object construction improvement. The first
|
|
improvement is constructor delegation such as the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class A {
|
|
public:
|
|
int a;
|
|
int b;
|
|
int c;
|
|
|
|
A() : A(10) {}
|
|
A(int aa) : A(aa, 20) {}
|
|
A(int aa, int bb) : A(aa, bb, 30) {}
|
|
A(int aa, int bb, int cc) { a=aa; b=bb; c=cc; }
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> where peer constructors can be called. SWIG handles this without any
|
|
issue.</p>
|
|
<p> The second improvement is constructor inheritance via a <tt>using</tt>
|
|
declaration. The extra constructors provided by the <tt>using</tt>
|
|
declaration will add the appropriate constructors into the target
|
|
language proxy derived classes. In the example below a wrapper for the <tt>
|
|
DerivedClass(int)</tt> constructor is added to <tt>DerivedClass</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class BaseClass {
|
|
public:
|
|
BaseClass(int iValue);
|
|
};
|
|
|
|
class DerivedClass: public BaseClass {
|
|
public:
|
|
using BaseClass::BaseClass; // Adds DerivedClass(int) constructor
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> SWIG-4.2.0 was the first version to
|
|
generate wrappers for constructors inherited via <tt>using</tt>
|
|
declarations.</p>
|
|
<p> The final part is member initialization at the site of the
|
|
declaration. This kind of initialization is handled by SWIG.</p>
|
|
<div class="code">
|
|
<pre>
|
|
class SomeClass {
|
|
public:
|
|
SomeClass() {}
|
|
explicit SomeClass(int new_value) : value(new_value) {}
|
|
|
|
int value = 5;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_explicit_overrides_final">7.2.11 Explicit
|
|
overrides and final</a></h3>
|
|
<p> The special identifiers <tt>final</tt> and <tt>override</tt> can be
|
|
used on methods and destructors, such as in the following example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct BaseStruct {
|
|
virtual void ab() const = 0;
|
|
virtual void cd();
|
|
virtual void ef();
|
|
virtual ~BaseStruct();
|
|
};
|
|
struct DerivedStruct : BaseStruct {
|
|
virtual void ab() const override;
|
|
virtual void cd() final;
|
|
virtual void ef() final override;
|
|
virtual ~DerivedStruct() override;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Classes can also be marked as final, such as</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct FinalDerivedStruct final : BaseStruct {
|
|
virtual void ab() const override;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> Final methods were supported much earlier
|
|
than final classes. SWIG-4.1.0 was the first version to support classes
|
|
marked as final.</p>
|
|
<h3><a name="CPlusPlus11_null_pointer_constant">7.2.12 Null pointer
|
|
constant</a></h3>
|
|
<p>The <tt>nullptr</tt> constant is mostly unimportant in wrappers. In
|
|
the few places it has an effect, it is treated like <tt>NULL</tt>.</p>
|
|
<h3><a name="CPlusPlus11_strongly_typed_enumerations">7.2.13 Strongly
|
|
typed enumerations</a></h3>
|
|
<p>SWIG supports strongly typed enumerations and parses the new <tt>enum
|
|
class</tt> syntax and forward declarator for the enums, such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
enum class MyEnum : unsigned int;
|
|
</pre>
|
|
</div>
|
|
<p> Strongly typed enums are often used to avoid name clashes such as
|
|
the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct Color {
|
|
enum class RainbowColors : unsigned int {
|
|
Red, Orange, Yellow, Green, Blue, Indigo, Violet
|
|
};
|
|
|
|
enum class WarmColors {
|
|
Yellow, Orange, Red
|
|
};
|
|
|
|
// Note normal enum
|
|
enum PrimeColors {
|
|
Red=100, Green, Blue
|
|
};
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> There are various ways that the target languages handle enums, so it
|
|
is not possible to precisely state how they are handled in this
|
|
section. However, generally, most scripting languages mangle in the
|
|
strongly typed enumeration's class name, but do not use any additional
|
|
mangling for normal enumerations. For example, in Python, the following
|
|
code</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
print(Color.RainbowColors_Red, Color.WarmColors_Red, Color.Red)
|
|
</pre>
|
|
</div>
|
|
<p> results in</p>
|
|
<div class="shell">
|
|
<pre>
|
|
0 2 100
|
|
</pre>
|
|
</div>
|
|
<p> The strongly typed languages often wrap normal enums into an enum
|
|
class and so treat normal enums and strongly typed enums the same. The
|
|
equivalent in Java is:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
System.out.println(Color.RainbowColors.Red.swigValue() + " " + Color.WarmColors.Red.swigValue() + " " + Color.PrimeColors.Red.swigValue());
|
|
</pre>
|
|
</div>
|
|
<p> The C++11 enum base type, such as <tt>unsigned int</tt>, in the
|
|
example above, is used by some language modules and is missing support
|
|
in others. For example, in C#, the enum base type in the example above
|
|
is used and converted into a C# <tt>uint</tt> to specify the underlying
|
|
C# enumeration type as follows:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
public enum RainbowColors : uint {
|
|
Red,
|
|
Orange,
|
|
Yellow,
|
|
Green,
|
|
Blue,
|
|
Indigo,
|
|
Violet
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_double_angle_brackets">7.2.14 Double angle
|
|
brackets</a></h3>
|
|
<p>SWIG correctly parses the symbols >> as closing the template block,
|
|
if found inside it at the top level, or as the right shift operator >>
|
|
otherwise.</p>
|
|
<div class="code">
|
|
<pre>
|
|
std::vector<std::vector<int>> myIntTable;
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_explicit_conversion_operators">7.2.15 Explicit
|
|
conversion operators</a></h3>
|
|
<p>SWIG correctly parses the keyword <tt>explicit</tt> for operators in
|
|
addition to constructors now. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class U {
|
|
public:
|
|
int u;
|
|
};
|
|
|
|
class V {
|
|
public:
|
|
int v;
|
|
};
|
|
|
|
class TestClass {
|
|
public:
|
|
//implicit converting constructor
|
|
TestClass(U const &val) { t=val.u; }
|
|
|
|
// explicit constructor
|
|
explicit TestClass(V const &val) { t=val.v; }
|
|
|
|
int t;
|
|
};
|
|
|
|
struct Testable {
|
|
// explicit conversion operator
|
|
explicit operator bool() const {
|
|
return false;
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The effect of explicit constructors and operators has little
|
|
relevance for the proxy classes as target languages don't have the same
|
|
concepts of implicit conversions as C++. Conversion operators either
|
|
with or without <tt>explicit</tt> need renaming to a valid identifier
|
|
name in order to make them available as a normal proxy method.</p>
|
|
<h3><a name="CPlusPlus11_alias_templates">7.2.16 Type alias and alias
|
|
templates</a></h3>
|
|
<p> A type alias is a statement of the form:</p>
|
|
<div class="code">
|
|
<pre>
|
|
using PFD = void (*)(double); // New introduced syntax
|
|
</pre>
|
|
</div>
|
|
<p> which is equivalent to the old style typedef:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef void (*PFD)(double); // The old style
|
|
</pre>
|
|
</div>
|
|
<p> The following is an example of an alias template:<div class="code">
|
|
<pre>
|
|
template< typename T1, typename T2, int N >
|
|
class SomeType {
|
|
public:
|
|
T1 a;
|
|
T2 b;
|
|
};
|
|
|
|
template< typename T2 >
|
|
using TypedefName = SomeType<char*, T2, 5>;
|
|
</pre>
|
|
</div></p>
|
|
<p> SWIG supports both type aliasing and alias templates. However, in
|
|
order to use an alias template, two <tt>%template</tt> directives must
|
|
be used:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%template(SomeTypeBool) SomeType<char*, bool, 5>;
|
|
%template() TypedefName<bool>;
|
|
</pre>
|
|
</div>
|
|
<p>Firstly, the actual template is instantiated with a name to be used
|
|
by the target language, as per any template being wrapped. Secondly,
|
|
the empty template instantiation, <tt>%template()</tt>, is required for
|
|
the alias template. This second requirement is necessary to add the
|
|
appropriate instantiated template type into the type system as SWIG
|
|
does not automatically instantiate templates. See the <a href="#SWIGPlus_nn30">
|
|
Templates</a> section for more general information on wrapping
|
|
templates.</p>
|
|
<h3><a name="CPlusPlus11_unrestricted_unions">7.2.17 Unrestricted unions</a>
|
|
</h3>
|
|
<p>SWIG fully supports any type inside a union even if it does not
|
|
define a trivial constructor. For example, the wrapper for the
|
|
following code correctly provides access to all members in the union:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct point {
|
|
point() {}
|
|
point(int x, int y) : x_(x), y_(y) {}
|
|
int x_, y_;
|
|
};
|
|
|
|
#include <new> // For placement 'new' in the constructor below
|
|
union P {
|
|
int z;
|
|
double w;
|
|
point p; // Illegal in C++03; legal in C++11.
|
|
// Due to the point member, a constructor definition is required.
|
|
P() {
|
|
new(&p) point();
|
|
}
|
|
} p1;
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_variadic_templates">7.2.18 Variadic templates</a>
|
|
</h3>
|
|
<p>SWIG supports the variadic templates including the <> variadic class
|
|
inheritance, variadic methods, variadic constructors and initializers.
|
|
Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
template <typename... BaseClasses> class ClassName : public BaseClasses... {
|
|
public:
|
|
ClassName(BaseClasses &&... baseClasses) : BaseClasses(baseClasses)... {}
|
|
void InstanceMethod(const BaseClasses&... baseClasses) {}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>%template</tt> directive works as expected for variable
|
|
template parameters.</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct A {
|
|
virtual void amethod();
|
|
virtual ~A();
|
|
};
|
|
struct B {
|
|
virtual void bmethod();
|
|
virtual ~B();
|
|
};
|
|
%template(ClassName0) ClassName<>
|
|
%template(ClassName1) ClassName<A>
|
|
%template(ClassName2) ClassName<A, B>
|
|
</pre>
|
|
</div>
|
|
<p> Example usage from say Python:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
cn0 = ClassName0()
|
|
cn0.InstanceMethod()
|
|
|
|
a = A()
|
|
cn1 = ClassName1(a)
|
|
cn1.amethod()
|
|
cn1.InstanceMethod(a)
|
|
|
|
b = B()
|
|
cn2 = ClassName2(a, b)
|
|
cn2.InstanceMethod(a, b)
|
|
cn2.amethod()
|
|
cn2.bmethod()
|
|
</pre>
|
|
</div>
|
|
<p>Support for the variadic <tt>sizeof()</tt> function also works:</p>
|
|
<div class="code">
|
|
<pre>
|
|
const int SIZE = sizeof...(ClassName<A, B>);
|
|
</pre>
|
|
</div>
|
|
<p> In the above example <tt>SIZE</tt> is of course wrapped as a
|
|
constant.</p>
|
|
<p><b> Compatibility note:</b> SWIG-4.2.0 was the first version to fully
|
|
support variadic templates. SWIG-3.0.0 provided initial support and was
|
|
limited to only one variadic parameter.</p>
|
|
<h3><a name="CPlusPlus11_new_char_literals">7.2.19 New character
|
|
literals</a></h3>
|
|
<p> C++11 adds support for UCS-2 and UCS-4 character literals. These
|
|
character literals are preceded by either 'u' or 'U'.</p>
|
|
<div class="code">
|
|
<pre>
|
|
char16_t a = u'a';
|
|
char32_t b = U'b';
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> SWIG-4.0.0 was the first version to
|
|
support these Universal Coded Character Set (UCS) character literals.</p>
|
|
<h3><a name="CPlusPlus11_new_string_literals">7.2.20 New string literals</a>
|
|
</h3>
|
|
<p>SWIG supports wide string and Unicode string constants and raw string
|
|
literals.</p>
|
|
<div class="code">
|
|
<pre>
|
|
// New string literals
|
|
wstring aa = L"Wide string";
|
|
const char *bb = u8"UTF-8 string";
|
|
const char16_t *cc = u"UTF-16 string";
|
|
const char32_t *dd = U"UTF-32 string";
|
|
|
|
// Raw string literals
|
|
const char *xx = ")I'm an \"ascii\" \\ string.";
|
|
const char *ee = R"XXX()I'm an "ascii" \ string.)XXX"; // same as xx
|
|
wstring ff = LR"XXX(I'm a "raw wide" \ string.)XXX";
|
|
const char *gg = u8R"XXX(I'm a "raw UTF-8" \ string.)XXX";
|
|
const char16_t *hh = uR"XXX(I'm a "raw UTF-16" \ string.)XXX";
|
|
const char32_t *ii = UR"XXX(I'm a "raw UTF-32" \ string.)XXX";
|
|
</pre>
|
|
</div>
|
|
<p> Non-ASCII string support varies quite a bit among the various target
|
|
languages though.</p>
|
|
<p> Note: There is a bug currently where SWIG's preprocessor incorrectly
|
|
parses an odd number of double quotes inside raw string literals.</p>
|
|
<h3><a name="CPlusPlus11_user_defined_literals">7.2.21 User-defined
|
|
literals</a></h3>
|
|
<p> SWIG parses the declaration of user-defined literals, that is, the <tt>
|
|
operator "" _mysuffix()</tt> function syntax.</p>
|
|
<p> Some examples are the raw literal:</p>
|
|
<div class="code">
|
|
<pre>
|
|
OutputType operator "" _myRawLiteral(const char * value);
|
|
</pre>
|
|
</div>
|
|
<p> numeric cooked literals:</p>
|
|
<div class="code">
|
|
<pre>
|
|
OutputType operator "" _mySuffixIntegral(unsigned long long);
|
|
OutputType operator "" _mySuffixFloat(long double);
|
|
</pre>
|
|
</div>
|
|
<p> and cooked string literals:</p>
|
|
<div class="code">
|
|
<pre>
|
|
OutputType operator "" _mySuffix(const char * string_values, size_t num_chars);
|
|
OutputType operator "" _mySuffix(const wchar_t * string_values, size_t num_chars);
|
|
OutputType operator "" _mySuffix(const char16_t * string_values, size_t num_chars);
|
|
OutputType operator "" _mySuffix(const char32_t * string_values, size_t num_chars);
|
|
</pre>
|
|
</div>
|
|
<p> Like other operators that SWIG parses, a warning is given about
|
|
renaming the operator in order for it to be wrapped:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:27: Warning 503: Can't wrap 'operator "" _myRawLiteral' unless renamed to a valid identifier.
|
|
</pre>
|
|
</div>
|
|
<p> If %rename is used, then it can be called like any other wrapped
|
|
method. Currently you need to specify the full declaration including
|
|
parameters for %rename:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(MyRawLiteral) operator"" _myRawLiteral(const char * value);
|
|
</pre>
|
|
</div>
|
|
<p> Or if you just wish to ignore it altogether:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%ignore operator "" _myRawLiteral(const char * value);
|
|
</pre>
|
|
</div>
|
|
<p> Note that use of user-defined literals such as the following still
|
|
give a syntax error:</p>
|
|
<div class="code">
|
|
<pre>
|
|
OutputType var1 = "1234"_suffix;
|
|
OutputType var2 = 1234_suffix;
|
|
OutputType var3 = 3.1416_suffix;
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_thread_local_storage">7.2.22 Thread-local
|
|
storage</a></h3>
|
|
<p>SWIG correctly parses the <tt>thread_local</tt> keyword. For example,
|
|
variables reachable by the current thread can be defined as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct A {
|
|
static thread_local int val;
|
|
};
|
|
thread_local int global_val;
|
|
</pre>
|
|
</div>
|
|
<p> The use of the <tt>thread_local</tt> storage specifier does not
|
|
affect the wrapping process; it does not modify the wrapper code
|
|
compared to when it is not specified. A variable will be thread local
|
|
if accessed from different threads from the target language in the same
|
|
way that it will be thread local if accessed from C++ code.</p>
|
|
<h3><a name="CPlusPlus11_defaulted_deleted">7.2.23 Explicitly defaulted
|
|
functions and deleted functions</a></h3>
|
|
<p>SWIG handles explicitly defaulted functions, that is, <tt>= default</tt>
|
|
added to a function declaration. Deleted definitions, which are also
|
|
called deleted functions, have <tt>= delete</tt> added to the function
|
|
declaration. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct NonCopyable {
|
|
NonCopyable & operator=(const NonCopyable &) = delete; /* Removes operator= */
|
|
NonCopyable(const NonCopyable &) = delete; /* Removes copy constructor */
|
|
NonCopyable() = default; /* Explicitly allows the empty constructor */
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Wrappers for deleted functions will not be available in the target
|
|
language. Wrappers for defaulted functions will of course be available
|
|
in the target language. Explicitly defaulted functions have no direct
|
|
effect for SWIG wrapping as the declaration is handled much like any
|
|
other method declaration parsed by SWIG.</p>
|
|
<p> Deleted functions are also designed to prevent implicit conversions
|
|
when calling the function. For example, the C++ compiler will not
|
|
compile any code which attempts to use an int as the type of the
|
|
parameter passed to <tt>f</tt> below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct NoInt {
|
|
void f(double i);
|
|
void f(int) = delete;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> This is a C++ compile time check and SWIG does not make any attempt
|
|
to detect if the target language is using an int instead of a double
|
|
though, so in this case it is entirely possible to pass an int instead
|
|
of a double to <tt>f</tt> from Java, Python etc.</p>
|
|
<h3><a name="CPlusPlus11_type_long_long_int">7.2.24 Type long long int</a>
|
|
</h3>
|
|
<p>SWIG correctly parses and uses the new <tt>long long</tt> type
|
|
already introduced in C99 some time ago.</p>
|
|
<h3><a name="CPlusPlus11_static_assertions">7.2.25 Static assertions</a></h3>
|
|
<p> SWIG correctly parses the new <tt>static_assert</tt> declarations
|
|
(though 3.0.12 and earlier had a bug which meant this wasn't accepted
|
|
at file scope). This is a C++ compile time directive so there isn't
|
|
anything useful that SWIG can do with it.</p>
|
|
<div class="code">
|
|
<pre>
|
|
template <typename T>
|
|
struct Check {
|
|
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
|
};
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_sizeof">7.2.26 Allow sizeof to work on members
|
|
of classes without an explicit object</a></h3>
|
|
<p> SWIG can parse the new sizeof() on types as well as on objects. For
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct A {
|
|
int member;
|
|
};
|
|
|
|
const int SIZE = sizeof(A::member); // does not work with C++03. Okay with C++11
|
|
</pre>
|
|
</div>
|
|
<p>In Python:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> SIZE
|
|
8
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_noexcept">7.2.27 Exception specifications and
|
|
noexcept</a></h3>
|
|
<p> C++11 added in the noexcept specification to exception
|
|
specifications to indicate that a function simply may or may not throw
|
|
an exception, without actually naming any exception. SWIG understands
|
|
these, although there isn't any useful way that this information can be
|
|
taken advantage of by target languages, so it is as good as ignored
|
|
during the wrapping process. Below are some examples of noexcept in
|
|
function declarations:</p>
|
|
<div class="code">
|
|
<pre>
|
|
static void noex1() noexcept;
|
|
int noex2(int) noexcept(true);
|
|
int noex3(int, bool) noexcept(false);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_alignment">7.2.28 Control and query object
|
|
alignment</a></h3>
|
|
<p> An <tt>alignof</tt> operator is used mostly within C++ to return
|
|
alignment in number of bytes, but could be used to initialize a
|
|
variable as shown below. The variable's value will be available for
|
|
access by the target language as any other variable's compile time
|
|
initialised value.<div class="code">
|
|
<pre>
|
|
const int align1 = alignof(A::member);
|
|
</pre>
|
|
</div></p>
|
|
<p> The <tt>alignas</tt> specifier for variable alignment is not yet
|
|
supported. Example usage:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct alignas(16) S {
|
|
int num;
|
|
};
|
|
alignas(double) unsigned char c[sizeof(double)];
|
|
</pre>
|
|
</div>
|
|
<p> Use the preprocessor to work around this for now:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#define alignas(T)
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_attributes">7.2.29 Attributes</a></h3>
|
|
<p> Attributes such as those shown below, are supported since SWIG 4.1.0
|
|
but are currently crudely ignored by the parser's tokeniser so they
|
|
have no effect on SWIG's code generation.</p>
|
|
<div class="code">
|
|
<pre>
|
|
int [[attr1]] i [[attr2, attr3]];
|
|
|
|
[[noreturn, nothrow]] void f [[noreturn]] ();
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_ref_qualifiers">7.2.30 Methods with
|
|
ref-qualifiers</a></h3>
|
|
<p> C++11 non-static member functions can be declared with
|
|
ref-qualifiers. Member functions declared with a <tt>&</tt> lvalue
|
|
ref-qualifiers are wrapped like any other function without
|
|
ref-qualifiers. Member functions declared with a <tt>&&</tt> rvalue
|
|
ref-qualifiers are ignored by default as they are unlikely to be
|
|
required from non-C++ languages where the concept of<i> rvalue-ness</i>
|
|
for the implied *this pointer does not apply. The warning is hidden by
|
|
default, but can be displayed as described in the section on <a href="#Warnings_nn4">
|
|
Enabling extra warnings</a>.</p>
|
|
<p> Consider:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct RQ {
|
|
void m1(int x) &;
|
|
void m2(int x) &&;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The only wrapped method will be the lvalue ref-qualified method <tt>
|
|
m1</tt> and if SWIG is run with the <tt>-Wextra</tt> command-line
|
|
option, the following warning will be issued indicating <tt>m2</tt> is
|
|
not wrapped:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:7: Warning 405: Method with rvalue ref-qualifier m2(int) && ignored.
|
|
</pre>
|
|
</div>
|
|
<p> If you unignore the method as follows, wrappers for <tt>m2</tt> will
|
|
be generated:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("ignore", "0") RQ::m2(int x) &&;
|
|
struct RQ {
|
|
void m1(int x) &;
|
|
void m2(int x) &&;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Inspection of the generated C++ code, will show that <tt>std::move</tt>
|
|
is used on the instance of the <tt>RQ *</tt> class:</p>
|
|
<div class="code">
|
|
<pre>
|
|
RQ *arg1 = (RQ *) 0 ;
|
|
int arg2 ;
|
|
|
|
arg1 = ...marshalled from target language...
|
|
arg2 = ...marshalled from target language...
|
|
|
|
std::move(*arg1).m2(arg2);
|
|
</pre>
|
|
</div>
|
|
<p> This will compile but when run, the move effects may not be what you
|
|
want. As stated earlier, rvalue ref-qualifiers aren't really applicable
|
|
outside the world of C++. However, if you really know what you are
|
|
doing, full control over the call to the method is possible via the
|
|
low-level "action" feature. This feature completely replaces the call
|
|
to the underlying function, that is, the last line in the snippet of
|
|
code above.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("ignore", "0") RQ::m2(int x) &&;
|
|
%feature("action") RQ::m2(int x) && %{
|
|
RQ().m2(arg2);
|
|
%}
|
|
struct RQ {
|
|
void m1(int x) &;
|
|
void m2(int x) &&;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> resulting in:</p>
|
|
<div class="code">
|
|
<pre>
|
|
RQ *arg1 = (RQ *) 0 ;
|
|
int arg2 ;
|
|
|
|
arg1 = ...marshalled from target language...
|
|
arg2 = ...marshalled from target language...
|
|
|
|
RQ().m2(arg2);
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> SWIG-4.0.0 was the first version to
|
|
support ref-qualifiers.</p>
|
|
<h2><a name="CPlusPlus11_standard_library_changes">7.3 Standard library
|
|
changes</a></h2>
|
|
<h3><a name="CPlusPlus11_threading_facilities">7.3.1 Threading
|
|
facilities</a></h3>
|
|
<p>SWIG does not currently wrap or use any of the new threading classes
|
|
introduced (thread, mutex, locks, condition variables, task). The main
|
|
reason is that SWIG target languages offer their own threading
|
|
facilities so there is limited use for them.</p>
|
|
<h3><a name="CPlusPlus11_tuple_types">7.3.2 Tuple types</a></h3>
|
|
<p> SWIG does not provide library files for the new tuple types yet.
|
|
Variadic template support requires further work to provide substantial
|
|
tuple wrappers.</p>
|
|
<h3><a name="CPlusPlus11_hash_tables">7.3.3 Hash tables</a></h3>
|
|
<p> The new hash tables in the STL are <tt>unordered_set</tt>, <tt>
|
|
unordered_multiset</tt>, <tt>unordered_map</tt>, <tt>unordered_multimap</tt>
|
|
. These are not available in all target languages. Any missing support
|
|
can in principle be easily implemented by adapting the current STL
|
|
containers.</p>
|
|
<h3><a name="CPlusPlus11_regular_expressions">7.3.4 Regular expressions</a>
|
|
</h3>
|
|
<p> While SWIG could provide wrappers for the new C++11 regular
|
|
expressions classes, there is little need as the target languages have
|
|
their own regular expression facilities.</p>
|
|
<h3><a name="CPlusPlus11_general_purpose_smart_pointers">7.3.5
|
|
General-purpose smart pointers</a></h3>
|
|
<p> SWIG provides special smart pointer handling for <tt>std::shared_ptr</tt>
|
|
in the same way it has support for <tt>boost::shared_ptr</tt>. Please
|
|
see the <a href="#Library_std_shared_ptr">shared_ptr smart pointer</a>
|
|
and <a href="#Library_std_unique_ptr">unique_ptr smart pointer</a>
|
|
library sections. There is no special smart pointer handling available
|
|
for <tt>std::weak_ptr</tt>.</p>
|
|
<h3><a name="CPlusPlus11_extensible_random_number_facility">7.3.6
|
|
Extensible random number facility</a></h3>
|
|
<p>This feature extends and standardizes the standard library only and
|
|
does not affect the C++ language nor SWIG.</p>
|
|
<h3><a name="CPlusPlus11_wrapper_reference">7.3.7 Wrapper reference</a></h3>
|
|
<p> Wrapper references are similar to normal C++ references but are
|
|
copy-constructible and copy-assignable. They could conceivably be used
|
|
in public APIs. There is no special support for <tt>
|
|
std::reference_wrapper</tt> in SWIG though. Users would need to write
|
|
their own typemaps if wrapper references are being used and these would
|
|
be similar to the plain C++ reference typemaps.</p>
|
|
<h3><a name="CPlusPlus11_polymorphous_wrappers_for_function_objects">
|
|
7.3.8 Polymorphic wrappers for function objects</a></h3>
|
|
<p> SWIG supports functor classes in a few languages in a very natural
|
|
way. However nothing is provided yet for the new <tt>std::function</tt>
|
|
template. SWIG will parse usage of the template like any other
|
|
template.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(__call__) Test::operator(); // Default renaming used for Python
|
|
|
|
struct Test {
|
|
bool operator()(int x, int y); // function object
|
|
};
|
|
|
|
#include <functional>
|
|
std::function<void (int, int)> pF = Test; // function template wrapper
|
|
|
|
</pre>
|
|
</div>
|
|
<p> Example of supported usage of the plain functor from Python is shown
|
|
below. It does not involve <tt>std::function</tt>.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
t = Test()
|
|
b = t(1, 2) # invoke C++ function object
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_type_traits_for_metaprogramming">7.3.9 Type
|
|
traits for metaprogramming</a></h3>
|
|
<p>The type_traits functions to support C++ metaprogramming is useful at
|
|
compile time and is aimed specifically at C++ development:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#include <type_traits>
|
|
|
|
// First way of operating.
|
|
template< bool B > struct algorithm {
|
|
template< class T1, class T2 > static int do_it(T1 &, T2 &) { /*...*/ return 1; }
|
|
};
|
|
|
|
// Second way of operating.
|
|
template<> struct algorithm<true> {
|
|
template< class T1, class T2 > static int do_it(T1, T2) { /*...*/ return 2; }
|
|
};
|
|
|
|
// Instantiating 'elaborate' will automatically instantiate the correct way to operate, depending on the types used.
|
|
template< class T1, class T2 > int elaborate(T1 A, T2 B) {
|
|
// Use the second way only if 'T1' is an integer and if 'T2' is a floating point,
|
|
// otherwise use the first way.
|
|
return algorithm< std::is_integral<T1>::value && std::is_floating_point<T2>::value >::do_it(A, B);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> SWIG correctly parses the template specialization, template types
|
|
etc. However, metaprogramming and the additional support in the
|
|
type_traits header is really for compile time and is not much use at
|
|
runtime for the target languages. For example, as SWIG requires
|
|
explicit instantiation of templates via <tt>%template</tt>, there isn't
|
|
much that <tt>std::is_integral<int></tt> is going to provide by itself.
|
|
However, template functions using such metaprogramming techniques might
|
|
be useful to wrap. For example, the following instantiations could be
|
|
made:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%template(Elaborate) elaborate<int, int>;
|
|
%template(Elaborate) elaborate<int, double>;
|
|
</pre>
|
|
</div>
|
|
<p> Then the appropriate algorithm can be called for the subset of types
|
|
given by the above <tt>%template</tt> instantiations from a target
|
|
language, such as Python:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> Elaborate(0, 0)
|
|
1
|
|
>>> Elaborate(0, 0.0)
|
|
2
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">
|
|
7.3.10 Uniform method for computing return type of function objects</a></h3>
|
|
<p> The new <tt>std::result_of</tt> class introduced in the <functional>
|
|
header provides a generic way to obtain the return type of a function
|
|
type via <tt>std::result_of::type</tt>. There isn't any library
|
|
interface file to support this type. With a bit of work, SWIG will
|
|
deduce the return type of functions when used in <tt>std::result_of</tt>
|
|
using the approach shown below. The technique basically forward
|
|
declares the <tt>std::result_of</tt> template class, then partially
|
|
specializes it for the function types of interest. SWIG will use the
|
|
partial specialization and hence correctly use the <tt>
|
|
std::result_of::type</tt> provided in the partial specialization.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%inline %{
|
|
#include <functional>
|
|
typedef double(*fn_ptr)(double);
|
|
%}
|
|
|
|
namespace std {
|
|
// Forward declaration of result_of
|
|
template<typename Func> struct result_of;
|
|
// Add in a partial specialization of result_of
|
|
template<> struct result_of< fn_ptr(double) > {
|
|
typedef double type;
|
|
};
|
|
}
|
|
|
|
%template() std::result_of< fn_ptr(double) >;
|
|
|
|
%inline %{
|
|
|
|
double square(double x) {
|
|
return (x * x);
|
|
}
|
|
|
|
template<class Fun, class Arg>
|
|
typename std::result_of<Fun(Arg)>::type test_result_impl(Fun fun, Arg arg) {
|
|
return fun(arg);
|
|
}
|
|
%}
|
|
|
|
%template(test_result) test_result_impl< fn_ptr, double >;
|
|
%constant double (*SQUARE)(double) = square;
|
|
</pre>
|
|
</div>
|
|
<p> Note the first use of <tt>%template</tt> which SWIG requires to
|
|
instantiate the template. The empty template instantiation suffices as
|
|
no proxy class is required for <tt>std::result_of<Fun(Arg)>::type</tt>
|
|
as this type is really just a <tt>double</tt>. The second <tt>%template</tt>
|
|
instantiates the template function which is being wrapped for use as a
|
|
callback. The <tt>%constant</tt> can then be used for any callback
|
|
function as described in <a href="#SWIG_nn30">Pointers to functions and
|
|
callbacks</a>.</p>
|
|
<p> Example usage from Python should give the not too surprising result:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> test_result(SQUARE, 5.0)
|
|
25.0
|
|
</pre>
|
|
</div>
|
|
<p> Phew, that is a lot of hard work to get a callback working. You
|
|
could just go with the more attractive option of just using <tt>double</tt>
|
|
as the return type in the function declaration instead of <tt>result_of</tt>
|
|
!</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="CPlusPlus14">8 SWIG and C++14</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#CPlusPlus14_introduction">Introduction</a></li>
|
|
<li><a href="#CPlusPlus14_core_language_changes">Core language changes</a>
|
|
<ul>
|
|
<li><a href="#CPlusPlus14_binary_literals">Binary integer literals</a></li>
|
|
<li><a href="#CPlusPlus14_return_type_deduction">Return type deduction</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#CPlusPlus14_standard_library_changes">Standard library
|
|
changes</a></li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<h2><a name="CPlusPlus14_introduction">8.1 Introduction</a></h2>
|
|
<p>This chapter gives you a brief overview about the SWIG implementation
|
|
of the C++14 standard. There isn't much in C++14 that affects SWIG,
|
|
however, work has only just begun on adding C++14 support.</p>
|
|
<p><b> Compatibility note:</b> SWIG-4.0.0 is the first version to
|
|
support any C++14 features.</p>
|
|
<h2><a name="CPlusPlus14_core_language_changes">8.2 Core language
|
|
changes</a></h2>
|
|
<h3><a name="CPlusPlus14_binary_literals">8.2.1 Binary integer literals</a>
|
|
</h3>
|
|
<p> C++14 added binary integer literals and SWIG supports these.
|
|
Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int b = 0b101011;
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus14_return_type_deduction">8.2.2 Return type
|
|
deduction</a></h3>
|
|
<p> C++14 added the ability to specify <tt>auto</tt> for the return type
|
|
of a function and have the compiler deduce it from the body of the
|
|
function (in C++11 you had to explicitly specify a trailing return type
|
|
if you used <tt>auto</tt> for the return type).</p>
|
|
<p> SWIG parses these types of functions, but with one significant
|
|
limitation: SWIG can't actually deduce the return type! If you want to
|
|
wrap such a function you will need to tell SWIG the return type
|
|
explicitly.</p>
|
|
<p> The trick for specifying the return type is to use <tt>%ignore</tt>
|
|
to tell SWIG to ignore the function with the deduced return type, but
|
|
first provide SWIG with an alternative declaration of the function with
|
|
an explicit return type. The generated wrapper will wrap this
|
|
alternative declaration, and the call in the wrapper to the function
|
|
will call the actual declaration. Here is an actual example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
std::tuple<int, int> va_static_cast();
|
|
%ignore va_static_cast();
|
|
#pragma SWIG nowarn=SWIGWARN_CPP14_AUTO
|
|
|
|
%inline %{
|
|
#include <tuple>
|
|
|
|
auto va_static_cast() {
|
|
return std::make_tuple(0, 0);
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> For member methods the trick is to use <tt>%extend</tt> to redeclare
|
|
the method and call it as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%extend X {
|
|
const char * a() const { return $self->a(); }
|
|
}
|
|
%inline %{
|
|
struct X {
|
|
auto a() const {
|
|
return "a string";
|
|
}
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> SWIG-4.2.0 first introduced support for
|
|
functions declared with an auto return without a trailing return type.</p>
|
|
<h2><a name="CPlusPlus14_standard_library_changes">8.3 Standard library
|
|
changes</a></h2>
|
|
<HR NOSHADE>
|
|
<h1><a name="CPlusPlus17">9 SWIG and C++17</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#CPlusPlus17_introduction">Introduction</a></li>
|
|
<li><a href="#CPlusPlus17_core_language_changes">Core language changes</a>
|
|
<ul>
|
|
<li><a href="#CPlusPlus17_nested_namespaces">Nested namespace
|
|
definitions</a></li>
|
|
<li><a href="#CPlusPlus17_u8_char_literals">UTF-8 character literals</a></li>
|
|
<li><a href="#CPlusPlus17_hexadecimal_floating_literals">Hexadecimal
|
|
floating literals</a></li>
|
|
<li><a href="#CPlusPlus17_fold_expressions">Fold expressions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#CPlusPlus17_standard_library_changes">Standard library
|
|
changes</a></li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<h2><a name="CPlusPlus17_introduction">9.1 Introduction</a></h2>
|
|
<p>This chapter gives you a brief overview about the SWIG implementation
|
|
of the C++17 standard. There isn't much in C++17 that affects SWIG,
|
|
however, work has only just begun on adding C++17 support.</p>
|
|
<p><b> Compatibility note:</b> SWIG-4.0.0 is the first version to
|
|
support any C++17 features.</p>
|
|
<h2><a name="CPlusPlus17_core_language_changes">9.2 Core language
|
|
changes</a></h2>
|
|
<h3><a name="CPlusPlus17_nested_namespaces">9.2.1 Nested namespace
|
|
definitions</a></h3>
|
|
<p> C++17 offers a more concise syntax for defining namespaces. SWIG has
|
|
support for nested namespace definitions such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
namespace A::B::C {
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> This is the equivalent to the C++98 namespace definitions:</p>
|
|
<div class="code">
|
|
<pre>
|
|
namespace A {
|
|
namespace B {
|
|
namespace C {
|
|
...
|
|
}
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus17_u8_char_literals">9.2.2 UTF-8 character
|
|
literals</a></h3>
|
|
<p> C++17 added UTF-8 (u8) character literals. These are of type char.
|
|
Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
char a = u8'a';
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus17_hexadecimal_floating_literals">9.2.3
|
|
Hexadecimal floating literals</a></h3>
|
|
<p> C++17 added hexadecimal floating literals. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
double f = 0xF.68p2;
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CPlusPlus17_fold_expressions">9.2.4 Fold expressions</a></h3>
|
|
<p> C++17 added template fold expressions. SWIG 4.3.0 and later support
|
|
parsing these with a few restrictions. Unary left fold expressions are
|
|
not supported currently. Also the same restrictions that apply to other
|
|
expressions apply here too.</p>
|
|
<h2><a name="CPlusPlus17_standard_library_changes">9.3 Standard library
|
|
changes</a></h2>
|
|
<HR NOSHADE>
|
|
<h1><a name="CPlusPlus20">10 SWIG and C++20</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#CPlusPlus20_introduction">Introduction</a></li>
|
|
<li><a href="#CPlusPlus20_core_language_changes">Core language changes</a>
|
|
<ul>
|
|
<li><a href="#CPlusPlus20_spaceship_operator">Spaceship operator</a></li>
|
|
<li><a href="#CPlusPlus20_lambda_templates">Lambda templates</a></li>
|
|
<li><a href="#CPlusPlus20_constexpr_destructors">Constexpr destructors</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#CPlusPlus20_preprocessor_changes">Preprocessor changes</a>
|
|
<ul>
|
|
<li><a href="#CPlusPlus20_va_opt">__VA_OPT__()</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#CPlusPlus20_standard_library_changes">Standard library
|
|
changes</a></li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<h2><a name="CPlusPlus20_introduction">10.1 Introduction</a></h2>
|
|
<p>This chapter gives you a brief overview about the SWIG implementation
|
|
of the C++20 standard. Work has only just begun on adding C++20
|
|
support.</p>
|
|
<p><b> Compatibility note:</b> SWIG-4.1.0 is the first version to
|
|
support any C++20 features.</p>
|
|
<h2><a name="CPlusPlus20_core_language_changes">10.2 Core language
|
|
changes</a></h2>
|
|
<h3><a name="CPlusPlus20_spaceship_operator">10.2.1 Spaceship operator</a>
|
|
</h3>
|
|
<p> SWIG supports the spaceship operator <tt><=></tt> in constant
|
|
expressions. To simplify handling of the return value type, it is
|
|
currently treated as an integer rather than <tt>std::strong_ordering</tt>
|
|
, etc. In practice we think that should do the right thing in most
|
|
cases.</p>
|
|
<p> SWIG also recognises <tt>operator<=></tt> which can be wrapped if
|
|
renamed. There is not currently any default renaming for the operator
|
|
or any attempt to automatically map it to a three-way comparison
|
|
operator in any of the target languages.</p>
|
|
<h3><a name="CPlusPlus20_lambda_templates">10.2.2 Lambda templates</a></h3>
|
|
<p> SWIG should parse lambda templates, but like <a href="#CPlusPlus11_lambda_functions_and_expressions">
|
|
non-templated lambdas</a> they aren't currently wrapped.</p>
|
|
<h3><a name="CPlusPlus20_constexpr_destructors">10.2.3 Constexpr
|
|
destructors</a></h3>
|
|
<p> Destructors that are declared <tt>constexpr</tt> are parsed and
|
|
handled like any other constructor. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class DtorA {
|
|
public:
|
|
constexpr ~DtorA() {}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<h2><a name="CPlusPlus20_preprocessor_changes">10.3 Preprocessor changes</a>
|
|
</h2>
|
|
<h3><a name="CPlusPlus20_va_opt">10.3.1 __VA_OPT__()</a></h3>
|
|
<p> Support for <tt>__VA_OPT__()</tt> was added in SWIG 4.3.0.</p>
|
|
<h2><a name="CPlusPlus20_standard_library_changes">10.4 Standard library
|
|
changes</a></h2>
|
|
<HR NOSHADE>
|
|
<h1><a name="Preprocessor">11 Preprocessing</a></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">Variadic Macros</a></li>
|
|
<li><a href="#Preprocessor_delimiters">Preprocessing and delimiters</a>
|
|
<ul>
|
|
<li><a href="#Preprocessor_nn8">Preprocessing and %{ ... %} & " ... "
|
|
delimiters</a></li>
|
|
<li><a href="#Preprocessor_nn9">Preprocessing and { ... } delimiters</a></li>
|
|
</ul>
|
|
</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>
|
|
<li><a href="#Preprocessor_trigraphs">Trigraphs</a></li>
|
|
<li><a href="#Preprocessor_digraphs">Digraphs</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">11.1 File inclusion</a></h2>
|
|
<p> To include another file into a SWIG interface, use the <tt>%include</tt>
|
|
directive like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include "cpointer.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">11.2 File imports</a></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">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">11.3 Conditional
|
|
Compilation</a></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.</p>
|
|
<p> SWIG's preprocessor conditionals support the standard C/C++
|
|
preprocessor integer expressions. As a SWIG-specific extension, string
|
|
equality and inequality tests are also supported, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#if defined __cplusplus && (#__VA_ARGS__ != "" || #TYPE == "void")
|
|
</pre>
|
|
</div>
|
|
<p> 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>
|
|
SWIG_VERSION Hexadecimal (binary-coded decimal) number containing SWIG version,
|
|
such as 0x010311 (corresponding to SWIG-1.3.11).
|
|
|
|
SWIGCSHARP Defined when using C#
|
|
SWIGD Defined when using D
|
|
SWIGGO Defined when using Go
|
|
SWIGGUILE Defined when using Guile
|
|
SWIGJAVA Defined when using Java
|
|
SWIGJAVASCRIPT Defined when using Javascript
|
|
SWIG_JAVASCRIPT_JSC Defined when using Javascript with -jsc
|
|
SWIG_JAVASCRIPT_V8 Defined when using Javascript with -v8 or -node
|
|
SWIG_JAVASCRIPT_NAPI Defined when using Javascript with -napi
|
|
SWIGLUA Defined when using Lua
|
|
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 (any version)
|
|
SWIGPHP7 Defined when using PHP 7 or later (with a compatible C API)
|
|
SWIGPYTHON Defined when using Python
|
|
SWIGR Defined when using R
|
|
SWIGRUBY Defined when using Ruby
|
|
SWIGSCILAB Defined when using Scilab
|
|
SWIGTCL Defined when using Tcl
|
|
SWIGXML Defined when using XML
|
|
</pre>
|
|
</div>
|
|
<p> SWIG also defines <tt>SWIG_VERSION</tt> and a target language macro
|
|
in the generated wrapper file (since SWIG 4.1.0 - in older versions
|
|
these were defined for some target languages but this wasn't
|
|
consistent). Best practice is to use SWIG-time conditional checks
|
|
because that results in smaller generated wrapper sources.</p>
|
|
<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 ISO C/C++
|
|
__cplusplus Defined when -c++ option used, value controlled by <tt>-std=c++NN</tt>
|
|
__STDC_VERSION__ May be defined when -c++ option is not used, value controlled by <tt>-std=cNN</tt>
|
|
</pre>
|
|
</div>
|
|
<p> Since SWIG 4.2.0, <tt>__STDC__</tt> is defined to <tt>1</tt> to
|
|
match the behaviour of ISO C/C++ compilers. Before this SWIG defined it
|
|
to have an empty value.</p>
|
|
<p> Since SWIG 4.2.0, <tt>__cplusplus</tt> is defined to <tt>199711L</tt>
|
|
(the value for C++98) by default. Before this SWIG always defined it to
|
|
have the<b> value</b> <tt>__cplusplus</tt>.</p>
|
|
<p> Since SWIG 4.2.0, SWIG supports command line options <tt>-std=cNN</tt>
|
|
and <tt>-std=c++NN</tt> to specify the C/C++ standards version. The
|
|
only effect of these options is to set appropriate values for <tt>
|
|
__STDC_VERSION__</tt> and <tt>__cplusplus</tt> respectively, which is
|
|
useful if you're wrapping headers which have preprocessor checks based
|
|
on their values.</p>
|
|
<p> If your code requires these macros to be set to a version of the
|
|
standard that is not a final official version, or one that SWIG is not
|
|
yet aware of, you can simply redefine the appropriate macro to an
|
|
alternative value at the top of your interface file, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#undef __cplusplus
|
|
#define __cplusplus 202211L
|
|
</pre>
|
|
</div>
|
|
<p> The following are language specific symbols that might be defined:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIG_D_VERSION Unsigned integer target version when using D
|
|
SWIGGO_CGO Defined when using Go for cgo
|
|
SWIGGO_GCCGO Defined when using Go for gccgo
|
|
SWIGGO_INTGO_SIZE Size of the Go type int when using Go (32 or 64)
|
|
SWIGPYTHON_BUILTIN Defined when using Python with -builtin
|
|
SWIG_RUBY_AUTORENAME Defined when using Ruby with -autorename
|
|
</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.</p>
|
|
<h2><a name="Preprocessor_nn5">11.4 Macro Expansion</a></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 ISOC_(args) (args)
|
|
#else
|
|
#define ISOC_(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">11.5 SWIG Macros</a></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">11.6 Variadic Macros</a></h2>
|
|
<p> SWIG-1.3.12 and newer releases support variadic preprocessor macros
|
|
which were standardised by C99 and C++11. 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> The variable arguments can be empty. However, this often results in
|
|
an extra comma (<tt>,</tt>) and syntax error in the resulting
|
|
expansion. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
DEBUGF("hello"); --> fprintf(stderr, "hello", );
|
|
</pre>
|
|
</div>
|
|
<p> C++20 and C23 added <tt>__VA_OPT__()</tt> as a solution to this,
|
|
which SWIG 4.3.0 added support for. <tt>__VA_OPT__()</tt> expands to
|
|
its argument if the variable arguments contain any tokens, and to
|
|
nothing otherwise. It can be used to solve the problem above like so:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#define DEBUGF(fmt, ...) fprintf(stderr, fmt __VA_OPT__(,) __VA_ARGS__)
|
|
</pre>
|
|
</div>
|
|
<p> An early non-standardised solution to this problem which gave a
|
|
special meaning to the token sequence <tt>, ## __VA_ARGS__</tt> is
|
|
supported by several C and C++ compilers, and also by SWIG 4.3.0 and
|
|
later (it was documented as supported by earlier SWIG versions, but
|
|
didn't actually work in at least SWIG 2.x and 3.x). Using this feature
|
|
you can get rid of the extra comma 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, which specify a name
|
|
for the variable arguments instead of using <tt>__VA_ARGS__</tt>. For
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#define DEBUGF(fmt, args...) fprintf(stdout, fmt, args)
|
|
</pre>
|
|
</div>
|
|
<p> SWIG supports <tt>__VA_OPT__()</tt> in combination with GNU-style
|
|
variadic macros (following the lead of GCC and clang which also support
|
|
this, albeit with a warning by default).</p>
|
|
<h2><a name="Preprocessor_delimiters">11.7 Preprocessing and delimiters</a>
|
|
</h2>
|
|
<p> The preprocessor handles { }, " " and %{ %} delimiters differently.</p>
|
|
<h3><a name="Preprocessor_nn8">11.7.1 Preprocessing and %{ ... %} & "
|
|
... " delimiters</a></h3>
|
|
<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>
|
|
<h3><a name="Preprocessor_nn9">11.7.2 Preprocessing and { ... }
|
|
delimiters</a></h3>
|
|
<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">11.8 Preprocessor and
|
|
Typemaps</a></h2>
|
|
<p> <a href="#Typemaps">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">11.9 Viewing preprocessor output</a></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>
|
|
option 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">11.10 The #error and #warning
|
|
directives</a></h2>
|
|
<p> SWIG supports the standard <tt>#warning</tt> and <tt>#error</tt>
|
|
preprocessor directives. The <tt>#warning</tt> directive will cause
|
|
SWIG to issue a warning then continue processing. It was standardised
|
|
in C++23 and C23, and has been widely supported as an extension by most
|
|
C and C++ compilers for a long time. 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>
|
|
<h2><a name="Preprocessor_trigraphs">11.11 Trigraphs</a></h2>
|
|
<p> SWIG's preprocessor does not implement trigraphs (such as <tt>??!</tt>
|
|
being mapped to <tt>|</tt>). They are very rarely used deliberately but
|
|
these character sequences sometimes occur in code where they aren't
|
|
intended as trigraphs. Compilers typically don't enable trigraph
|
|
support by default, and they've been removed in C++17 and C23.</p>
|
|
<h2><a name="Preprocessor_digraphs">11.12 Digraphs</a></h2>
|
|
<p> SWIG's preprocessor does not currently implement digraphs (such as <tt>
|
|
<%</tt> being an alternative way to write the token <tt>{</tt>). These
|
|
are standard in C++ and C95, but they're intended to support working
|
|
with code on systems with very restricted character sets which are
|
|
really rare these days so digraphs just don't seem to be used in
|
|
practice.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Library">12 SWIG library</a></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_argcargv">argcargv.i</a></li>
|
|
<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 a string with length</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_c_standard_library">C standard library</a>
|
|
<ul>
|
|
<li><a href="#Library_complex">Complex floating types</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Library_stl_cpp_library">STL/C++ library</a>
|
|
<ul>
|
|
<li><a href="#Library_std_string">std::string</a></li>
|
|
<li><a href="#Library_std_string_view">std::string_view</a></li>
|
|
<li><a href="#Library_std_vector">std::vector</a></li>
|
|
<li><a href="#Library_stl_exceptions">STL exceptions</a></li>
|
|
<li><a href="#Library_std_shared_ptr">shared_ptr smart pointer</a>
|
|
<ul>
|
|
<li><a href="#Library_shared_ptr_basics">shared_ptr basics</a></li>
|
|
<li><a href="#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
|
|
</li>
|
|
<li><a href="#Library_shared_ptr_overloading">shared_ptr and method
|
|
overloading</a></li>
|
|
<li><a href="#Library_shared_ptr_templates">shared_ptr and templates</a></li>
|
|
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Library_std_unique_ptr">unique_ptr smart pointer</a>
|
|
<ul>
|
|
<li><a href="#Library_std_unique_ptr_by_value">unique_ptr passed by
|
|
value</a></li>
|
|
<li><a href="#Library_std_unique_ptr_by_ref">unique_ptr passed by
|
|
reference</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Library_std_auto_ptr">auto_ptr smart pointer</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Library_nn16">Utility Libraries</a>
|
|
<ul>
|
|
<li><a href="#Library_nn17">exception.i</a></li>
|
|
<li><a href="#Library_attributes">attribute.i</a>
|
|
<ul>
|
|
<li><a href="#Library_attribute_templates">%attribute and C++ templates</a>
|
|
</li>
|
|
</ul>
|
|
</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">12.1 The %include directive and library search
|
|
path</a></h2>
|
|
<p> Library files are included using the <tt>%include</tt> directive.
|
|
When searching for files, directories are searched in the following
|
|
order:</p>
|
|
<ol>
|
|
<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>
|
|
</ol>
|
|
<p> Within directories mentioned in points 3-5, 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">12.2 C arrays and pointers</a></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_argcargv">12.2.1 argcargv.i</a></h3>
|
|
<p> The argcargv.i library is a simple library providing multi-argument
|
|
typemaps for handling C argc argv command line argument C string
|
|
arrays. The <tt>argc</tt> parameter contains the argument count and <tt>
|
|
argv</tt> contains the argument vector array.</p>
|
|
<p> This library provides the following multi-argument typemap:</p>
|
|
<p><b> <tt>(int ARGC, char **ARGV)</tt></b></p>
|
|
<p> Apply this multi-argument typemap to your use case, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
|
|
|
|
int mainApp(size_t argc, const char **argv);
|
|
</pre>
|
|
</div>
|
|
<p> then from Ruby:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
$args = ["myarg1", "myarg2"]
|
|
mainApp(args);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Library_nn4">12.2.2 cpointer.i</a></h3>
|
|
<p> The <tt>cpointer.i</tt> module defines macros that can be 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">12.2.3 carrays.i</a></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(size_t 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, size_t index)</tt></p>
|
|
<div class="indent">
|
|
<p> Returns the value <tt>ary[index]</tt>.</p>
|
|
</div>
|
|
<p> <tt>void name_setitem(type *ary, size_t 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="targetlang">
|
|
<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(size_t nelements); // Create an array
|
|
~name(); // Delete array
|
|
type getitem(size_t index); // Return item
|
|
void setitem(size_t 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="targetlang">
|
|
<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>.
|
|
SWIG's default handling of these types is to handle them as character
|
|
strings and the two macros do not do enough to change this.</p>
|
|
<h3><a name="Library_nn6">12.2.4 cmalloc.i</a></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">12.2.5 cdata.i</a></h3>
|
|
<p> The <tt>cdata.i</tt> module defines functions for converting raw C
|
|
data to and from a target language type. The target language type is
|
|
either:</p>
|
|
<ul>
|
|
<li> A string for the scripting languages. The scripting language must
|
|
support strings with embedded binary data in order for this to work.</li>
|
|
<li> A byte array for the statically typed languages; namely, <tt>byte[]</tt>
|
|
for C# and Java, <tt>ubyte[]</tt> for D, <tt>[]byte</tt> for Go.</li>
|
|
</ul>
|
|
<p> 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.</p>
|
|
<p> The available APIs are:</p>
|
|
<p><b> <tt>const char *cdata(void *ptr, size_t nbytes)</tt></b></p>
|
|
<div class="indent">
|
|
<p> Converts <tt>nbytes</tt> of data at <tt>ptr</tt> into the target
|
|
language type. <tt>ptr</tt> can be any pointer.</p>
|
|
</div>
|
|
<p><b> <tt>void memmove(void *ptr, const char *s)</tt></b></p>
|
|
<div class="indent">
|
|
<p> This is actually a wrapper of the standard C library <tt>memmove</tt>
|
|
function,<b> <tt>void *memmove(void *ptr, const void *src, size_t n)</tt>
|
|
</b>, which copies <tt>n</tt> bytes of data from <tt>src</tt> into the
|
|
destination pointed to by <tt>ptr</tt>. Multi-argument typemaps are
|
|
used so that the last two parameters, <tt>src</tt> and <tt>n</tt> are
|
|
replaced by <tt>s</tt>, a string or byte array target language type,
|
|
mentioned earlier. The string/byte array may contain embedded NULL
|
|
bytes. Unlike the C library function nothing is returned by the wrapper
|
|
function.</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">12.3 C string handling</a></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">12.3.1 Default string handling</a></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="targetlang">
|
|
<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">12.3.2 Passing a string with length</a></h3>
|
|
<p> If you have a function that expects string with a length,</p>
|
|
<div class="code">
|
|
<pre>
|
|
size_t parity(char *str, size_t len, size_t initial);
|
|
</pre>
|
|
</div>
|
|
<p> you can wrap the parameters <tt>(char *str, size_t len)</tt> as a
|
|
single argument using a typemap. Just do this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%apply (char *STRING, size_t LENGTH) { (char *str, size_t len) };
|
|
...
|
|
size_t parity(char *str, size_t len, size_t initial);
|
|
</pre>
|
|
</div>
|
|
<p> Now, in the target language, you can use the string like this:</p>
|
|
<div class="targetlang">
|
|
<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. The <tt>(char *STRING, int LENGTH)</tt>
|
|
multi-argument typemap is also available in addition to <tt>(char
|
|
*STRING, size_t LENGTH)</tt>.</p>
|
|
<h3><a name="Library_nn11">12.3.3 Using %newobject to release memory</a></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 if the appropriate target language
|
|
support is available. SWIG provides the appropriate "newfree" typemap
|
|
for <tt>char *</tt> so that the memory is released, however, you may
|
|
need to provide your own "newfree" typemap for other types. See <a href="#Customization_ownership">
|
|
Object ownership and %newobject</a> for more details.</p>
|
|
<h3><a name="Library_nn12">12.3.4 cstring.i</a></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 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_c_standard_library">12.4 C standard library</a></h2>
|
|
<h3><a name="Library_complex">12.4.1 Complex floating types</a></h3>
|
|
<p> SWIG has some support for complex floating types. By default the
|
|
keyword <tt>_Complex</tt> is understood by the parser but <tt>complex</tt>
|
|
is not treated as a keyword because it may be used as an identifier.</p>
|
|
<p> SWIG is only able to fully wrap complex floating types for some
|
|
target languages. If you are using such a target language for complex
|
|
floating types, you should include <tt>complex.i</tt> to enable this
|
|
support:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include "complex.i"
|
|
</pre>
|
|
</div>
|
|
<p> If SWIG is in C++ code this will actually include <tt>std_complex.i</tt>
|
|
for you; otherwise it will include <tt>ccomplex.i</tt>.</p>
|
|
<p> For target languages without support this will fail to find a file
|
|
to include. In this case, if you are wrapping headers which use <tt>
|
|
complex</tt> then you'll need to add a define to your SWIG interface
|
|
file to get SWIG to parse the headers:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#define complex _Complex
|
|
</pre>
|
|
</div>
|
|
<p> Then if wrapping as opaque types is not useful to you, you can use <a
|
|
href="#SWIG_ignore"><tt>%ignore</tt></a> to tell SWIG not to wrap the
|
|
functions and/or variables which use complex floating types.</p>
|
|
<h2><a name="Library_stl_cpp_library">12.5 STL/C++ library</a></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::array (C++11)</td><td>array</td><td>std_array.i</td></tr>
|
|
<tr><td>std::auto_ptr</td><td>memory</td><td>std_auto_ptr.i</td></tr>
|
|
<tr><td>std::complex</td><td>complex</td><td>std_complex.i</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::multimap (C++11)</td><td>multimap</td><td>std_multimap.i</td>
|
|
</tr>
|
|
<tr><td>std::multiset (C++11)</td><td>multiset</td><td>std_multiset.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::shared_ptr (C++11)</td><td>shared_ptr</td><td>
|
|
std_shared_ptr.i</td></tr>
|
|
<tr><td>std::string</td><td>string</td><td>std_string.i</td></tr>
|
|
<tr><td>std::string_view (C++17)</td><td>string_view</td><td>
|
|
std_string_view.i</td></tr>
|
|
<tr><td>std::unordered_map (C++11)</td><td>unordered_map</td><td>
|
|
std_unordered_map.i</td></tr>
|
|
<tr><td>std::unordered_multimap (C++11)</td><td>unordered_multimap</td><td>
|
|
std_unordered_multimap.i</td></tr>
|
|
<tr><td>std::unordered_multiset (C++11)</td><td>unordered_multiset</td><td>
|
|
std_unordered_multiset.i</td></tr>
|
|
<tr><td>std::unordered_set (C++11)</td><td>unordered_set</td><td>
|
|
std_unordered_set.i</td></tr>
|
|
<tr><td>std::vector</td><td>vector</td><td>std_vector.i</td></tr>
|
|
<tr><td>std::wstring</td><td>wstring</td><td>std_wstring.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_std_string">12.5.1 std::string</a></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>
|
|
<h3><a name="Library_std_string_view">12.5.2 std::string_view</a></h3>
|
|
<p> The <tt>std_string_view.i</tt> library provides typemaps for
|
|
converting C++17 <tt>std::string_view</tt> objects to and from strings
|
|
in the target scripting language. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%include "std_string_view.i"
|
|
|
|
std::string_view foo();
|
|
void bar(std::string_view 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_view
|
|
</pre>
|
|
</div>
|
|
<p> For target languages for which SWIG supports directors, <tt>
|
|
directorout</tt> typemaps are provided for <tt>std::string_view</tt>,
|
|
but these require extra care to use safely. The issue is that returning
|
|
<tt>std::string_view</tt> effectively returns a pointer to string data
|
|
but doesn't own the pointed to data. For target languages where there
|
|
isn't a native narrow string representation (e.g. C#, Java) a <tt>
|
|
static std::string</tt> is used to cache the data, which works but isn't
|
|
thread/reentrant safe. For target languages where there is a native
|
|
narrow string representation SWIG will return a <tt>std::string_view</tt>
|
|
pointing to that data, so you need to store the string to return
|
|
somewhere which will persist for the lifetime the caller needs (e.g.
|
|
put it in a member variable) - you can't return a temporary target
|
|
language string. In both cases SWIG will issue a warning by default.</p>
|
|
<h3><a name="Library_std_vector">12.5.3 std::vector</a></h3>
|
|
<p> The <tt>std_vector.i</tt> library provides support for the C++ <tt>
|
|
std::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) {
|
|
for (std::vector<double>::iterator it = v.begin(); it != v.end(); ++it)
|
|
*it /= 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>
|
|
<h3><a name="Library_stl_exceptions">12.5.4 STL exceptions</a></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>
|
|
<h3><a name="Library_std_shared_ptr">12.5.5 shared_ptr smart pointer</a></h3>
|
|
<h4><a name="Library_shared_ptr_basics">12.5.5.1 shared_ptr basics</a></h4>
|
|
<p> Some target languages have support for handling the shared_ptr
|
|
reference counted smart pointer. This smart pointer is available in the
|
|
standard C++11 library as <tt>std::shared_ptr</tt>. It was also in TR1
|
|
as <tt>std::tr1::shared_ptr</tt> before it was fully standardized.
|
|
Support for the widely used <tt>boost::shared_ptr</tt> is also
|
|
available.</p>
|
|
<p> In order to use <tt>std::shared_ptr</tt>, the <tt>std_shared_ptr.i</tt>
|
|
library file should be included:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_shared_ptr.i>
|
|
</pre>
|
|
</div>
|
|
<p> The pre-standard <tt>std::tr1::shared_ptr</tt> can be used by
|
|
including the following macro before including the <tt>std_shared_ptr.i</tt>
|
|
library file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#define SWIG_SHARED_PTR_SUBNAMESPACE tr1
|
|
%include <std_shared_ptr.i>
|
|
</pre>
|
|
</div>
|
|
<p> In order to use <tt>boost::shared_ptr</tt>, the <tt>
|
|
boost_shared_ptr.i</tt> library file should be included:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <boost_shared_ptr.i>
|
|
</pre>
|
|
</div>
|
|
<p> You can only use one of these variants of shared_ptr in your
|
|
interface file at a time (also SWIG doesn't currently support using
|
|
both <tt>%shared_ptr(T)</tt> and <tt>%unique_ptr<T></tt> on the same
|
|
type <tt>T</tt>). All three variants must be used in conjunction with
|
|
the <tt>%shared_ptr(T)</tt> macro, where <tt>T</tt> is the underlying
|
|
pointer type equating to usage <tt>shared_ptr<T></tt>. The type <tt>T</tt>
|
|
must be non-primitive. A simple example demonstrates usage:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%include <boost_shared_ptr.i>
|
|
%shared_ptr(IntValue)
|
|
|
|
%inline %{
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
struct IntValue {
|
|
int value;
|
|
IntValue(int v) : value(v) {}
|
|
};
|
|
|
|
static int extractValue(const IntValue &t) {
|
|
return t.value;
|
|
}
|
|
|
|
static int extractValueSmart(boost::shared_ptr<IntValue> t) {
|
|
return t->value;
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> Note that the <tt>%shared_ptr(IntValue)</tt> declaration occurs
|
|
after the inclusion of the <tt>boost_shared_ptr.i</tt> library which
|
|
provides the macro and, very importantly, before any usage or
|
|
declaration of the type, <tt>IntValue</tt>. The <tt>%shared_ptr</tt>
|
|
macro provides, a few things for handling this smart pointer, but
|
|
mostly a number of typemaps. These typemaps override the default
|
|
typemaps so that the underlying proxy class is stored and passed around
|
|
as a pointer to a <tt>shared_ptr</tt> instead of a plain pointer to the
|
|
underlying type. This approach means that any instantiation of the type
|
|
can be passed to methods taking the type by value, reference, pointer
|
|
or as a smart pointer. The interested reader might want to look at the
|
|
generated code, however, usage is simple and no different handling is
|
|
required from the target language. For example, a simple use case of
|
|
the above code from Java would be:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
IntValue iv = new IntValue(1234);
|
|
int val1 = example.extractValue(iv);
|
|
int val2 = example.extractValueSmart(iv);
|
|
System.out.println(val1 + " " + val2);
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Library_shared_ptr_inheritance">12.5.5.2 shared_ptr and
|
|
inheritance</a></h4>
|
|
<p> The shared_ptr library works quite differently to SWIG's normal, but
|
|
somewhat limited, <a href="#SWIGPlus_smart_pointers">smart pointer
|
|
handling</a>. The shared_ptr library does not generate extra wrappers,
|
|
just for smart pointer handling, in addition to the proxy class. The
|
|
normal proxy class including inheritance relationships is generated as
|
|
usual. The only real change introduced by the <tt>%shared_ptr</tt>
|
|
macro is that the proxy class stores a pointer to the shared_ptr
|
|
instance instead of a raw pointer to the instance. A proxy class
|
|
derived from a base which is being wrapped with shared_ptr can and<b>
|
|
must</b> be wrapped as a shared_ptr too. In other words all classes in
|
|
an inheritance hierarchy must all be used with the <tt>%shared_ptr</tt>
|
|
macro. For example the following code can be used with the base class
|
|
shown earlier:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%shared_ptr(DerivedIntValue)
|
|
%inline %{
|
|
struct DerivedIntValue : IntValue {
|
|
DerivedIntValue(int value) : IntValue(value) {}
|
|
...
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> A shared_ptr of the derived class can now be passed to a method
|
|
where the base is expected in the target language, just as it can in
|
|
C++:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
DerivedIntValue div = new DerivedIntValue(5678);
|
|
int val3 = example.extractValue(div);
|
|
int val4 = example.extractValueSmart(div);
|
|
</pre>
|
|
</div>
|
|
<p> If the <tt>%shared_ptr</tt> macro is omitted for any class in the
|
|
inheritance hierarchy, SWIG will warn about this and the generated code
|
|
may or may not result in a C++ compilation error. For example, the
|
|
following input:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include "boost_shared_ptr.i"
|
|
%shared_ptr(Parent);
|
|
|
|
%inline %{
|
|
#include <boost/shared_ptr.hpp>
|
|
struct GrandParent {
|
|
virtual ~GrandParent() {}
|
|
};
|
|
|
|
struct Parent : GrandParent {
|
|
virtual ~Parent() {}
|
|
};
|
|
|
|
struct Child : Parent {
|
|
virtual ~Child() {}
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> warns about the missing smart pointer information:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:12: Warning 520: Base class 'GrandParent' of 'Parent' is not similarly marked as a smart pointer.
|
|
example.i:16: Warning 520: Derived class 'Child' of 'Parent' is not similarly marked as a smart pointer.
|
|
</pre>
|
|
</div>
|
|
<p> Adding the missing <tt>%shared_ptr</tt> macros will fix this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <boost_shared_ptr.i>
|
|
%shared_ptr(GrandParent);
|
|
%shared_ptr(Parent);
|
|
%shared_ptr(Child);
|
|
|
|
... as before ...
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Library_shared_ptr_overloading">12.5.5.3 shared_ptr and
|
|
method overloading</a></h4>
|
|
<p> A C++ compiler can disambiguate a method overloaded by a shared_ptr
|
|
and one using the raw underlying type. For example, either one of these
|
|
methods can be called in C++:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int age(std::shared_ptr<GrandParent> num);
|
|
int age(GrandParent& num);
|
|
</pre>
|
|
</div>
|
|
<p> When wrapped by SWIG, disambiguation is not possible using the
|
|
overloaded names as there is just one equivalent type (<tt>GrandParent</tt>
|
|
) in the target language. SWIG will choose to wrap just the first method
|
|
by default. <a href="#SWIGPlus_nn25">Ambiguity in overloading</a>
|
|
discusses ways to control which method(s) gets wrapped using <tt>
|
|
%ignore</tt> or <tt>%rename</tt>. For the interested reader, SWIG
|
|
detects that they are equivalent types via the <a href="#Typemaps_typecheck_pointer">
|
|
typecheck typemaps</a> in the shared_ptr library.</p>
|
|
<h4><a name="Library_shared_ptr_templates">12.5.5.4 shared_ptr and
|
|
templates</a></h4>
|
|
<p> The <tt>%shared_ptr</tt> macro should be used for all the required
|
|
instantiations of the template before each of the <tt>%template</tt>
|
|
instantiations. For example, consider <tt>number.h</tt> containing the
|
|
following illustrative template:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#include <memory>
|
|
|
|
template<int N> struct Number {
|
|
int num;
|
|
Number() : num(N) {}
|
|
static std::shared_ptr<Number<N>> make() { return std::make_shared<Number<N>>(); }
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The SWIG code below shows the required ordering:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_shared_ptr.i>
|
|
|
|
%shared_ptr(Number<10>);
|
|
%shared_ptr(Number<42>);
|
|
|
|
%{
|
|
#include "number.h"
|
|
%}
|
|
%include "number.h"
|
|
|
|
%template(Number10) Number<10>;
|
|
%template(Number42) Number<42>;
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Library_shared_ptr_directors">12.5.5.5 shared_ptr and
|
|
directors</a></h4>
|
|
<p> The languages that support shared_ptr also have support for using
|
|
shared_ptr with directors.</p>
|
|
<h3><a name="Library_std_unique_ptr">12.5.6 unique_ptr smart pointer</a></h3>
|
|
<p> The <tt>std_unique_ptr.i</tt> library file provides SWIG's
|
|
unique_ptr support. It provides move semantics for the smart pointer's
|
|
underlying object, both from C++ to the target language and vice versa.</p>
|
|
<p> The library defines typemaps and a macro, <tt>%unique_ptr(T)</tt>,
|
|
to use for handling <tt>std::unique_ptr<T></tt> for a type <tt>T</tt>.
|
|
The type <tt>T</tt> must be non-primitive. This macro should be used
|
|
before any code declaring or using type <tt>T</tt>. Ordering
|
|
requirements for using this smart pointer macro are the same as the
|
|
equivalent <tt>%shared_ptr(T)</tt> macro covered in the previous
|
|
section. The ownership and move semantics described here can of course
|
|
be modified if not suitable by copying and customising the typemaps in
|
|
the appropriate <tt>std_unique_ptr.i</tt> library file.</p>
|
|
<p> Note that SWIG doesn't currently support using both <tt>
|
|
%shared_ptr(T)</tt> and <tt>%unique_ptr<T></tt> on the same type <tt>T</tt>
|
|
.</p>
|
|
<h4><a name="Library_std_unique_ptr_by_value">12.5.6.1 unique_ptr passed
|
|
by value</a></h4>
|
|
<p> Example usage of a <tt>std::unique_ptr</tt> being returned from a
|
|
function by value is shown below.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_unique_ptr.i>
|
|
|
|
%unique_ptr(Klass)
|
|
%inline %{
|
|
#include <memory>
|
|
class Klass {
|
|
public:
|
|
// Factory function creating objects of this class:
|
|
static std::unique_ptr<Klass> Create(int value) {
|
|
return std::unique_ptr<Klass>(new Klass(value));
|
|
}
|
|
|
|
int getValue() const { return m_value; }
|
|
|
|
private:
|
|
Klass(int value) : m_value(value) {}
|
|
int m_value;
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The returned objects can be used naturally from the target language,
|
|
e.g. from C#:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Klass k = Klass.Create(17);
|
|
int value = k.getValue();
|
|
</pre>
|
|
</div>
|
|
<p> The implementation simply calls <tt>std::unique_ptr::release()</tt>
|
|
to obtain the underlying raw pointer. The pointer is then used to
|
|
create a target language proxy class in the same way that SWIG handles
|
|
a C++ function returning a class by value. The target language proxy
|
|
class then owns the memory pointed to by the raw pointer and memory
|
|
handling is identical to normal SWIG proxy class handling of the
|
|
underlying C++ memory. Note that an object returned by value is first
|
|
copied/moved from the stack onto the heap in order to obtain a raw
|
|
pointer on the heap, whereas the underlying raw pointer in <tt>
|
|
std::unique_ptr</tt> already points to an object the heap.</p>
|
|
<p> Note that the implementation is quite different to the <tt>
|
|
std::shared_ptr</tt> smart pointer, where the proxy class manages the
|
|
underlying C++ memory as a pointer to a shared_ptr instead of a plain
|
|
raw pointer.</p>
|
|
<p> A possibly less common usage of this smart pointer is as a parameter
|
|
to a function. When used like this it indicates that memory usage of
|
|
the object pointed to by the underlying pointer is transferred to the
|
|
function being called. The code that SWIG generates assumes this
|
|
happens. First, it is assumed that a proxy class already owns the
|
|
underlying C++ object and is used to pass the object to the C++
|
|
function being called. Second, the ownership is transferred from the
|
|
proxy class to the C++ function being called and lifetime is then
|
|
controlled by the function. Finally, it is assumed the lifetime of the
|
|
object may not last beyond returning from the C++ function and hence
|
|
the proxy class can no longer be used.</p>
|
|
<p> Consider expanding the example above with a function that takes a <tt>
|
|
std::unique_ptr</tt> as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void take(std::unique_ptr<Klass>);
|
|
</pre>
|
|
</div>
|
|
<p> and use from C#:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Klass k = Klass.Create(17); // create an instance of Klass any way you like
|
|
int value = k.getValue(); // ok
|
|
example.take(k); // memory ownership passes from C# layer to C++ layer
|
|
int v = k.getValue(); // don't do this - invalid use of k
|
|
</pre>
|
|
</div>
|
|
<p> Attempts to use <tt>k</tt> after the ownership has been passed into
|
|
the <tt>take</tt> function should not be attempted. The implementation
|
|
sets the proxy class to an invalid state by setting the class's
|
|
underlying C++ pointer to null after the return from the <tt>take</tt>
|
|
function. Subsequent use of an invalid proxy class instance is very
|
|
much dependent on the implementation in the target language and ranges
|
|
from a segfault to giving a nice error. Consider implementing
|
|
additional checks via the 'check' typemap.</p>
|
|
<p> Attempts to pass ownership from a proxy class to a <tt>std::unique</tt>
|
|
parameter more than once will result in a "Cannot release ownership as
|
|
memory is not owned" exception. For example, if <tt>example.take(k)</tt>
|
|
in the example above is called twice.</p>
|
|
<h4><a name="Library_std_unique_ptr_by_ref">12.5.6.2 unique_ptr passed
|
|
by reference</a></h4>
|
|
<p> The effect of passing a <tt>std::unique_ptr</tt> by rvalue reference
|
|
into a function is identical to passing it by value. The ownership of
|
|
the memory of the object being pointed to by the underyling pointer is
|
|
transferred from the proxy class to the C++ function being called.
|
|
Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void grab(std::unique_ptr<Klass> &&);
|
|
</pre>
|
|
</div>
|
|
<p> Passing non-const lvalue references into a function is a bit quirky
|
|
and not perfect due to ambiguities as to what the function may do. The
|
|
approach taken is the ownership is transferred out of the target
|
|
language from the proxy class into C++ space and the proxy class can
|
|
then no longer be used after the wrapped function returns. In summary
|
|
it works much like passing a <tt>std::unique_ptr</tt> by value into a
|
|
function. The assumption is the function will not modify the <tt>
|
|
std::unique_ptr</tt>. If this is not true and the underlying pointer is
|
|
changed, such as calling the member functions, <tt>swap</tt>, <tt>reset</tt>
|
|
or <tt>release</tt>, then the modified <tt>std::unique_ptr</tt> will
|
|
effectively be ignored. It is destroyed when the function exits C++
|
|
space on return to the target language. Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void process(std::unique_ptr<Klass> &);
|
|
</pre>
|
|
</div>
|
|
<p> Passing const lvalue references into a function works much like
|
|
passing any wrapped class. The proxy class owning the underling C++
|
|
object continues to own the underying C++ object after calling the
|
|
function, the function cannot modify the <tt>std::unique_ptr</tt> or
|
|
take ownership. Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void use(const std::unique_ptr<Klass> &);
|
|
</pre>
|
|
</div>
|
|
<p> Move semantics are not provided when wrapping a C++ function that
|
|
returns a <tt>std::unique_ptr</tt> by reference. The target language
|
|
proxy class wrapper that is returned does not own the underlying C++
|
|
object. This applies to all reference types, such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
std::unique_ptr<Klass> & LvalueRefReturn();
|
|
std::unique_ptr<Klass> && RvalueRefReturn();
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> Support for <tt>std::unique_ptr</tt> was
|
|
first added in SWIG-4.1.0. This initial support contained the move
|
|
semantics when passing a <tt>std::unique_ptr</tt> around by value.
|
|
Support for passing a <tt>std::unique_ptr</tt> around by reference was
|
|
added in SWIG-4.3.0.</p>
|
|
<h3><a name="Library_std_auto_ptr">12.5.7 auto_ptr smart pointer</a></h3>
|
|
<p> While <tt>std::auto_ptr</tt> is deprecated in C++11, some existing
|
|
code may still be using it. SWIG provides support for this class which
|
|
is nearly identical to <tt>std::unique_ptr</tt>.</p>
|
|
<p> The <tt>std_auto_ptr.i</tt> library file provides SWIG's auto_ptr
|
|
support. It defines typemaps and a macro, <tt>%auto_ptr(T)</tt>, to use
|
|
for handling <tt>std::auto_ptr<T></tt> for a type <tt>T</tt>. The type <tt>
|
|
T</tt> must be non-primitive. This macro should be used before any code
|
|
declaring or using type <tt>T</tt>. Ordering requirements for using
|
|
this smart pointer macro are the same as the equivalent <tt>
|
|
%shared_ptr(T)</tt> and <tt>%unique_ptr</tt> macros covered in the
|
|
previous two sections.</p>
|
|
<p> Example usage of a <tt>std::auto_ptr</tt> being returned from a
|
|
function is shown below.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_auto_ptr.i>
|
|
|
|
%auto_ptr(Klass)
|
|
%inline %{
|
|
#include <memory>
|
|
class Klass {
|
|
public:
|
|
// Factory function creating objects of this class:
|
|
static std::auto_ptr<Klass> Create(int value) {
|
|
return std::auto_ptr<Klass>(new Klass(value));
|
|
}
|
|
|
|
int getValue() const { return m_value; }
|
|
|
|
private:
|
|
Klass(int value) : m_value(value) {}
|
|
int m_value;
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The returned objects can be used naturally from the target language,
|
|
e.g. from C#:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Klass k = Klass.Create(17);
|
|
int value = k.getValue();
|
|
</pre>
|
|
</div>
|
|
<p> The implementation simply calls <tt>std::auto_ptr::release()</tt> to
|
|
obtain the underlying raw pointer. That is, it works the same way
|
|
covered in the previous section for <tt>std::unique_ptr</tt>.</p>
|
|
<p> Input parameters also work the same way as <tt>std::unique_ptr</tt>
|
|
covered in the previous section.</p>
|
|
<h2><a name="Library_nn16">12.6 Utility Libraries</a></h2>
|
|
<h3><a name="Library_nn17">12.6.1 exception.i</a></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
|
|
SWIG_NullReferenceError
|
|
</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>
|
|
<h3><a name="Library_attributes">12.6.2 attribute.i</a></h3>
|
|
<p> The attribute library contains a set of macros to convert a pair of
|
|
set/get methods into a "native" attribute/property.</p>
|
|
<p> Use <tt>%attribute</tt> when you have a pair of get/set methods to a
|
|
primitive type like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include "attribute.i"
|
|
%attribute(A, int, a, get_a, set_a);
|
|
|
|
struct A {
|
|
int get_a() const;
|
|
void set_a(int aa);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> and you want to provide that variable as an attribute in the target
|
|
language. This example only works for primitive types, not derived
|
|
types. Now you can use the attributes like so (in Python):</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
x = A()
|
|
x.a = 3 # calls A::set_a(3)
|
|
print(x.a) # calls A::get_a() const
|
|
</pre>
|
|
</div>
|
|
<p> If you don't provide a 'set' method, a 'read-only' attribute is
|
|
generated, ie, like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%attribute(A, int, c, get_c);
|
|
</pre>
|
|
</div>
|
|
<p> Use <tt>%attributeref</tt> when you have const/non-const reference
|
|
access methods for primitive types or class/structs, like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%attributeref(A, int, b);
|
|
|
|
struct A {
|
|
const int & b() const;
|
|
int & b();
|
|
};
|
|
|
|
%attributeref(B, int, c);
|
|
|
|
struct B {
|
|
int & c();
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Use the attributes like so (in Python):</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
x = A()
|
|
x.b = 3 # calls A::b()
|
|
print(x.b) # calls A::b() const
|
|
</pre>
|
|
</div>
|
|
<p> You can also use</p>
|
|
<div class="code">
|
|
<pre>
|
|
%attributeref(Class, AttributeType, AttributeName, AccessorMethod)
|
|
</pre>
|
|
</div>
|
|
<p> if the internal C++ reference methods have a different name from the
|
|
attribute you want, so</p>
|
|
<div class="code">
|
|
<pre>
|
|
%attributeref(B, int, d, c);
|
|
</pre>
|
|
</div>
|
|
<p> is the same as the last example, but instead of the attribute 'c'
|
|
being called 'c', it is called 'd'.</p>
|
|
<p> Use <tt>%attribute2</tt> instead of <tt>%attribute</tt> to indicate
|
|
that reference-pointer translation is required. Use <tt>%attribute2</tt>
|
|
instead of <tt>%attribute</tt> in cases like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
|
|
%inline %{
|
|
struct MyFoo {
|
|
int x;
|
|
};
|
|
class MyClass {
|
|
MyFoo foo;
|
|
public:
|
|
MyFoo & GetFoo() { return foo; }
|
|
void SetFoo(const MyFoo &other) { foo = other; }
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> Here, the data type of the property is a wrapped type <tt>MyFoo</tt>
|
|
and on the C++ side it is passed by reference. The problem is that the
|
|
SWIG wrapper will pass around a pointer (MyFoo *) which is not
|
|
compatible with the reference type of the accessors (MyFoo &).
|
|
Therefore, if you use <tt>%attribute</tt>, you'll get an error from
|
|
your C/C++ compiler. <tt>%attribute2</tt> translates between a pointer
|
|
and a reference to eliminate the error. In case you're confused, let's
|
|
make it simple: just use <tt>%attribute</tt> at first, but if the C/C++
|
|
compiler gives an error while compiling the wrapper, try <tt>
|
|
%attribute2</tt> instead.</p>
|
|
<p> NOTE: remember that if the type contains commas, such as <tt>
|
|
std::pair<int, int></tt>, you need to use the macro like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%attributeref(A, %arg(std::pair<int, int>), pval);
|
|
</pre>
|
|
</div>
|
|
<p> where <tt>%arg()</tt> 'normalizes' the type to be understood as a
|
|
single argument, otherwise the macro will get confused by the comma.</p>
|
|
<p> The <tt>%attributeval</tt> is the same as <tt>%attribute</tt>, but
|
|
should be used when the type is a class/struct (ie a non-primitive
|
|
type) and when the get and set methods return/pass by value. The
|
|
following is very similar to the above example, but note that the
|
|
access is by value rather than reference.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%attributeval(MyClassVal, MyFoo, ReadWriteFoo, GetFoo, SetFoo);
|
|
%attributeval(MyClassVal, MyFoo, ReadOnlyFoo, GetFoo);
|
|
%inline %{
|
|
class MyClassVal {
|
|
MyFoo foo;
|
|
public:
|
|
MyFoo GetFoo() { return foo; }
|
|
void SetFoo(MyFoo other) { foo = other; }
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>%attributestring</tt> is the same as <tt>%attributeval</tt>,
|
|
but should be used for string class types, which are unusual as they
|
|
are a class on the C++ side, but normally an immutable/primitive type
|
|
in the target language. Example usage for <tt>std::string</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <std_string.i>
|
|
%attributestring(MyStringyClass, std::string, ReadWriteString, GetString, SetString);
|
|
%attributestring(MyStringyClass, std::string, ReadOnlyString, GetString);
|
|
%inline %{
|
|
class MyStringyClass {
|
|
std::string str;
|
|
public:
|
|
MyStringyClass(const std::string &val) : str(val) {}
|
|
std::string GetString() { return str; }
|
|
void SetString(std::string other) { str = other; }
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>%attributestring</tt> also works for class types that have <tt>
|
|
%naturalvar</tt> turned on and so is also useful for shared_ptr which
|
|
has <tt>%naturalvar</tt> turned on in <tt>%shared_ptr</tt>.</p>
|
|
<h4><a name="Library_attribute_templates">12.6.2.1 %attribute and C++
|
|
templates</a></h4>
|
|
<p> <tt>%attribute</tt> and friends have to be used on fully specified
|
|
classes. For example</p>
|
|
<div class="code">
|
|
<pre>
|
|
%attributeref(A<int>, int, a);
|
|
%inline %{
|
|
template <class T> struct A {
|
|
T a() const;
|
|
void a(T &);
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> Note the use of a template-id (i.e., <tt>A<int></tt> not <tt>A<T></tt>
|
|
or just <tt>A</tt>). This means that <tt>%attribute</tt> statements
|
|
have to be repeated for any template-id that you want to use with <tt>
|
|
%template</tt>.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Arguments">13 Argument Handling</a></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 5, 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">13.1 The typemaps.i library</a></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">13.1.1 Introduction</a></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 };
|
|
%inline %{
|
|
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">13.1.2 Input parameters</a></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">13.1.3 Output parameters</a></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">13.1.4 Input/Output parameters</a></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>
|
|
<h3><a name="Arguments_nn7">13.1.5 Using different names</a></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">13.2 Applying constraints to input values</a>
|
|
</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">13.2.1 Simple constraint example</a></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
|
|
int fclose(FILE *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">13.2.2 Constraint methods</a></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">13.2.3 Applying constraints to new
|
|
datatypes</a></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">14 Typemaps</a></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_aspects">Similarities to Aspect Oriented
|
|
Programming</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_typedef_reductions">Typedef reductions matching</a>
|
|
</li>
|
|
<li><a href="#Typemaps_nn19">Default typemap matching rules</a></li>
|
|
<li><a href="#Typemaps_multi_argument_typemaps_patterns">Multi-arguments
|
|
typemaps</a></li>
|
|
<li><a href="#Typemaps_matching_template_comparison">Matching rules
|
|
compared to C++ templates</a></li>
|
|
<li><a href="#Typemaps_debugging_search">Debugging typemap pattern
|
|
matching</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>
|
|
<ul>
|
|
<li><a href="#Typemaps_type_special_variables">Type related special
|
|
variables</a></li>
|
|
<li><a href="#Typemaps_non_type_special_variables">Non-type related
|
|
special variables</a></li>
|
|
</ul>
|
|
</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>
|
|
<li><a href="#Typemaps_special_macro_typemap_attribute">
|
|
$typemap(method:attribute, typepattern)</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Typemaps_special_variable_attributes">Special variables
|
|
and typemap attributes</a></li>
|
|
<li><a href="#Typemaps_special_variables_and_macros">Special variables
|
|
combined with special variable macros</a></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_ret">"ret" 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="#Typemaps_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 target 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="#Typemaps_warnings">Typemap warnings</a></li>
|
|
<li><a href="#Typemaps_fragments">Typemap fragments</a>
|
|
<ul>
|
|
<li><a href="#Typemaps_fragment_type_specialization">Fragment type
|
|
specialization</a></li>
|
|
<li><a href="#Typemaps_automatic_specialization">Fragments and automatic
|
|
typemap specialization</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Typemaps_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>
|
|
<ul>
|
|
<li><a href="#Typemaps_typecheck_pointer">SWIG_TYPECHECK_POINTER
|
|
precedence level and the typecheck typemap</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Typemaps_nn48">More about %apply and %clear</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">14.1 Introduction</a></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">14.1.1 Type conversion</a></h3>
|
|
<p> One of the most important problems in wrapper code generation is the
|
|
conversion or marshalling 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">14.1.2 Typemaps</a></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 <tt>$</tt> 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">14.1.3 Pattern matching</a></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 family 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.");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
|
|
...
|
|
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">14.1.4 Reusing typemaps</a></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> There is a more powerful way to copy a family of typemaps though.
|
|
Consider the following family of two typemap methods, "in" and "out"
|
|
for type <tt>int</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) int {
|
|
/* Convert an integer argument */
|
|
...
|
|
}
|
|
%typemap(out) int {
|
|
/* Return an integer value */
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Each of the two typemap methods could be copied individually for
|
|
type <tt>size_t</tt> as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* Apply all of the int typemaps to size_t */
|
|
%typemap(in) size_t = int;
|
|
%typemap(out) size_t = int;
|
|
</pre>
|
|
</div>
|
|
<p> A more powerful form of copying is available from the <tt>%apply</tt>
|
|
directive. The code below is identical to the above:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* Apply all of the int 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">14.1.5 What can be done with typemaps?</a></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 for types used in overloaded methods
|
|
("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">14.1.6 What can't be done with typemaps?</a></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(int n);
|
|
</pre>
|
|
</div>
|
|
<p> and you wanted to tell SWIG that <tt>make_Foo(int n)</tt> returned a
|
|
newly allocated object (for the purposes of providing better memory
|
|
management). Clearly, this property of <tt>make_Foo(int n)</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_aspects">14.1.7 Similarities to Aspect Oriented
|
|
Programming</a></h3>
|
|
<p> SWIG has parallels to <a href="https://en.wikipedia.org/wiki/Aspect-oriented_programming">
|
|
Aspect Oriented Software Development (AOP)</a>. The <a href="https://en.wikipedia.org/wiki/Aspect-oriented_programming#Terminology">
|
|
AOP terminology</a> with respect to SWIG typemaps can be viewed as
|
|
follows:</p>
|
|
<ul>
|
|
<li><b> Cross-cutting concerns</b>: The cross-cutting concerns are the
|
|
modularization of the functionality that the typemaps implement, which
|
|
is primarily marshalling of types from/to the target language and
|
|
C/C++.</li>
|
|
<li><b> Advice</b>: The typemap body contains code which is executed
|
|
whenever the marshalling is required.</li>
|
|
<li><b> Pointcut</b>: The pointcuts are the positions in the wrapper
|
|
code that the typemap code is generated into.</li>
|
|
<li><b> Aspect</b>: Aspects are the combination of the pointcut and the
|
|
advice, hence each typemap is an aspect.</li>
|
|
</ul>
|
|
<p> SWIG can also be viewed as has having a second set of aspects based
|
|
around <a href="#Customization">%feature</a>. Features such as <tt>
|
|
%exception</tt> are also cross-cutting concerns as they encapsulate code
|
|
that can be used to add logging or exception handling to any function.</p>
|
|
<h3><a name="Typemaps_nn9">14.1.8 The rest of this chapter</a></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">14.2 Typemap specifications</a></h2>
|
|
<p> This section describes the behavior of the <tt>%typemap</tt>
|
|
directive itself.</p>
|
|
<h3><a name="Typemaps_defining">14.2.1 Defining a typemap</a></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. They
|
|
are also known as typemap attributes.</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_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 = scm_to_int($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">14.2.2 Typemap scope</a></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">14.2.3 Copying a typemap</a></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">14.2.4 Deleting a typemap</a></h3>
|
|
<p> A particular typemap can be deleted / cleared by simply defining no
|
|
code. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) int; // Clears the "in" typemap for int
|
|
%typemap(in) int, long, short; // Clears the "in" typemap for int, long, short
|
|
%typemap(in) int *output;
|
|
</pre>
|
|
</div>
|
|
<p> The above syntax deletes a typemap for just one typemap method - the
|
|
"in" method in each of the examples above. The <tt>%clear</tt>
|
|
directive is more powerful and will delete / clear a family of
|
|
typemaps, that is, all the typemap methods for a given type. For
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%clear int; // Delete all typemaps ("in", "out", "varin", ...) 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 family of typemaps immediately
|
|
after the clear operation.</p>
|
|
<h3><a name="Typemaps_nn15">14.2.5 Placement of typemaps</a></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 forward class declaration <tt>class
|
|
string</tt>.</p>
|
|
<h2><a name="Typemaps_pattern_matching">14.3 Pattern matching rules</a></h2>
|
|
<p> The section describes the pattern matching rules by which C/C++
|
|
datatypes are associated with typemaps. The matching rules can be
|
|
observed in practice by using the debugging options also described.</p>
|
|
<h3><a name="Typemaps_nn17">14.3.1 Basic matching rules</a></h3>
|
|
<p> Typemaps are matched using both a type and a name (typically the
|
|
name of an argument, but in the case of <tt>out</tt> typemaps, the name
|
|
of a function, qualified by the class name if it's a class method). 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>
|
|
<li>If <tt>TYPE</tt> is a C++ template of type <tt>T< TPARMS ></tt>,
|
|
where <tt>TPARMS</tt> are the template parameters, the type is stripped
|
|
of the template parameters and the following checks are then made:
|
|
<ul>
|
|
<li>Typemaps that exactly match <tt>T</tt> and <tt>NAME</tt>.</li>
|
|
<li>Typemaps that exactly match <tt>T</tt> only.</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<p> If <tt>TYPE</tt> includes qualifiers (const, volatile, etc.), each
|
|
qualifier is stripped one at a time to form a new stripped type and the
|
|
matching rules above are repeated on the stripped type. The left-most
|
|
qualifier is stripped first, resulting in the right-most (or top-level)
|
|
qualifier being stripped last. For example <tt>int const*const</tt> is
|
|
first stripped to <tt>int *const</tt> then <tt>int *</tt>.</p>
|
|
<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 (qualifier stripped)
|
|
char * Type match (qualifier stripped)
|
|
</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); // const int *z 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>
|
|
<p><b> Compatibility note:</b> SWIG-2.0.0 introduced stripping the
|
|
qualifiers one step at a time. Prior versions stripped all qualifiers
|
|
in one step.</p>
|
|
<h3><a name="Typemaps_typedef_reductions">14.3.2 Typedef reductions
|
|
matching</a></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>
|
|
<p> As a point of clarification, it is worth emphasizing that typedef
|
|
matching is a typedef<b> reduction</b> process only, that is, SWIG does
|
|
not search for every single possible typedef. Given a type in a
|
|
declaration, it will only reduce the type, it won't build it up looking
|
|
for typedefs. For example, given the type <tt>Struct</tt>, the typemap
|
|
below will not be used for the <tt>aStruct</tt> parameter, because <tt>
|
|
Struct</tt> is fully reduced:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct Struct {...};
|
|
typedef Struct StructTypedef;
|
|
|
|
%typemap(in) StructTypedef {
|
|
...
|
|
}
|
|
|
|
void go(Struct aStruct);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Typemaps_nn19">14.3.3 Default typemap matching rules</a></h3>
|
|
<p> If the basic pattern matching rules result in no match being made,
|
|
even after typedef reductions, the default typemap matching rules are
|
|
used to look for a suitable typemap match. These rules match a generic
|
|
typemap based on the reserved <tt>SWIGTYPE</tt> base type. For example
|
|
pointers will use <tt>SWIGTYPE *</tt> and references will use <tt>
|
|
SWIGTYPE &</tt>. More precisely, the rules are based on the C++ class
|
|
template partial specialization matching rules used by C++ compilers
|
|
when looking for an appropriate partial template specialization. This
|
|
means that a match is chosen from the most specialized set of generic
|
|
typemap types available. For example, when looking for a match to <tt>
|
|
int const *</tt>, the rules will prefer to match <tt>SWIGTYPE const *</tt>
|
|
if available before matching <tt>SWIGTYPE *</tt>, before matching <tt>
|
|
SWIGTYPE</tt>.</p>
|
|
<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 for primitives marshalled by value or
|
|
const reference are written like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) int "... convert to int ..."
|
|
%typemap(in) short "... convert to short ..."
|
|
%typemap(in) float "... convert to float ..."
|
|
...
|
|
%typemap(in) const int & "... convert ..."
|
|
%typemap(in) const short & "... convert ..."
|
|
%typemap(in) const float & "... convert ..."
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> Since typemap matching follows all <tt>typedef</tt> declarations,
|
|
any sort of type that is mapped to a primitive type by value or const
|
|
reference through <tt>typedef</tt> will be picked up by one of these
|
|
primitive typemaps. Most language modules also define typemaps for char
|
|
pointers and char arrays to handle strings, so these non-default types
|
|
will also be used in preference as the basic typemap matching rules
|
|
provide a better match than the default typemap matching rules.</p>
|
|
<p> Below is a list of the typical default types supplied by language
|
|
modules, showing what the "in" typemap would look like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) SWIGTYPE & { ... default reference handling ... }
|
|
%typemap(in) SWIGTYPE * { ... default pointer handling ... }
|
|
%typemap(in) SWIGTYPE *const { ... default pointer const handling ... }
|
|
%typemap(in) SWIGTYPE *const& { ... default pointer const reference handling ... }
|
|
%typemap(in) SWIGTYPE[ANY] { ... 1D fixed size arrays handling ... }
|
|
%typemap(in) SWIGTYPE [] { ... unknown sized array handling ... }
|
|
%typemap(in) enum SWIGTYPE { ... default handling for enum values ... }
|
|
%typemap(in) const enum SWIGTYPE & { ... default handling for const enum reference values ... }
|
|
%typemap(in) SWIGTYPE (CLASS::*) { ... default pointer member handling ... }
|
|
%typemap(in) SWIGTYPE { ... simple default handling ... }
|
|
</pre>
|
|
</div>
|
|
<p> If you wanted to change SWIG's default handling for simple pointers,
|
|
you would simply redefine the rule for <tt>SWIGTYPE *</tt>. Note, the
|
|
simple default typemap rule is used to match against simple types that
|
|
don't match any other rules:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) SWIGTYPE { ... simple default handling ... }
|
|
</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 (<a href="#SWIG_nn22">as described in
|
|
this earlier section</a>).</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> Let's consider an example where 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.</p>
|
|
<p> The best way to explore the default typemaps is to look at the ones
|
|
already defined for a particular language module. Typemap definitions
|
|
are usually found in the SWIG library in a file such as <tt>java.swg</tt>
|
|
, <tt>csharp.swg</tt> etc. However, for many of the target languages the
|
|
typemaps are hidden behind complicated macros, so the best way to view
|
|
the default typemaps, or any typemaps for that matter, is to look at
|
|
the preprocessed output by running <tt>swig -E</tt> on any interface
|
|
file. Finally the best way to view the typemap matching rules in action
|
|
is via the <a href="#Typemaps_debugging_search">debugging typemap
|
|
pattern matching</a> options covered later on.</p>
|
|
<p><b> Compatibility note:</b> The default typemap matching rules were
|
|
modified in SWIG-2.0.0 from a slightly simpler scheme to match the
|
|
current C++ class template partial specialization matching rules.</p>
|
|
<h3><a name="Typemaps_multi_argument_typemaps_patterns">14.3.4
|
|
Multi-arguments typemaps</a></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>
|
|
<h3><a name="Typemaps_matching_template_comparison">14.3.5 Matching
|
|
rules compared to C++ templates</a></h3>
|
|
<p> For those intimately familiar with C++ templates, a comparison of
|
|
the typemap matching rules and template type deduction is interesting.
|
|
The two areas considered are firstly the default typemaps and their
|
|
similarities to partial template specialization and secondly,
|
|
non-default typemaps and their similarities to full template
|
|
specialization.</p>
|
|
<p> For default (SWIGTYPE) typemaps the rules are inspired by C++ class
|
|
template partial specialization. For example, given partial
|
|
specialization for <tt>T const&</tt> :</p>
|
|
<div class="code">
|
|
<pre>
|
|
template <typename T> struct X { void a(); };
|
|
template <typename T> struct X< T const& > { void b(); };
|
|
</pre>
|
|
</div>
|
|
<p> The full (unspecialized) template is matched with most types, such
|
|
as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
X< int & > x1; x1.a();
|
|
</pre>
|
|
</div>
|
|
<p> and the following all match the <tt>T const&</tt> partial
|
|
specialization:</p>
|
|
<div class="code">
|
|
<pre>
|
|
X< int *const& > x2; x2.b();
|
|
X< int const*const& > x3; x3.b();
|
|
X< int const& > x4; x4.b();
|
|
</pre>
|
|
</div>
|
|
<p> Now, given just these two default typemaps, where T is analogous to
|
|
SWIGTYPE:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(...) SWIGTYPE { ... }
|
|
%typemap(...) SWIGTYPE const& { ... }
|
|
</pre>
|
|
</div>
|
|
<p> The generic default typemap <tt>SWIGTYPE</tt> is used with most
|
|
types, such as</p>
|
|
<div class="code">
|
|
<pre>
|
|
int &
|
|
</pre>
|
|
</div>
|
|
<p> and the following all match the <tt>SWIGTYPE const&</tt> typemap,
|
|
just like the partial template matching:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int *const&
|
|
int const*const&
|
|
int const&
|
|
</pre>
|
|
</div>
|
|
<p> Note that the template and typemap matching rules are not identical
|
|
for all default typemaps though, for example, with arrays.</p>
|
|
<p> For non-default typemaps, one might expect SWIG to follow the fully
|
|
specialized template rules. This is nearly the case, but not quite.
|
|
Consider a very similar example to the earlier partially specialized
|
|
template but this time there is a fully specialized template:</p>
|
|
<div class="code">
|
|
<pre>
|
|
template <typename T> struct Y { void a(); };
|
|
template <> struct Y< int const & > { void b(); };
|
|
</pre>
|
|
</div>
|
|
<p> Only the one type matches the specialized template exactly:</p>
|
|
<div class="code">
|
|
<pre>
|
|
Y< int & > y1; y1.a();
|
|
Y< int *const& > y2; y2.a();
|
|
Y< int const *const& > y3; y3.a();
|
|
Y< int const& > y4; y4.b(); // fully specialized match
|
|
</pre>
|
|
</div>
|
|
<p> Given typemaps with the same types used for the template declared
|
|
above, where T is again analogous to SWIGTYPE:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(...) SWIGTYPE { ... }
|
|
%typemap(...) int const& { ... }
|
|
</pre>
|
|
</div>
|
|
<p> The comparison between non-default typemaps and fully specialized
|
|
single parameter templates turns out to be the same, as just the one
|
|
type will match the non-default typemap:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int &
|
|
int *const&
|
|
int const*const&
|
|
int const& // matches non-default typemap int const&
|
|
</pre>
|
|
</div>
|
|
<p> However, if a non-const type is used instead:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(...) SWIGTYPE { ... }
|
|
%typemap(...) int & { ... }
|
|
</pre>
|
|
</div>
|
|
<p> then there is a clear difference to template matching as both the
|
|
const and non-const types match the typemap:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int & // matches non-default typemap int &
|
|
int *const&
|
|
int const*const&
|
|
int const& // matches non-default typemap int &
|
|
</pre>
|
|
</div>
|
|
<p> There are other subtle differences such as typedef handling, but at
|
|
least it should be clear that the typemap matching rules are similar to
|
|
those for specialized template handling.</p>
|
|
<h3><a name="Typemaps_debugging_search">14.3.6 Debugging typemap pattern
|
|
matching</a></h3>
|
|
<p> There are two useful debug command line options available for
|
|
debugging typemaps, <tt>-debug-tmsearch</tt> and <tt>-debug-tmused</tt>
|
|
.</p>
|
|
<p> The <tt>-debug-tmsearch</tt> option is a verbose option for
|
|
debugging typemap searches. This can be very useful for watching the
|
|
pattern matching process in action and for debugging which typemaps are
|
|
used. The option displays all the typemaps and types that are looked
|
|
for until a successful pattern match is made. As the display includes
|
|
searches for each and every type needed for wrapping, the amount of
|
|
information displayed can be large. Normally you would manually search
|
|
through the displayed information for the particular type that you are
|
|
interested in.</p>
|
|
<p> For example, consider some of the code used in the <a href="#Typemaps_typedef_reductions">
|
|
Typedef reductions</a> section already covered:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef int Integer;
|
|
typedef Integer Row4[4];
|
|
void foo(Row4 rows[10]);
|
|
</pre>
|
|
</div>
|
|
<p> A sample of the debugging output is shown below for the "in"
|
|
typemap:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
swig -perl -debug-tmsearch example.i
|
|
...
|
|
example.h:3: Searching for a suitable 'in' typemap for: Row4 rows[10]
|
|
Looking for: Row4 rows[10]
|
|
Looking for: Row4 [10]
|
|
Looking for: Row4 rows[ANY]
|
|
Looking for: Row4 [ANY]
|
|
Looking for: Integer rows[10][4]
|
|
Looking for: Integer [10][4]
|
|
Looking for: Integer rows[ANY][ANY]
|
|
Looking for: Integer [ANY][ANY]
|
|
Looking for: int rows[10][4]
|
|
Looking for: int [10][4]
|
|
Looking for: int rows[ANY][ANY]
|
|
Looking for: int [ANY][ANY]
|
|
Looking for: SWIGTYPE rows[ANY][ANY]
|
|
Looking for: SWIGTYPE [ANY][ANY]
|
|
Looking for: SWIGTYPE rows[ANY][]
|
|
Looking for: SWIGTYPE [ANY][]
|
|
Looking for: SWIGTYPE *rows[ANY]
|
|
Looking for: SWIGTYPE *[ANY]
|
|
Looking for: SWIGTYPE rows[ANY]
|
|
Looking for: SWIGTYPE [ANY]
|
|
Looking for: SWIGTYPE rows[]
|
|
Looking for: SWIGTYPE []
|
|
Using: %typemap(in) SWIGTYPE []
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> showing that the best default match supplied by SWIG is the <tt>
|
|
SWIGTYPE []</tt> typemap. As the example shows, the successful match
|
|
displays the used typemap source including typemap method, type and
|
|
optional name in one of these simplified formats:</p>
|
|
<ul>
|
|
<li> <tt>Using: %typemap(method) type name</tt></li>
|
|
<li> <tt>Using: %typemap(method) type name = type2 name2</tt></li>
|
|
<li> <tt>Using: %apply type2 name2 { type name }</tt></li>
|
|
</ul>
|
|
<p> This information might meet your debugging needs, however, you might
|
|
want to analyze further. If you next invoke SWIG with the <tt>-E</tt>
|
|
option to display the preprocessed output, and search for the
|
|
particular typemap used, you'll find the full typemap contents (example
|
|
shown below for Python):</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in, noblock=1) SWIGTYPE [] (void *argp = 0, int res = 0) {
|
|
res = SWIG_ConvertPtr($input, &argp, $descriptor, $disown | 0 );
|
|
if (!SWIG_IsOK(res)) {
|
|
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument "
|
|
"$argnum"" of type '" "$type""'");
|
|
}
|
|
$1 = ($ltype)(argp);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The generated code for the <tt>foo</tt> wrapper will then contain
|
|
the snippets of the typemap with the special variables expanded. The
|
|
rest of this chapter will need reading though to fully understand all
|
|
of this, however, the relevant parts of the generated code for the
|
|
above typemap can be seen below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIGINTERN PyObject *_wrap_foo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
|
...
|
|
void *argp1 = 0 ;
|
|
int res1 = 0 ;
|
|
...
|
|
res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_a_4__int, 0 | 0 );
|
|
if (!SWIG_IsOK(res1)) {
|
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "foo" "', argument "
|
|
"1"" of type '" "int [10][4]""'");
|
|
}
|
|
arg1 = (int (*)[4])(argp1);
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Searches for multi-argument typemaps are not mentioned unless a
|
|
matching multi-argument typemap does actually exist. For example, the
|
|
output for the code in the <a href="#Typemaps_multi_argument_typemaps_patterns">
|
|
earlier multi-arguments section</a> is as follows:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
...
|
|
example.h:39: Searching for a suitable 'in' typemap for: char *buffer
|
|
Looking for: char *buffer
|
|
Multi-argument typemap found...
|
|
Using: %typemap(in) (char *buffer, int len)
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> The second option for debugging is <tt>-debug-tmused</tt> and this
|
|
displays the typemaps used. This option is a less verbose version of
|
|
the <tt>-debug-tmsearch</tt> option as it only displays each
|
|
successfully found typemap on a separate single line. The output
|
|
displays the type, and name if present, the typemap method in brackets
|
|
and then the actual typemap used in the same simplified format output
|
|
by the <tt>-debug-tmsearch</tt> option. Below is the output for the
|
|
example code at the start of this section on debugging.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -perl -debug-tmused example.i
|
|
example.h:3: Typemap for Row4 rows[10] (in) : %typemap(in) SWIGTYPE []
|
|
example.h:3: Typemap for Row4 rows[10] (typecheck) : %typemap(typecheck) SWIGTYPE *
|
|
example.h:3: Typemap for Row4 rows[10] (freearg) : %typemap(freearg) SWIGTYPE []
|
|
example.h:3: Typemap for void foo (out) : %typemap(out) void
|
|
</pre>
|
|
</div>
|
|
<p> Now, consider the following interface file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%{
|
|
void set_value(const char* val) {}
|
|
%}
|
|
|
|
%typemap(check) char *NON_NULL {
|
|
if (!$1) {
|
|
/* ... error handling ... */
|
|
}
|
|
}
|
|
|
|
// use default pointer handling instead of strings
|
|
%apply SWIGTYPE * { const char* val, const char* another_value }
|
|
|
|
%typemap(check) const char* val = char* NON_NULL;
|
|
|
|
%typemap(arginit, noblock=1) const char* val {
|
|
$1 = "";
|
|
}
|
|
|
|
void set_value(const char* val);
|
|
|
|
</pre>
|
|
</div>
|
|
<p> and the output debug:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
swig -perl5 -debug-tmused example.i
|
|
example.i:21: Typemap for char const *val (arginit) : %typemap(arginit) char const *val
|
|
example.i:21: Typemap for char const *val (in) : %apply SWIGTYPE * { char const *val }
|
|
example.i:21: Typemap for char const *val (typecheck) : %apply SWIGTYPE * { char const *val }
|
|
example.i:21: Typemap for char const *val (check) : %typemap(check) char const *val = char *NON_NULL
|
|
example.i:21: Typemap for char const *val (freearg) : %apply SWIGTYPE * { char const *val }
|
|
example.i:21: Typemap for void set_value (out) : %typemap(out) void
|
|
</pre>
|
|
</div>
|
|
<p> The following observations about what is displayed can be noted (the
|
|
same applies for <tt>-debug-tmsearch</tt>):</p>
|
|
<ul>
|
|
<li> The relevant typemap is shown, but for typemap copying, the
|
|
appropriate <tt>%typemap</tt> or <tt>%apply</tt> is displayed, for
|
|
example, the "check" and "in" typemaps.</li>
|
|
<li> The typemap modifiers are not shown, eg the <tt>noblock=1</tt>
|
|
modifier in the "arginit" typemap.</li>
|
|
<li> The exact <tt>%apply</tt> statement might look different to what is
|
|
in the actual code. For example, the <tt>const char* another_value</tt>
|
|
is not shown as it is not relevant here. Also the types may be
|
|
displayed slightly differently - <tt>char const *</tt> and not <tt>
|
|
const char*</tt>.</li>
|
|
</ul>
|
|
<h2><a name="Typemaps_nn21">14.4 Code generation rules</a></h2>
|
|
<p> This section describes rules by which typemap code is inserted into
|
|
the generated wrapper code.</p>
|
|
<h3><a name="Typemaps_nn22">14.4.1 Scope</a></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);
|
|
%}
|
|
%typemap(in, noblock=1) int {
|
|
$1 = PyInt_AsLong($input);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> These three 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. Note that only
|
|
the third of the three typemaps have the typemap code passed through
|
|
the SWIG preprocessor.</p>
|
|
<h3><a name="Typemaps_nn23">14.4.2 Declaring new local variables</a></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>There is an exception: if the variable name starts with the <tt>
|
|
_global_</tt> prefix, the argument number is not appended. Such
|
|
variables can be used throughout the generated wrapper function. For
|
|
example, the above typemap could be rewritten to use <tt>_global_temp</tt>
|
|
instead of <tt>temp</tt> and the generated code would then contain a
|
|
single <tt>_global_temp</tt> variable instead of <tt>temp1</tt>, <tt>
|
|
temp2</tt> and <tt>temp3</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) std::string * <b>(std::string _global_temp)</b> {
|
|
... as above ...
|
|
}
|
|
</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 (input typemaps such as the "in" typemap).</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">14.4.3 Special variables</a></h3>
|
|
<p> Special variables are prefixed with a <tt>$</tt> and are expanded by
|
|
SWIG as part of the code generation process.</p>
|
|
<h4><a name="Typemaps_type_special_variables">14.4.3.1 Type related
|
|
special variables</a></h4>
|
|
<p> Within all typemaps, the following special variables are expanded.
|
|
These are related in some way to a typemap's type. 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 type related 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>
|
|
<h4><a name="Typemaps_non_type_special_variables">14.4.3.2 Non-type
|
|
related special variables</a></h4>
|
|
<p> The following are additional special variables. These are not
|
|
specifically related to a typemap's type.</p>
|
|
<center>
|
|
<table border="1" summary="Non-type related special variables">
|
|
<tr><th>Variable</th><th>Meaning</th></tr>
|
|
<tr><td>$<em>isvoid</em></td><td> Expands to 1 if the wrapped function
|
|
has a void return, otherwise expands to 0. Note that it expands to 1 in
|
|
destructors and 0 in constructors.</td></tr>
|
|
<tr><td>$<em>symname</em></td><td> Name of function/method being
|
|
wrapped.</td></tr>
|
|
</table>
|
|
</center>
|
|
<h3><a name="Typemaps_special_variable_macros">14.4.4 Special variable
|
|
macros</a></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">14.4.4.1
|
|
$descriptor(type)</a></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">14.4.4.2 $typemap(method,
|
|
typepattern)</a></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>
|
|
<h4><a name="Typemaps_special_macro_typemap_attribute">14.4.4.3
|
|
$typemap(method:attribute, typepattern)</a></h4>
|
|
<p> An enhanced version of <tt>$typemap</tt> provides access to typemap
|
|
attributes by appending a colon and the attribute name after the method
|
|
name. In the example below, "cstype" is the typemap method and "out" is
|
|
the typemap attribute.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(cstype, out="object") XClass "XClass"
|
|
%typemap(cscode) BarClass %{
|
|
$typemap(cstype:out, XClass) bar()
|
|
{
|
|
return null;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> which expands to</p>
|
|
<div class="code">
|
|
<pre>
|
|
object bar()
|
|
{
|
|
return null;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> Support for typemap attributes in <tt>
|
|
$typemap</tt> was introduced in SWIG-4.1.0.</p>
|
|
<h3><a name="Typemaps_special_variable_attributes">14.4.5 Special
|
|
variables and typemap attributes</a></h3>
|
|
<p> As of SWIG-3.0.7 typemap attributes will also expand special
|
|
variables and special variable macros.</p>
|
|
<p> Example usage showing the expansion in the 'out' attribute (C#
|
|
specific) as well as the main typemap body:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(ctype, out="$*1_ltype") unsigned int& "$*1_ltype"
|
|
</pre>
|
|
</div>
|
|
<p> is equivalent to the following as <tt>$*1_ltype</tt> expands to <tt>
|
|
unsigned int</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(ctype, out="unsigned int") unsigned int& "unsigned int"
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Typemaps_special_variables_and_macros">14.4.6 Special
|
|
variables combined with special variable macros</a></h3>
|
|
<p> Special variables can also be used within special variable macros.
|
|
The special variables are expanded before they are used in the special
|
|
variable macros.</p>
|
|
<p> Consider the following C# typemaps:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(cstype) unsigned int "uint"
|
|
%typemap(cstype, out="$typemap(cstype, $*1_ltype)") unsigned int& "$typemap(cstype, $*1_ltype)"
|
|
</pre>
|
|
</div>
|
|
<p> Special variables are expanded first and hence the above is
|
|
equivalent to:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(cstype) unsigned int "uint"
|
|
%typemap(cstype, out="$typemap(cstype, unsigned int)") unsigned int& "$typemap(cstype, unsigned int)"
|
|
</pre>
|
|
</div>
|
|
<p> which then expands to:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(cstype) unsigned int "uint"
|
|
%typemap(cstype, out="uint") unsigned int& "uint"
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Typemaps_nn25">14.5 Common typemap methods</a></h2>
|
|
<p> The family of typemaps recognized by a language module may vary.
|
|
However, the following typemap methods are nearly universal:</p>
|
|
<h3><a name="Typemaps_nn26">14.5.1 "in" typemap</a></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 additional special variables are available:</p>
|
|
<div class="code">
|
|
<pre>
|
|
$input - Input object holding value to be converted.
|
|
</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 multiple
|
|
adjacent C/C++ arguments.</p>
|
|
<h3><a name="Typemaps_nn27">14.5.2 "typecheck" typemap</a></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. Set to 1 if the input argument is the correct type
|
|
otherwise set to 0.</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 the <a href="#Typemaps_overloading">
|
|
Typemaps and overloading</a> section.</p>
|
|
<h3><a name="Typemaps_nn28">14.5.3 "out" typemap</a></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 additional special variables are available.</p>
|
|
<div class="code">
|
|
<pre>
|
|
$result - Result object returned to target language.
|
|
</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">14.5.4 "arginit" typemap</a></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">14.5.5 "default" typemap</a></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">14.5.6 "check" typemap</a></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">14.5.7 "argout" typemap</a></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 additional special variables are available.</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
$result - Result object returned to target language.
|
|
$input - The original input object passed.
|
|
</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 file for examples.</p>
|
|
<h3><a name="Typemaps_nn33">14.5.8 "freearg" typemap</a></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">14.5.9 "newfree" typemap</a></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="#Customization_ownership">Object ownership and
|
|
%newobject</a> for further details.</p>
|
|
<h3><a name="Typemaps_ret">14.5.10 "ret" typemap</a></h3>
|
|
<p> The "ret" typemap is not used very often, but can be useful for
|
|
anything associated with the return type, such as resource management,
|
|
return value error checking, etc. Usually this can all be done in the
|
|
"out" typemap, but sometimes it is handy to use the "out" typemap code
|
|
untouched and add to the generated code using the code in the "ret"
|
|
typemap. One such case is memory clean up. For example, a <tt>
|
|
stringheap_t</tt> type is defined indicating that the returned memory
|
|
must be deleted and a <tt>string_t</tt> type is defined indicating that
|
|
the returned memory must not be deleted.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(ret) stringheap_t %{
|
|
free($1);
|
|
%}
|
|
|
|
typedef char * string_t;
|
|
typedef char * stringheap_t;
|
|
|
|
string_t MakeString1();
|
|
stringheap_t MakeString2();
|
|
</pre>
|
|
</div>
|
|
<p> The "ret" typemap above will only be used for <tt>MakeString2</tt>,
|
|
but both functions will use the default "out" typemap for <tt>char *</tt>
|
|
provided by SWIG. The code above would ensure the appropriate memory is
|
|
freed in all target languages as the need to provide custom "out"
|
|
typemaps (which involve target language specific code) is not
|
|
necessary.</p>
|
|
<p> This approach is an alternative to using the "newfree" typemap and <tt>
|
|
%newobject</tt> as there is no need to list all the functions that
|
|
require the memory cleanup, it is purely done on types.</p>
|
|
<h3><a name="Typemaps_nn35">14.5.11 "memberin" typemap</a></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">14.5.12 "varin" typemap</a></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">14.5.13 "varout" typemap</a></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="Typemaps_throws_typemap">14.5.14 "throws" typemap</a></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 (see <a href="#SWIGPlus_catches">Exception
|
|
handling with %catches</a>). 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;
|
|
%}
|
|
|
|
// Either an exception specification on the method
|
|
void bar() throw (const char *);
|
|
|
|
// Or a %catches feature attached to the method
|
|
%catches(const char *) bar();
|
|
void bar();
|
|
</pre>
|
|
</div>
|
|
<p> As can be seen from the resulting generated code below, SWIG
|
|
generates an exception handler when wrapping the <tt>bar</tt> function
|
|
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 but
|
|
they do throw exceptions and you are not using <tt>%catches</tt>, SWIG
|
|
cannot know how to deal with them. Please also see the <a href="#Customization_exception">
|
|
Exception handling with %exception</a> section for another way to handle
|
|
exceptions.</p>
|
|
<h2><a name="Typemaps_nn39">14.6 Some typemap examples</a></h2>
|
|
<p> This section contains a few examples. Consult language module
|
|
documentation for more examples.</p>
|
|
<h3><a name="Typemaps_nn40">14.6.1 Typemaps for arrays</a></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");
|
|
SWIG_fail;
|
|
}
|
|
if (PySequence_Length($input) != 4) {
|
|
PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected 4 elements");
|
|
SWIG_fail;
|
|
}
|
|
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");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
$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");
|
|
SWIG_fail;
|
|
}
|
|
if (PySequence_Length($input) != $1_dim0) {
|
|
PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected $1_dim0 elements");
|
|
SWIG_fail;
|
|
}
|
|
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");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
$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");
|
|
SWIG_fail;
|
|
}
|
|
if (PySequence_Length($input) != $1_dim0) {
|
|
PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected $1_dim0 elements");
|
|
SWIG_fail;
|
|
}
|
|
$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 {
|
|
free($1);
|
|
PyErr_SetString(PyExc_ValueError, "Sequence elements must be numbers");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
}
|
|
%typemap(freearg) float value[ANY] {
|
|
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
|
|
example.i:10: Warning 462: Unable to set variable of type float [4].
|
|
</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">14.6.2 Implementing constraints with
|
|
typemaps</a></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");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
|
|
</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>
|
|
<h2><a name="Typemaps_nn43">14.7 Typemaps for multiple target languages</a>
|
|
</h2>
|
|
<p> The code within typemaps is usually language dependent, however,
|
|
many target 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, but this was deprecated in SWIG 1.3.28 and support finally
|
|
dropped completely in SWIG 4.1.0 so you'll need to update any remaining
|
|
uses to use the approach above. For example,
|
|
<br> <tt>%typemap(ruby, in) int "$1 = NUM2INT($input);"</tt>.</p>
|
|
<h2><a name="Typemaps_optimal">14.8 Optimal code generation when
|
|
returning by value</a></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 the number of 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($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
|
|
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($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(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(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="#Customization_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 ignored
|
|
example.i:14: Warning 474: in the out typemap 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, that is, for the <tt>$1</tt>
|
|
substitution.</p>
|
|
<p> Secondly, if the typemap 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
|
|
example.i:7: Warning 475: optimal attribute usage in the out typemap.
|
|
</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">14.9 Multi-argument
|
|
typemaps</a></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. Multi-argument
|
|
typemaps help in this situation.</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 a 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");
|
|
SWIG_fail;
|
|
}
|
|
$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");
|
|
SWIG_fail;
|
|
}
|
|
$2[i] = PyString_AsString(s);
|
|
}
|
|
$2[i] = 0;
|
|
}
|
|
|
|
%typemap(freearg) (int argc, char *argv[]) {
|
|
free($2);
|
|
}
|
|
|
|
/* Required for C++ method overloading */
|
|
%typecheck(SWIG_TYPECHECK_STRING_ARRAY) (int argc, char *argv[]) {
|
|
$1 = PyList_Check($input) ? 1 : 0;
|
|
}
|
|
</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> Don't forget to also provide a suitable <a href="#Typemaps_overloading">
|
|
typemap for overloaded functions</a>, such as <tt>%typecheck</tt> shown
|
|
for foo above. This is only required if the function is overloaded in
|
|
C++.</p>
|
|
<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");
|
|
SWIG_fail;
|
|
}
|
|
$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");
|
|
SWIG_fail;
|
|
}
|
|
$2 = PyInt_AsLong($input);
|
|
if ($2 < 0) {
|
|
PyErr_SetString(PyExc_ValueError, "Positive integer expected");
|
|
SWIG_fail;
|
|
}
|
|
$1 = (void *) malloc($2);
|
|
}
|
|
|
|
// Return the buffer. Discarding any previous return result
|
|
%typemap(argout) (void *rbuffer, size_t len) {
|
|
Py_DecRef($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). Note that
|
|
multi-argument typemaps cannot deal with non-consecutive C/C++
|
|
arguments; a workaround such as a helper function re-ordering the
|
|
arguments to make them consecutive will need to be written.</p>
|
|
<h2><a name="Typemaps_warnings">14.10 Typemap warnings</a></h2>
|
|
<p> Warnings can be added to typemaps so that SWIG generates a warning
|
|
message whenever the typemap is used. See the information in the <a href="#Warnings_nn5">
|
|
issuing warnings</a> section.</p>
|
|
<h2><a name="Typemaps_fragments">14.11 Typemap fragments</a></h2>
|
|
<p> The primary purpose of fragments is to reduce code bloat that
|
|
repeated use of typemap code can lead to. Fragments are snippets of
|
|
code that can be thought of as code dependencies of a typemap. If a
|
|
fragment is used by more than one typemap, then the snippet of code
|
|
within the fragment is only generated once. Code bloat is typically
|
|
reduced by moving typemap code into a support function and then placing
|
|
the support function into a fragment.</p>
|
|
<p> For example, if you have a very long typemap</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) MyClass * {
|
|
MyClass *value = 0;
|
|
|
|
... many lines of marshalling code ...
|
|
|
|
$result = value;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> the same marshalling code is often repeated in several typemaps,
|
|
such as "in", "varin", "directorout", etc. SWIG copies the code for
|
|
each argument that requires the typemap code, easily leading to code
|
|
bloat in the generated code. To eliminate this, define a fragment that
|
|
includes the common marshalling code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("AsMyClass", "header") {
|
|
MyClass *AsMyClass(PyObject *obj) {
|
|
MyClass *value = 0;
|
|
|
|
... many lines of marshalling code ...
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
%typemap(in, fragment="AsMyClass") MyClass * {
|
|
$result = AsMyClass($input);
|
|
}
|
|
|
|
%typemap(varin, fragment="AsMyClass") MyClass * {
|
|
$result = AsMyClass($input);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> When the "in" or "varin" typemaps for MyClass are required, the
|
|
contents of the fragment called "AsMyClass" are added to the "header"
|
|
section within the generated code, and then the typemap code is
|
|
emitted. Hence, the method <tt>AsMyClass</tt> will be generated into
|
|
the wrapper code before any typemap code that calls it.</p>
|
|
<p> To define a fragment you need a fragment name, a section name for
|
|
generating the fragment code into, and the code itself. See <a href="#SWIG_nn42">
|
|
Code insertion blocks</a> for a full list of section names. Usually the
|
|
section name used is "header". Different delimiters can be used:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("my_name", "header") %{ ... %}
|
|
%fragment("my_name", "header") { ... }
|
|
%fragment("my_name", "header") " ... "
|
|
</pre>
|
|
</div>
|
|
<p> and these follow the usual preprocessing rules mentioned in the <a href="#Preprocessor_delimiters">
|
|
Preprocessing delimiters</a> section. The following are some rules and
|
|
guidelines for using fragments:</p>
|
|
<ol>
|
|
<li>
|
|
<p> A fragment is added to the wrapping code only once. When using the <tt>
|
|
MyClass *</tt> typemaps above and wrapping the method:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void foo(MyClass *a, MyClass *b);
|
|
</pre>
|
|
</div>
|
|
<p> the generated code will look something like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
MyClass *AsMyClass(PyObject *obj) {
|
|
...
|
|
}
|
|
|
|
void _wrap_foo(...) {
|
|
....
|
|
arg1 = AsMyClass(obj1);
|
|
arg2 = AsMyClass(obj2);
|
|
...
|
|
foo(arg1, arg2);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> even as there is duplicated typemap code to process both <tt>a</tt>
|
|
and <tt>b</tt>, the <tt>AsMyClass</tt> method will be defined only
|
|
once.</p>
|
|
</li>
|
|
<li>
|
|
<p> A fragment should only be defined once. If there is more than one
|
|
definition, the first definition is the one used. All other definitions
|
|
are silently ignored. For example, if you have</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("AsMyClass", "header") { ...definition 1... }
|
|
....
|
|
%fragment("AsMyClass", "header") { ...definition 2... }
|
|
</pre>
|
|
</div>
|
|
<p> only the first definition is used. In this way you can override the
|
|
default fragments in a SWIG library by defining your fragment before
|
|
the library <tt>%include</tt>. Note that this behavior is the opposite
|
|
to typemaps, where the last typemap defined/applied prevails. Fragments
|
|
follow the first-in-first-out convention since they are intended to be
|
|
global, while typemaps are intended to be locally specialized.</p>
|
|
</li>
|
|
<li>
|
|
<p> Fragment names cannot contain commas.</p>
|
|
</li>
|
|
<li>
|
|
<p> A fragment can use one or more additional fragments, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("<limits.h>", "header") %{
|
|
#include <limits.h>
|
|
%}
|
|
|
|
|
|
%fragment("AsMyClass", "header", fragment="<limits.h>") {
|
|
MyClass *AsMyClass(PyObject *obj) {
|
|
MyClass *value = 0;
|
|
|
|
... some marshalling code ...
|
|
|
|
if (ival < CHAR_MIN /*defined in <limits.h>*/) {
|
|
...
|
|
} else {
|
|
...
|
|
}
|
|
...
|
|
return value;
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> in this case, when the "AsMyClass" fragment is emitted, it also
|
|
triggers the inclusion of the "<limits.h>" fragment.</p>
|
|
</li>
|
|
<li>
|
|
<p> A fragment can have dependencies on a number of other fragments, for
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("bigfragment", "header", fragment="frag1", fragment="frag2", fragment="frag3") "";
|
|
</pre>
|
|
</div>
|
|
<p> When the "bigfragment" is used, the three dependent fragments
|
|
"frag1", "frag2" and "frag3" are also pulled in. Note that as
|
|
"bigframent" is empty (the empty string - ""), it does not add any code
|
|
itself, but merely triggers the inclusion of the other fragments.</p>
|
|
</li>
|
|
<li>
|
|
<p> A typemap can also use more than one fragment:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap("in", fragment="frag1", fragment="frag2", fragment="frag3") {...}
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility note:</b> The ability to use multiple <tt>fragment</tt>
|
|
keys as shown above was introduced in SWIG-4.1.0.</p>
|
|
<p> Multiple fragments can alternatively be specified as a comma
|
|
separated list value in a single <tt>fragment</tt> key. Note that no
|
|
whitespace is allowed within this comma separated list. The following
|
|
is the equivalent to the above:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in, fragment="frag1,frag2,frag3") {...}
|
|
</pre>
|
|
</div>
|
|
<p> which in turn is functionally equivalent to:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in, fragment="bigfragment") {...}
|
|
</pre>
|
|
</div>
|
|
<p> when used with the "bigfragment" defined above.</p>
|
|
</li>
|
|
<li>
|
|
<p> Finally, you can force the inclusion of a fragment at any point in
|
|
the generated code as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("bigfragment");
|
|
</pre>
|
|
</div>
|
|
<p> which, for example, is very useful inside a template class. Another
|
|
useful case is when using <tt>%extend</tt> inside a class where the
|
|
additional code in the <tt>%extend</tt> block depends on the contents
|
|
of the fragment.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("<limits.h>", "header") %{
|
|
#include <limits.h>
|
|
%}
|
|
|
|
struct X {
|
|
...
|
|
%extend {
|
|
%fragment("<limits.h>");
|
|
bool check(short val) {
|
|
if (val < SHRT_MIN /*defined in <limits.h>*/) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Forced inclusion of fragments can be used as a replacement for <a href="#SWIG_nn42">
|
|
code insertion block</a>, ensuring the code block is only generated
|
|
once. Consider the contents of FileA.i below which first uses a code
|
|
insertion block and then a forced fragment inclusion to generate code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// FileA.i
|
|
%{
|
|
#include <stdio.h>
|
|
%}
|
|
%fragment("<limits.h>");
|
|
</pre>
|
|
</div>
|
|
<p> and another file including the above:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// FileB.i
|
|
%include "FileA.i"
|
|
</pre>
|
|
</div>
|
|
<p> The resulting code in the wrappers for FileB.i is:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#include <stdio.h>
|
|
|
|
#include <limits.h>
|
|
</pre>
|
|
</div>
|
|
<p> A note of caution must be mentioned when using <tt>%fragment</tt>
|
|
forced inclusion or code insertion blocks with <tt>%import</tt>. If <tt>
|
|
%import</tt> is used instead:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// FileC.i
|
|
%import "FileA.i"
|
|
</pre>
|
|
</div>
|
|
<p> then nothing is generated in the resulting code in the wrappers for
|
|
FileC.i. This is because <tt>%import</tt> is for collecting type
|
|
information and does not result in any code being generated, see <a href="#Preprocessor_nn3">
|
|
File Imports</a>.</p>
|
|
</li>
|
|
</ol>
|
|
<p> Most readers will probably want to skip the next two sub-sections on
|
|
advanced fragment usage unless a desire to really get to grips with
|
|
some powerful but tricky macro and fragment usage that is used in parts
|
|
of the SWIG typemap library.</p>
|
|
<h3><a name="Typemaps_fragment_type_specialization">14.11.1 Fragment
|
|
type specialization</a></h3>
|
|
<p> Fragments can be<i> type specialized</i>. The syntax is as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("name", "header") { ...a type independent fragment... }
|
|
%fragment("name"{type}, "header") { ...a type dependent fragment... }
|
|
</pre>
|
|
</div>
|
|
<p> where <tt>type</tt> is a C/C++ type. Like typemaps, fragments can
|
|
also be used inside templates, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
template <class T>
|
|
struct A {
|
|
%fragment("incode"{A<T>}, "header") {
|
|
... 'incode' specialized fragment ...
|
|
}
|
|
|
|
%typemap(in, fragment="incode"{A<T>}) {
|
|
... here we use the 'type specialized' fragment "incode"{A<T>} ...
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Typemaps_automatic_specialization">14.11.2 Fragments and
|
|
automatic typemap specialization</a></h3>
|
|
<p> Since fragments can be type specialized, they can be elegantly used
|
|
to specialize typemaps. For example, if you have something like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("incode"{float}, "header") {
|
|
float in_method_float(PyObject *obj) {
|
|
...
|
|
}
|
|
}
|
|
|
|
%fragment("incode"{long}, "header") {
|
|
float in_method_long(PyObject *obj) {
|
|
...
|
|
}
|
|
}
|
|
|
|
// %my_typemaps macro definition
|
|
%define %my_typemaps(Type)
|
|
%typemap(in, fragment="incode"{Type}) Type {
|
|
value = in_method_##Type(obj);
|
|
}
|
|
%enddef
|
|
|
|
%my_typemaps(float);
|
|
%my_typemaps(long);
|
|
</pre>
|
|
</div>
|
|
<p> then the proper <tt>"incode"{float}</tt> or <tt>"incode"{long}</tt>
|
|
fragment will be used, and the <tt>in_method_float</tt> and <tt>
|
|
in_method_long</tt> methods will be called whenever the <tt>float</tt>
|
|
or <tt>long</tt> types are used as input parameters.</p>
|
|
<p> This feature is used a lot in the typemaps shipped in the SWIG
|
|
library for some scripting languages. The interested (or very brave)
|
|
reader can take a look at the fragments.swg file shipped with SWIG to
|
|
see this in action.</p>
|
|
<h2><a name="Typemaps_runtime_type_checker">14.12 The run-time type
|
|
checker</a></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, regardless 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">14.12.1 Implementation</a></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 statically 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 {
|
|
public:
|
|
int x;
|
|
};
|
|
|
|
class Bar {
|
|
public:
|
|
int y;
|
|
};
|
|
|
|
class FooBar : public Foo, public Bar {
|
|
public:
|
|
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 similar to the following (simplified for brevity):</p>
|
|
<div class="code">
|
|
<pre>
|
|
if (!SWIG_IsOK(SWIG_ConvertPtr(obj0, (void **) &arg1, SWIGTYPE_p_Foo, 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method 'GrabVal', expecting type Foo");
|
|
}
|
|
</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 object and uses this information to generate a C++
|
|
pointer. The <tt>SWIG_IsOK</tt> macro checks the return value for
|
|
errors and <tt>SWIG_exception_fail</tt> can be called to raise an
|
|
exception in the target language. 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">14.12.2 Usage</a></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="#Modules_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_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
}
|
|
</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_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
|
Bar *temp;
|
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &temp, $descriptor(Bar *), 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo or Bar");
|
|
}
|
|
$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 of the generated 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">14.13 Typemaps and overloading</a></h2>
|
|
<p> This section does not apply to the statically typed languages like
|
|
Java and C#, where overloading of the types is handled much like C++ by
|
|
generating overloaded methods in the target language. In many of the
|
|
other target languages, SWIG still 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_ITERATOR 5
|
|
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_SIZE 47
|
|
SWIG_TYPECHECK_PTRDIFF 48
|
|
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_CPLXFLT 95
|
|
SWIG_TYPECHECK_CPLXDBL 100
|
|
SWIG_TYPECHECK_COMPLEX 105
|
|
SWIG_TYPECHECK_UNICHAR 110
|
|
SWIG_TYPECHECK_STDUNISTRING 115
|
|
SWIG_TYPECHECK_UNISTRING 120
|
|
SWIG_TYPECHECK_CHAR 130
|
|
SWIG_TYPECHECK_STDSTRING 135
|
|
SWIG_TYPECHECK_STRING 140
|
|
SWIG_TYPECHECK_PAIR 150
|
|
SWIG_TYPECHECK_STDARRAY 155
|
|
SWIG_TYPECHECK_VECTOR 160
|
|
SWIG_TYPECHECK_DEQUE 170
|
|
SWIG_TYPECHECK_LIST 180
|
|
SWIG_TYPECHECK_SET 190
|
|
SWIG_TYPECHECK_MULTISET 200
|
|
SWIG_TYPECHECK_MAP 210
|
|
SWIG_TYPECHECK_MULTIMAP 220
|
|
SWIG_TYPECHECK_STACK 230
|
|
SWIG_TYPECHECK_QUEUE 240
|
|
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
|
|
SWIG_TYPECHECK_OBJECT_ARRAY 1150
|
|
SWIG_TYPECHECK_BOOL_PTR 2015
|
|
SWIG_TYPECHECK_UINT8_PTR 2020
|
|
SWIG_TYPECHECK_INT8_PTR 2025
|
|
SWIG_TYPECHECK_UINT16_PTR 2030
|
|
SWIG_TYPECHECK_INT16_PTR 2035
|
|
SWIG_TYPECHECK_UINT32_PTR 2040
|
|
SWIG_TYPECHECK_INT32_PTR 2045
|
|
SWIG_TYPECHECK_UINT64_PTR 2050
|
|
SWIG_TYPECHECK_INT64_PTR 2055
|
|
SWIG_TYPECHECK_FLOAT_PTR 2080
|
|
SWIG_TYPECHECK_DOUBLE_PTR 2090
|
|
SWIG_TYPECHECK_CHAR_PTR 2130
|
|
SWIG_TYPECHECK_SWIGOBJECT 5000
|
|
</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 following 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;
|
|
}
|
|
|
|
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, noblock=1) SWIGTYPE * {
|
|
void *vptr = 0;
|
|
int res = SWIG_ConvertPtr($input, &vptr, $1_descriptor, 0);
|
|
$1 = SWIG_IsOK(res) ? 1 : 0;
|
|
}
|
|
|
|
%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 new typecheck code
|
|
or copy and modify existing typecheck code.</p>
|
|
<p> If you write a typecheck typemap and omit the precedence level, for
|
|
example commenting it out as shown below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(typecheck /*, precedence=SWIG_TYPECHECK_INTEGER*/) int {
|
|
$1 = PyInt_Check($input) ? 1 : 0;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> then the type is given a precedence higher than any other known
|
|
precedence level and a <a href="#Warnings">warning</a> is issued:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:18: Warning 467: Overloaded method foo(int) not supported (incomplete type
|
|
checking rule - no precedence level in typecheck typemap for 'int').
|
|
</pre>
|
|
</div>
|
|
<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 <a href="#SWIGPlus_overloaded_methods">
|
|
overloading</a> in the SWIG and C++ chapter.</li>
|
|
</ul>
|
|
<h3><a name="Typemaps_typecheck_pointer">14.13.1 SWIG_TYPECHECK_POINTER
|
|
precedence level and the typecheck typemap</a></h3>
|
|
<p> When it comes to overloading of a particular type passed by value,
|
|
pointer or reference (const and non-const), a C++ compiler can
|
|
disambiguate which overloaded function to call. However, SWIG
|
|
effectively treats these as pointers in the target language and thus as
|
|
equivalent types. For example, consider:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class X { ... };
|
|
void m(X const &c); // equivalent: void m(X *c);
|
|
void m(X &r); // equivalent: void m(X *r);
|
|
void m(X *p); // equivalent: void m(X *p);
|
|
</pre>
|
|
</div>
|
|
<p> These cannot be disambiguated in the target languages and so SWIG
|
|
will choose the first method and ignore the subsequent two methods. The
|
|
scripting languages do this by using the overload dispatch mechanism
|
|
described earlier and warnings indicate this:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:6: Warning 509: Overloaded method m(X &) effectively ignored,
|
|
example.i:5: Warning 509: as it is shadowed by m(X const &).
|
|
example.i:7: Warning 509: Overloaded method m(X *) effectively ignored,
|
|
example.i:5: Warning 509: as it is shadowed by m(X const &).
|
|
</pre>
|
|
</div>
|
|
<p> The statically typed languages like Java and C# automatically ignore
|
|
all but the first equivalent overloaded methods with warnings:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:6: Warning 516: Overloaded method m(X &) ignored,
|
|
example.i:5: Warning 516: using m(X const &) instead.
|
|
example.i:7: Warning 516: Overloaded method m(X *) ignored,
|
|
example.i:5: Warning 516: using m(X const &) instead.
|
|
</pre>
|
|
</div>
|
|
<p> You can select the overloaded method you would like to wrap by
|
|
ignoring the other two with <tt>%ignore</tt> or rename two of them with
|
|
<tt>%rename</tt> and this will of course remove the warnings too. The
|
|
problem of ambiguity is also discussed in the C++ chapter on <a href="#SWIGPlus_overloaded_methods">
|
|
overloading</a>.</p>
|
|
<p> So how does this work with respect to typemaps? The typemaps SWIG
|
|
provides to handle overloading for these three methods are from the
|
|
SWIGTYPE family. As discussed earlier, in <a href="#Typemaps_nn19">
|
|
Default typemap matching rules</a>, the <tt>SWIGTYPE &</tt> typemaps are
|
|
used for references and <tt>SWIGTYPE *</tt> typemaps are used for
|
|
pointers. SWIG uses the special <tt>SWIG_TYPECHECK_POINTER</tt> (0)
|
|
precedence level to handle these types in the "typecheck" typemap:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) SWIGTYPE & "..."
|
|
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) SWIGTYPE * "..."
|
|
</pre>
|
|
</div>
|
|
<p> When the SWIGTYPE "typecheck" typemaps use the <tt>
|
|
SWIG_TYPECHECK_POINTER</tt> precedence level, SWIG converts the type to
|
|
a pointer equivalent type and then uses the equivalent type to detect
|
|
if it can be disambiguated in an overloaded method in the target
|
|
language. In our example above, the equivalent types for <tt>X const &</tt>
|
|
, <tt>X &</tt> and <tt>X *</tt> are all <tt>X *</tt>. As they are the
|
|
same, they cannot be disambiguated and so just the first overloaded
|
|
method is chosen.</p>
|
|
<p> The automatic conversion to equivalent types and subsequent type
|
|
comparison is triggered via the use of the special <tt>
|
|
SWIG_TYPECHECK_POINTER</tt> precedence level and works for types passed
|
|
by value, pointer and reference. Alas, there are more ways to overload
|
|
a method that also need handling. C++ smart pointers are such a type
|
|
which can be disambiguated by a C++ compiler but not automatically by
|
|
SWIG. SWIG does not automatically know that a smart pointer has an
|
|
equivalent type, but it can be told manually. Just specify the
|
|
'equivalent' attribute in the "typecheck" typemap with a pointer to the
|
|
underlying type.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="X *") MySmartPtr<X> " ... "
|
|
|
|
void m(X &r); // equivalent: void m(X *r);
|
|
void m(MySmartPtr<X> s); // equivalent: void m(X *s);
|
|
</pre>
|
|
</div>
|
|
<p> Now SWIG will detect the two types are equivalent and generate valid
|
|
code by wrapping just the first overloaded method. You can of course
|
|
choose which method to wrap by ignoring one of them with <tt>%ignore</tt>
|
|
. Otherwise both can be wrapped by removing the overloading name
|
|
ambiguity by renaming one of them with <tt>%rename</tt>.</p>
|
|
<p> The 'equivalent' attribute is used in the implementation for the <a href="#Library_std_shared_ptr">
|
|
shared_ptr smart pointer</a> library.</p>
|
|
<h2><a name="Typemaps_nn48">14.14 More about %apply and %clear</a></h2>
|
|
<p> In order to implement certain kinds of program behavior, it is
|
|
sometimes necessary to write a family of typemap methods. For example,
|
|
to support output arguments, one often writes a family 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 a source type to one or more set of target types. 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> (source) typemap methods are
|
|
copied to <tt>int *retvalue</tt> and <tt>int32 *output</tt> (the
|
|
targets).</p>
|
|
<p> However, there is a subtle aspect of <tt>%apply</tt> that needs
|
|
clarification. Namely, if a target contains a typemap method that the
|
|
source does not, the target typemap method remains in place and
|
|
unchanged. 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>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;
|
|
}
|
|
}
|
|
|
|
%typemap(arginit) int *invalue %{
|
|
$1 = NULL;
|
|
%}
|
|
|
|
...
|
|
%apply int *INPUT { int *invalue };
|
|
%apply int *POSITIVE { int *invalue };
|
|
</pre>
|
|
</div>
|
|
<p> In this example, neither of the two <tt>%apply</tt> directives will
|
|
overwrite / delete the "arginit" typemap as neither has an "arginit"
|
|
typemap. The result is a family of three relevant typemaps for <tt>int
|
|
*invalue</tt>. Since <tt>%apply</tt> does not overwrite / delete any
|
|
existing rules, the only way to reset behavior is to delete them, such
|
|
as with the <tt>%clear</tt> directive. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%clear int *invalue;
|
|
</pre>
|
|
</div>
|
|
<p> will delete the typemaps for all the typemap methods; namely "in",
|
|
"check" and "arginit". Alternatively delete each one individually:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) int *invalue;
|
|
%typemap(check) int *invalue;
|
|
%typemap(arginit) int *invalue;
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Typemaps_nn47">14.15 Passing data between typemaps</a></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">14.16 C++ "this" pointer</a></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,
|
|
"invalid native object; delete() likely already called");
|
|
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 gives the argument a name other than <tt>
|
|
self</tt>.</p>
|
|
<h2><a name="Typemaps_nn51">14.17 Where to go for more information?</a></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">15 Customization Features</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Customization_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="#Customization_ownership">Object ownership and %newobject</a>
|
|
</li>
|
|
<li><a href="#Customization_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="#Customization_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="Customization_exception">15.1 Exception handling with
|
|
%exception</a></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) {
|
|
... handle error ...
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> How the exception is handled depends on the target language, for
|
|
example, Python:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%exception {
|
|
try {
|
|
$action
|
|
}
|
|
catch (RangeError) {
|
|
PyErr_SetString(PyExc_IndexError, "index out-of-bounds");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
</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 variables</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>
|
|
<h3><a name="Customization_nn3">15.1.1 Handling exceptions in C code</a></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">15.1.2 Exception handling with longjmp()</a>
|
|
</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">15.1.3 Handling C++ exceptions</a></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">15.1.4 Exception handlers for
|
|
variables</a></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">15.1.5 Defining different exception
|
|
handlers</a></h3>
|
|
<p> By default, the <tt>%exception</tt> directive creates an exception
|
|
handler that is used for all wrapper functions that follow it. Unless
|
|
there is a well-defined (and simple) error handling mechanism in place,
|
|
defining one universal exception handler may be unwieldy and result in
|
|
excessive code bloat since the handler is inlined into each wrapper
|
|
function.</p>
|
|
<p> To fix this, you can be more selective about how you use the <tt>
|
|
%exception</tt> directive. One approach is to only place it around
|
|
critical pieces of code. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%exception {
|
|
... your exception handler ...
|
|
}
|
|
/* Define critical operations that can throw exceptions here */
|
|
|
|
%exception;
|
|
|
|
/* Define non-critical operations that don't throw exceptions */
|
|
</pre>
|
|
</div>
|
|
<p> More precise control over exception handling can be obtained by
|
|
attaching an exception handler to specific declaration name. For
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%exception allocate {
|
|
try {
|
|
$action
|
|
}
|
|
catch (MemoryError) {
|
|
croak("Out of memory");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> In this case, the exception handler is only attached to declarations
|
|
named "allocate". This would include both global and member functions.
|
|
The names supplied to <tt>%exception</tt> follow the same rules as for <tt>
|
|
%rename</tt> described in the section on <a href="#SWIGPlus_ambiguity_resolution_renaming">
|
|
Renaming and ambiguity resolution</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>
|
|
<h3><a name="Customization_exception_special_variables">15.1.6 Special
|
|
variables for %exception</a></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>$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>
|
|
<tr><td>$isvoid</td><td>Expands to 1 if the wrapped function has a void
|
|
return, otherwise expands to 0. Note that it expands to 1 in
|
|
destructors and 0 in constructors.</td></tr>
|
|
<tr><td>$name</td><td>The C/C++ symbol name for the function.</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>$parentclassname</td><td>The parent class name (if any) for a
|
|
method.</td></tr>
|
|
<tr><td>$parentclasssymname</td><td>The target language parent class
|
|
name (if any) for a method.</td></tr>
|
|
<tr><td>$symname</td><td>The symbol name used internally by SWIG.</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>
|
|
</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">15.1.7 Using The SWIG exception library</a>
|
|
</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
|
|
provides 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> The <tt>SWIG_exception()</tt> function can also be used in typemaps.</p>
|
|
<h2><a name="Customization_ownership">15.2 Object ownership and
|
|
%newobject</a></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> The use of <tt>%newobject</tt> is also integrated with reference
|
|
counting and is covered in the <a href="#SWIGPlus_ref_unref">C++
|
|
reference counted objects</a> section.</p>
|
|
<h2><a name="Customization_features">15.3 Features and the %feature
|
|
directive</a></h2>
|
|
<p> Both <tt>%exception</tt> and <tt>%newobject</tt> are examples of a
|
|
more general purpose customization mechanism known as "features." A
|
|
feature is simply a user-definable property that is attached to
|
|
specific declarations. Features are attached using the <tt>%feature</tt>
|
|
directive. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except") Object::allocate {
|
|
try {
|
|
$action
|
|
}
|
|
catch (MemoryError) {
|
|
croak("Out of memory");
|
|
}
|
|
}
|
|
|
|
%feature("new", "1") *::copy;
|
|
</pre>
|
|
</div>
|
|
<p> In fact, the <tt>%exception</tt> and <tt>%newobject</tt> directives
|
|
are really nothing more than macros involving <tt>%feature</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#define %exception %feature("except")
|
|
#define %newobject %feature("new", "1")
|
|
</pre>
|
|
</div>
|
|
<p> The name matching rules outlined in the <a href="#SWIGPlus_ambiguity_resolution_renaming">
|
|
Renaming and ambiguity resolution</a> section applies to all <tt>
|
|
%feature</tt> directives. In fact 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">15.3.1 Feature attributes</a>
|
|
</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="#Java_exception_handling">
|
|
Java exception handling</a> section.</p>
|
|
<h3><a name="Customization_feature_flags">15.3.2 Feature flags</a></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">15.3.3 Clearing features</a>
|
|
</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">15.3.4 Features and
|
|
default arguments</a></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") 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") 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="Customization_features_example">15.3.5 Feature example</a></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">16 Contracts</a></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">16.1 The %contract directive</a></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">16.2 %contract and classes</a></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">16.3 Constant aggregation and
|
|
%aggregate_check</a></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">16.4 Notes</a></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">17 Variable Length Arguments</a></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">17.1 Introduction</a></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">17.2 The Problem</a></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">17.3 Default varargs support</a></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, however it
|
|
does come with a caveat. 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))
|
|
>>> traceprintf("Your result is 90%%.")
|
|
</pre>
|
|
</div>
|
|
<p> Notice how string formatting is being done in Python instead of C.
|
|
The caveat is the strings passed must be safe to use in C though. For
|
|
example if name was to contain a "%" it should be double escaped in
|
|
order to avoid unpredictable behaviour:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> traceprintf("Your result is 90%.\n") # unpredictable behaviour
|
|
>>> traceprintf("Your result is 90%%.\n") # good
|
|
</pre>
|
|
</div>
|
|
<p> Read on for further solutions.</p>
|
|
<h2><a name="Varargs_nn5">17.4 Argument replacement using %varargs</a></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 arguments 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(3, char *str = NULL) execlp;
|
|
...
|
|
int execlp(const char *path, const char *arg, ...);
|
|
</pre>
|
|
</div>
|
|
<p> and is effectively seen as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int execlp(const char *path, const char *arg,
|
|
char *str1 = NULL,
|
|
char *str2 = NULL,
|
|
char *str3 = NULL);
|
|
</pre>
|
|
</div>
|
|
<p> This would wrap <tt>execlp()</tt> as a function that accepted up to
|
|
3 optional arguments. Depending on the application, this may be more
|
|
than enough for practical purposes.</p>
|
|
<p> The handling of <a href="#SWIGPlus_default_args">default arguments</a>
|
|
can be changed via the <tt>compactdefaultargs</tt> feature. If this
|
|
feature is used, for example</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("compactdefaultargs") execlp;
|
|
%varargs(3, char *str = NULL) execlp;
|
|
...
|
|
int execlp(const char *path, const char *arg, ...);
|
|
</pre>
|
|
</div>
|
|
<p> a call from the target language which does not provide the maximum
|
|
number of arguments, such as, <tt>execlp("a", "b", "c")</tt> will
|
|
generate C code which includes the missing default values, that is, <tt>
|
|
execlp("a", "b", "c", NULL, NULL)</tt>. If <tt>compactdefaultargs</tt>
|
|
is not used, then the generated code will be <tt>execlp("a", "b", "c")</tt>
|
|
. The former is useful for helping providing a sentinel to terminate the
|
|
argument list. However, this is not guaranteed, for example when a user
|
|
passes a non-NULL value for all the parameters. When using <tt>
|
|
compactdefaultargs</tt> it is possible to guarantee the NULL sentinel is
|
|
passed through the, <tt>numinputs=0</tt> <a href="#Typemaps_nn26">'in'
|
|
typemap attribute</a>, naming the<b> last parameter</b>. For example,</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("compactdefaultargs") execlp;
|
|
%varargs(3, char *str = NULL) execlp;
|
|
%typemap(in, numinputs=0) char *str3 ""
|
|
...
|
|
int execlp(const char *path, const char *arg, ...);
|
|
</pre>
|
|
</div>
|
|
<p> Note that <tt>str3</tt> is the name of the last argument, as we have
|
|
used <tt>%varargs</tt> with 3. Now <tt>execlp("a", "b", "c", "d", "e")</tt>
|
|
will result in an error as one too many arguments has been passed, as
|
|
now only 2 additional 'str' arguments can be passed with the 3rd one
|
|
always using the specified default <tt>NULL</tt>.</p>
|
|
<p> Argument replacement is most appropriate in cases where the types of
|
|
the extra arguments are uniform and the maximum number of arguments are
|
|
known. 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">17.5 Varargs and typemaps</a></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 *vargs[10]) {
|
|
int i;
|
|
Py_ssize_t argc;
|
|
for (i = 0; i < 10; i++) vargs[i] = 0;
|
|
argc = PyTuple_Size(varargs);
|
|
if (argc > 10) {
|
|
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
|
SWIG_fail;
|
|
}
|
|
for (i = 0; i < argc; i++) {
|
|
PyObject *pyobj = PyTuple_GetItem(varargs, i);
|
|
char *str = 0;
|
|
%#if PY_VERSION_HEX>=0x03000000
|
|
const char *strtmp = 0;
|
|
PyObject *pystr;
|
|
if (!PyUnicode_Check(pyobj)) {
|
|
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
|
SWIG_fail;
|
|
}
|
|
pystr = PyUnicode_AsUTF8String(pyobj);
|
|
if (!pystr) {
|
|
SWIG_fail;
|
|
}
|
|
strtmp = PyBytes_AsString(pystr);
|
|
str = (char *)malloc(strlen(strtmp) + 1);
|
|
if (str)
|
|
strcpy(str, strtmp);
|
|
Py_DecRef(pystr);
|
|
%#else
|
|
if (!PyString_Check(pyobj)) {
|
|
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
|
SWIG_fail;
|
|
}
|
|
str = PyString_AsString(pyobj);
|
|
%#endif
|
|
vargs[i] = str;
|
|
}
|
|
$1 = (void *)vargs;
|
|
}
|
|
|
|
%typemap(freearg) (...) {
|
|
%#if PY_VERSION_HEX>=0x03000000
|
|
int i;
|
|
for (i = 0; i < 10; i++) {
|
|
free(vargs$argnum[i]);
|
|
}
|
|
%#endif
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> In the 'in' 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. The 'freearg' typemap cleans up memory allocated in
|
|
the 'in' typemap; this code is generated to be called after the <tt>
|
|
execlp</tt> function is called. 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 **vargs = (char **) arg3;
|
|
result = execlp(arg1, arg2, vargs[0], vargs[1], vargs[2], vargs[3], vargs[4],
|
|
vargs[5], vargs[6], vargs[7], vargs[8], vargs[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">17.6 Varargs wrapping with libffi</a></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="https://www.sourceware.org/libffi/">
|
|
https://www.sourceware.org/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)) {
|
|
free(argv);
|
|
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
|
SWIG_fail;
|
|
}
|
|
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 {
|
|
free(types);
|
|
free(values);
|
|
free(arg3);
|
|
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
|
SWIG_fail;
|
|
}
|
|
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 {
|
|
free(argv);
|
|
PyErr_SetString(PyExc_ValueError, "Unsupported argument type");
|
|
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 {
|
|
free(types);
|
|
free(values);
|
|
free(args);
|
|
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
|
SWIG_fail;
|
|
}
|
|
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">17.7 Wrapping of va_list</a></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 vprintf(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>
|
|
<p> A workaround can be implemented by writing a simple varargs C
|
|
wrapper and then using the techniques discussed earlier in this chapter
|
|
for varargs. Below is a simple wrapper for <tt>vprintf</tt> renamed so
|
|
that it can still be called as <tt>vprintf</tt> from your target
|
|
language. The <tt>%varargs</tt> used in the example restricts the
|
|
function to taking one string argument.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
int vprintf(const char *fmt, va_list ap);
|
|
%}
|
|
|
|
%varargs(const char *) my_vprintf;
|
|
%rename(vprintf) my_vprintf;
|
|
|
|
%inline %{
|
|
int my_vprintf(const char *fmt, ...) {
|
|
va_list ap;
|
|
int result;
|
|
|
|
va_start(ap, fmt);
|
|
result = vprintf(fmt, ap);
|
|
va_end(ap);
|
|
return result;
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Varargs_nn9">17.8 C++ Issues</a></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">17.9 Discussion</a></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="Doxygen">18 SWIG and Doxygen Translation</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Doxygen_translation_overview">Doxygen translation overview</a>
|
|
</li>
|
|
<li><a href="#Doxygen_file_preparation">Preparations</a>
|
|
<ul>
|
|
<li><a href="#Doxygen_running_swig">Enabling Doxygen translation</a></li>
|
|
<li><a href="#Doxygen_features">Doxygen-specific %feature directives</a>
|
|
<ul>
|
|
<li><a href="#Doxygen_notranslate">doxygen:notranslate</a></li>
|
|
<li><a href="#Doxygen_alias">doxygen:alias:<command-name></a></li>
|
|
<li><a href="#Doxygen_ignore">doxygen:ignore:<command-name></a></li>
|
|
<li><a href="#Doxygen_nolinktranslate">doxygen:nolinktranslate</a></li>
|
|
<li><a href="#Doxygen_nostripparams">doxygen:nostripparams</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Doxygen_additional_options">Additional command line
|
|
options</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Doxygen_javadoc">Doxygen to Javadoc</a>
|
|
<ul>
|
|
<li><a href="#Doxygen_javadoc_basic_example">Basic Javadoc example</a></li>
|
|
<li><a href="#Doxygen_javadoc_tags">Javadoc tags</a></li>
|
|
<li><a href="#Doxygen_javadoc_unsupported_tags">Unsupported tags for
|
|
Javadoc</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Doxygen_pydoc">Doxygen to Pydoc</a>
|
|
<ul>
|
|
<li><a href="#Doxygen_pydoc_basic_example">Basic Pydoc example</a></li>
|
|
<li><a href="#Doxygen_pydoc_tags">Pydoc translator</a></li>
|
|
<li><a href="#Doxygen_pydoc_unsupported_tags">Unsupported tags for Pydoc</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Doxygen_csharp">Doxygen to XML C# documentation</a>
|
|
<ul>
|
|
<li><a href="#Doxygen_csharp_basic_example">Basic C# example</a></li>
|
|
<li><a href="#Doxygen_csharp_tags">C# tags</a></li>
|
|
<li><a href="#Doxygen_csharp_unsupported_tags">Unsupported tags for C#</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Doxygen_troubleshooting">Troubleshooting</a>
|
|
<ul>
|
|
<li><a href="#troubleshooting_ifndef">Problem with conditional
|
|
compilation</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Doxygen_developer_details">Developer information</a>
|
|
<ul>
|
|
<li><a href="#Doxygen_translator_design">Doxygen translator design</a></li>
|
|
<li><a href="#Doxygen_debugging_commands">Debugging the Doxygen parser
|
|
and translator</a></li>
|
|
<li><a href="#Doxygen_tests">Tests</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Doxygen_language_extension">Extending to other languages</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> This chapter describes SWIG's support for translating Doxygen
|
|
comments found in interface and header files into a target language's
|
|
normal documentation language. Currently only Javadoc and Pydoc is
|
|
supported.</p>
|
|
<h2><a name="Doxygen_translation_overview">18.1 Doxygen translation
|
|
overview</a></h2>
|
|
<p> The Doxygen Translation module of SWIG adds an extra layer of
|
|
functionality to SWIG, allowing automated translation of <a href="https://www.doxygen.nl/manual/">
|
|
Doxygen</a> formatted comments from input files into a documentation
|
|
language more suited for the target language. Currently this module
|
|
only translates into Javadoc and Pydoc for the SWIG Java and Python
|
|
modules. Other extensions could be added at a later date. The Doxygen
|
|
Translation module originally started as a <a href="https://developers.google.com/open-source/gsoc/2008/">
|
|
Google Summer of Code</a> proposal from Summer 2008.</p>
|
|
<h2><a name="Doxygen_file_preparation">18.2 Preparations</a></h2>
|
|
<p> To make use of the comment translation system, your documentation
|
|
comments must be in properly formatted <a href="https://www.doxygen.nl/manual/">
|
|
Doxygen.</a> Doxygen comments can be present in your main SWIG interface
|
|
file or any header file that it imports. You are advised to be validate
|
|
that your comments compile properly with Doxygen before you try to
|
|
translate them. Doxygen itself is a more comprehensive tool and can
|
|
provide you better feedback for correcting any syntax errors that may
|
|
be present. Please look at Doxygen's <a href="https://www.doxygen.nl/manual/docblocks.html">
|
|
Documenting the code</a> for the full comment format specifications.
|
|
However, SWIG's Doxygen parser will still report many errors and
|
|
warnings found in comments (like unterminated strings or missing ending
|
|
tags).</p>
|
|
<p> Currently, the whole subset of Doxygen comment styles is supported
|
|
(See <a href="https://www.doxygen.nl/manual/docblocks.html">
|
|
Documenting the code</a>). Here they are:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/**
|
|
* Javadoc style comment, multiline
|
|
*/
|
|
/*!
|
|
* QT-style comment, multiline
|
|
*/
|
|
/**
|
|
Any of the above, but without intermediate *'s
|
|
*/
|
|
/// Single-line comment
|
|
//! Another single-line comment
|
|
</pre>
|
|
</div>
|
|
<p> Also any of the above with '<tt><</tt>' added after comment-starting
|
|
symbol, like <tt>/**<, /*!<, ///<,</tt> or <tt>//!<</tt> will be
|
|
treated as a post-comment and will be assigned to the code before the
|
|
comment. Any number of '<tt>*</tt>' or '<tt>/</tt>' within a Doxygen
|
|
comment is considered to be a separator and is not included in the
|
|
final comment, so you may safely use comments like <tt>/*********/</tt>
|
|
or <tt>//////////</tt>.</p>
|
|
<p> Please note, as SWIG parses the input file by itself with strict
|
|
grammar, there is only a limited support for various cases of comment
|
|
placement in the file.</p>
|
|
<p> Comments can be placed before C/C++ expressions on separate lines:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/**
|
|
* Some comment
|
|
*/
|
|
void someOtherFunction();
|
|
/**
|
|
* Some comment
|
|
*/
|
|
void someFunction();
|
|
|
|
class Shape {
|
|
/*
|
|
* Calculate the area in cm^2
|
|
*/
|
|
int getArea();
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> After C/C++ expressions at the end of the line:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int someVariable = 9; ///< This is a var holding magic number 9
|
|
void doNothing(); ///< This does nothing, nop
|
|
</pre>
|
|
</div>
|
|
<p> and in some special cases, like function parameter comments:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void someFunction(
|
|
int a ///< Some parameter
|
|
);
|
|
</pre>
|
|
</div>
|
|
<p> or enum element comments:</p>
|
|
<div class="code">
|
|
<pre>
|
|
enum E_NUMBERS
|
|
{
|
|
EN_ZERO, ///< The first enum item, gets zero as its value
|
|
EN_ONE, ///< The second, EN_ONE=1
|
|
EN_THREE
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Currently only comments directly before or after the code items are
|
|
supported. Doxygen also supports comments containing structural
|
|
commands, where the comments for a code item are not put directly
|
|
before or after the code item. These structural commands are stripped
|
|
out by SWIG and are not assigned to anything.</p>
|
|
<h3><a name="Doxygen_running_swig">18.2.1 Enabling Doxygen translation</a>
|
|
</h3>
|
|
<p> Doxygen comments translation is disabled by default and needs to be
|
|
explicitly enabled using the command line <tt>-doxygen</tt> option for
|
|
the languages that do support it (currently Java and Python).</p>
|
|
<h3><a name="Doxygen_features">18.2.2 Doxygen-specific %feature
|
|
directives</a></h3>
|
|
<p> Translation of Doxygen comments is influenced by the following <a href="#Customization_features">
|
|
%feature directives</a>:</p>
|
|
<h4><a name="Doxygen_notranslate">18.2.2.1 doxygen:notranslate</a></h4>
|
|
<p> Turns off translation of Doxygen comments to the target language
|
|
syntax: the original comment will be copied to the output unchanged.
|
|
This is useful if you want to use Doxygen itself to generate
|
|
documentation for the target language instead of the corresponding
|
|
language tool (<tt>javadoc</tt>, <tt>sphinx</tt>, ...).</p>
|
|
<h4><a name="Doxygen_alias">18.2.2.2 doxygen:alias:<command-name></a></h4>
|
|
<p> Specify an alias for a Doxygen command with the given name. This can
|
|
be useful for custom Doxygen commands which can be defined using <tt>
|
|
ALIASES</tt> option for Doxygen itself but which are unknown to SWIG. <tt>
|
|
"command-name"</tt> is the name of the command in the Doxyfile, e.g. if
|
|
it contains</p>
|
|
<div class="code">
|
|
<pre>
|
|
ALIASES = "sideeffect=\par Side Effects:\n"
|
|
</pre>
|
|
</div>
|
|
<p> Then you could also specify the same expansion for SWIG with:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("doxygen:alias:sideeffect") "\par Side Effects:\n"
|
|
</pre>
|
|
</div>
|
|
<p> Please note that command arguments are not currently supported with
|
|
this feature.</p>
|
|
<p> Notice that it is perfectly possible and potentially useful to
|
|
define the alias expansion differently depending on the target
|
|
language, e.g. with</p>
|
|
<div class="code">
|
|
<pre>
|
|
#ifdef SWIGJAVA
|
|
%feature("doxygen:alias:not_for_java") "This functionality is not available for Java"
|
|
#else
|
|
%feature("doxygen:alias:not_for_java") ""
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
<p> you could use <tt>@not_for_java</tt> in the documentation comments
|
|
of all functions which can't, for whatever reason, be currently exposed
|
|
in Java wrappers of the C++ API.</p>
|
|
<h4><a name="Doxygen_ignore">18.2.2.3 doxygen:ignore:<command-name></a></h4>
|
|
<p> This feature makes it possible to just ignore an unknown Doxygen
|
|
command, instead of replacing it with the predefined text that <tt>
|
|
doxygen:alias</tt> does. For example, you could use</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("doxygen:ignore:transferfull") Fantastic();
|
|
/**
|
|
A fantastic function.
|
|
|
|
@transferfull Command ignored, but anything here is still included.
|
|
*/
|
|
int * Fantastic();
|
|
</pre>
|
|
</div>
|
|
<p> if you use a custom Doxygen <tt>transferfull</tt> command to
|
|
indicate that the return value ownership is transferred to the caller,
|
|
as this information doesn't make much sense for the other languages
|
|
without explicit ownership management.</p>
|
|
<p> Doxygen syntax is rather rich and, in addition to simple commands
|
|
such as <tt>@transferfull</tt>, it is also possible to define commands
|
|
with arguments. As explained in <a href="https://www.doxygen.nl/manual/commands.html">
|
|
Doxygen documentation</a>, the arguments can have a range of a single
|
|
word, everything until the end of line or everything until the end of
|
|
the next paragraph. Currently, only the "end of line" case is supported
|
|
using the <tt>range="line"</tt> argument of the feature directive:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// Ignore occurrences of
|
|
//
|
|
// @compileroptions Some special C++ compiler options.
|
|
//
|
|
// in Doxygen comments as C++ options are not interesting for the target language
|
|
// developers.
|
|
%feature("doxygen:ignore:compileroptions", range="line") Amazing();
|
|
|
|
/**
|
|
An amazing function.
|
|
|
|
@compileroptions This function must be compiled with /EHa when using MSVC.
|
|
*/
|
|
void Amazing();
|
|
|
|
</pre>
|
|
</div>
|
|
<p> In addition, it is also possible to have custom pairs of begin/end
|
|
tags, similarly to the standard Doxygen <tt>@code/@endcode</tt>, for
|
|
example. Such tags can also be ignored using the special value of <tt>
|
|
range</tt> starting with <tt>end</tt> to indicate that the range is an
|
|
interval, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("doxygen:ignore:forcpponly", range="end"); // same as "end:endforcpponly"
|
|
/**
|
|
An incredible function.
|
|
|
|
@forcpponly
|
|
This is C++-specific.
|
|
@endforcpponly
|
|
*/
|
|
void Incredible();
|
|
</pre>
|
|
</div>
|
|
<p> would ignore everything between <tt>@forcpponly</tt> and <tt>
|
|
@endforcpponly</tt> commands in Doxygen comments. By default, the name
|
|
of the end command is the same as of the start one with "end" prefix,
|
|
following Doxygen conventions, but this can be overridden by providing
|
|
the end command name after the colon.</p>
|
|
<p> This example shows how custom tags can be used to bracket anything
|
|
specific to C++ and prevent it from appearing in the target language
|
|
documentation. Conversely, another pair of custom tags could be used to
|
|
put target language specific information in the C++ comments. In this
|
|
case, only the custom tags themselves should be ignored, but their
|
|
contents should be parsed as usual and <tt>contents="parse"</tt> can be
|
|
used for this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("doxygen:ignore:beginPythonOnly", range="end:endPythonOnly", contents="parse");
|
|
/**
|
|
A splendid function.
|
|
|
|
@beginPythonOnly
|
|
This is specific to @b Python.
|
|
@endPythonOnly
|
|
*/
|
|
void Splendid();
|
|
|
|
</pre>
|
|
</div>
|
|
<p> Putting everything together, if these directives are in effect:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("doxygen:ignore:transferfull");
|
|
%feature("doxygen:ignore:compileroptions", range="line");
|
|
%feature("doxygen:ignore:forcpponly", range="end");
|
|
%feature("doxygen:ignore:beginPythonOnly", range="end:endPythonOnly", contents="parse");
|
|
</pre>
|
|
</div>
|
|
<p> then the following C++ Doxygen comment:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/**
|
|
A contrived example of ignoring too many commands in one comment.
|
|
|
|
@forcpponly
|
|
This is C++-specific.
|
|
@endforcpponly
|
|
|
|
@beginPythonOnly
|
|
This is specific to @b Python.
|
|
@endPythonOnly
|
|
|
|
@transferfull Command ignored, but anything here is still included.
|
|
|
|
@compileroptions This function must be compiled with /EHa when using MSVC.
|
|
*/
|
|
int * Contrived();
|
|
</pre>
|
|
</div>
|
|
<p> would be translated to this comment in Python:</p>
|
|
<div class="code">
|
|
<pre>
|
|
def func():
|
|
r"""
|
|
A contrived example of ignoring too many commands in one comment.
|
|
|
|
This is specific to **Python**.
|
|
|
|
Command ignored, but anything here is still included.
|
|
"""
|
|
...
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Doxygen_nolinktranslate">18.2.2.4 doxygen:nolinktranslate</a>
|
|
</h4>
|
|
<p> Turn off automatic link-objects translation. This is only applicable
|
|
to Java at the moment.</p>
|
|
<h4><a name="Doxygen_nostripparams">18.2.2.5 doxygen:nostripparams</a></h4>
|
|
<p> Turn off stripping of <tt>@param</tt> and <tt>@tparam</tt> Doxygen
|
|
commands if the parameter is not found in the function signature. This
|
|
is only applicable to Java at the moment.</p>
|
|
<h3><a name="Doxygen_additional_options">18.2.3 Additional command line
|
|
options</a></h3>
|
|
<p> ALSO TO BE ADDED (Javadoc auto brief?)</p>
|
|
<h2><a name="Doxygen_javadoc">18.3 Doxygen to Javadoc</a></h2>
|
|
<p> If translation is enabled, Javadoc formatted comments should be
|
|
automatically placed in the correct locations in the resulting module
|
|
and proxy files.</p>
|
|
<h3><a name="Doxygen_javadoc_basic_example">18.3.1 Basic Javadoc example</a>
|
|
</h3>
|
|
<p> Here is an example segment from an included header file</p>
|
|
<div class="code">
|
|
<pre>
|
|
/*! This is describing class Shape
|
|
\author Bob
|
|
*/
|
|
|
|
class Shape {
|
|
public:
|
|
Shape() {
|
|
nshapes++;
|
|
}
|
|
virtual ~Shape() {
|
|
nshapes--;
|
|
};
|
|
double x, y; /*!< Important Variables */
|
|
void move(double dx, double dy); /*!< Moves the Shape */
|
|
virtual double area(void) = 0; /*!< \return the area */
|
|
virtual double perimeter(void) = 0; /*!< \return the perimeter */
|
|
static int nshapes;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Simply running SWIG should result in the following code being
|
|
present in Shapes.java</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
|
|
/**
|
|
* This is describing class Shape
|
|
* @author Bob
|
|
*
|
|
*/
|
|
|
|
public class Shape {
|
|
|
|
...
|
|
|
|
/**
|
|
* Important Variables
|
|
*/
|
|
public void setX(double value) {
|
|
ShapesJNI.Shape_x_set(swigCPtr, this, value);
|
|
}
|
|
|
|
/**
|
|
* Important Variables
|
|
*/
|
|
public double getX() {
|
|
return ShapesJNI.Shape_x_get(swigCPtr, this);
|
|
}
|
|
|
|
/**
|
|
* Moves the Shape
|
|
*/
|
|
public void move(double dx, double dy) {
|
|
ShapesJNI.Shape_move(swigCPtr, this, dx, dy);
|
|
}
|
|
|
|
/**
|
|
* @return the area
|
|
*/
|
|
public double area() {
|
|
return ShapesJNI.Shape_area(swigCPtr, this);
|
|
}
|
|
|
|
/**
|
|
* @return the perimeter
|
|
*/
|
|
public double perimeter() {
|
|
return ShapesJNI.Shape_perimeter(swigCPtr, this);
|
|
}
|
|
}
|
|
|
|
</pre>
|
|
</div>
|
|
<p> The code Java-wise should be identical to what would have been
|
|
generated without the doxygen functionality enabled. When the Doxygen
|
|
Translator module encounters a comment that contains nothing useful or
|
|
a doxygen comment that it cannot parse, it will not affect the
|
|
functionality of the SWIG generated code.</p>
|
|
<p> The Javadoc translator will handle most of the tags conversions (see
|
|
the table below). It will also automatically translate link-objects
|
|
params, in <tt>\see</tt> and <tt>\link...\endlink</tt> commands. For
|
|
example, <tt>someFunction(std::string)</tt> will be converted to <tt>
|
|
someFunction(String)</tt>. If you don't want such behaviour, you could
|
|
turn this off by using the <tt>doxygen:nolinktranslate</tt> feature.
|
|
Also all <tt>\param</tt> and <tt>\tparam</tt> commands are stripped
|
|
out, if the specified parameter is not present in the function. Use <tt>
|
|
doxygen:nostripparams</tt> to avoid.</p>
|
|
<p> Javadoc translator features summary (see <a href="#Customization_features">
|
|
%feature directives</a>):</p>
|
|
<h3><a name="Doxygen_javadoc_tags">18.3.2 Javadoc tags</a></h3>
|
|
<p> Here is the list of all Doxygen tags and the description of how they
|
|
are translated to Javadoc</p>
|
|
<div class="diagram">
|
|
<table border="0" summary="Java Doxygen tags">
|
|
<tr><th align="left">Doxygen tags</th></tr>
|
|
<tr><td>\a</td><td>wrapped with <i> html tag</td></tr>
|
|
<tr><td>\arg</td><td>wrapped with <li> html tag</td></tr>
|
|
<tr><td>\author</td><td>translated to @author</td></tr>
|
|
<tr><td>\authors</td><td>translated to @author</td></tr>
|
|
<tr><td>\b</td><td>wrapped with <b> html tag</td></tr>
|
|
<tr><td>\c</td><td>wrapped with <code> html tag</td></tr>
|
|
<tr><td>\cite</td><td>wrapped with <i> html tag</td></tr>
|
|
<tr><td>\code</td><td>translated to {@code ...}</td></tr>
|
|
<tr><td>\code{<ext>}</td><td>translated to {@code ...}; code language
|
|
extension is ignored</td></tr>
|
|
<tr><td>\cond</td><td>translated to 'Conditional comment: <condition>'</td>
|
|
</tr>
|
|
<tr><td>\copyright</td><td>replaced with 'Copyright:'</td></tr>
|
|
<tr><td>\deprecated</td><td>translated to @deprecated</td></tr>
|
|
<tr><td>\e</td><td>wrapped with <i> html tag</td></tr>
|
|
<tr><td>\else</td><td>replaced with '}Else:{'</td></tr>
|
|
<tr><td>\elseif</td><td>replaced with '}Else if: <condition>{'</td></tr>
|
|
<tr><td>\em</td><td>wrapped with <i> html tag</td></tr>
|
|
<tr><td>\endcode</td><td>see note for \code</td></tr>
|
|
<tr><td>\endcond</td><td>replaced with 'End of conditional comment.'</td>
|
|
</tr>
|
|
<tr><td>\endif</td><td>replaced with '}'</td></tr>
|
|
<tr><td>\endlink</td><td>see note for \link</td></tr>
|
|
<tr><td>\endverbatim</td><td>see note for \verbatim</td></tr>
|
|
<tr><td>\exception</td><td>translated to @exception</td></tr>
|
|
<tr><td>\f$, \f[, \f], \f{, \f}</td><td>LateX formulas are left
|
|
unchanged</td></tr>
|
|
<tr><td>\if</td><td>replaced with 'If: <condition> {'</td></tr>
|
|
<tr><td>\ifnot</td><td>replaced with 'If not: <condition> {'</td></tr>
|
|
<tr><td>\image</td><td>translated to <img/> html tag only if target=HTML</td>
|
|
</tr>
|
|
<tr><td>\li</td><td>wrapped with <li> html tag</td></tr>
|
|
<tr><td>\link</td><td>translated to {@link ...}</td></tr>
|
|
<tr><td>\n</td><td>replaced with newline char</td></tr>
|
|
<tr><td>\note</td><td>replaced with 'Note:'</td></tr>
|
|
<tr><td>\overload</td><td>prints 'This is an overloaded ...' according
|
|
to Doxygen docs</td></tr>
|
|
<tr><td>\p</td><td>wrapped with <code> html tag</td></tr>
|
|
<tr><td>\par</td><td>replaced with <p alt='title'>...</p></td></tr>
|
|
<tr><td>\param</td><td>translated to @param</td></tr>
|
|
<tr><td>\param[<dir>]</td><td>translated to @param; parameter direction
|
|
('in'; 'out'; or 'in,out') is ignored</td></tr>
|
|
<tr><td>\remark</td><td>replaced with 'Remarks:'</td></tr>
|
|
<tr><td>\remarks</td><td>replaced with 'Remarks:'</td></tr>
|
|
<tr><td>\result</td><td>translated to @return</td></tr>
|
|
<tr><td>\return</td><td>translated to @return</td></tr>
|
|
<tr><td>\returns</td><td>translated to @return</td></tr>
|
|
<tr><td>\sa</td><td>translated to @see</td></tr>
|
|
<tr><td>\see</td><td>translated to @see</td></tr>
|
|
<tr><td>\since</td><td>translated to @since</td></tr>
|
|
<tr><td>\throw</td><td>translated to @throws</td></tr>
|
|
<tr><td>\throws</td><td>translated to @throws</td></tr>
|
|
<tr><td>\todo</td><td>replaced with 'TODO:'</td></tr>
|
|
<tr><td>\tparam</td><td>translated to @param</td></tr>
|
|
<tr><td>\verbatim</td><td>translated to {@literal ...}</td></tr>
|
|
<tr><td>\version</td><td>translated to @version</td></tr>
|
|
<tr><td>\warning</td><td>translated to 'Warning:'</td></tr>
|
|
<tr><td>\$</td><td>prints $ char</td></tr>
|
|
<tr><td>\@</td><td>prints @ char</td></tr>
|
|
<tr><td>\\</td><td>prints \ char</td></tr>
|
|
<tr><td>\&</td><td>prints & char</td></tr>
|
|
<tr><td>\~</td><td>prints ~ char</td></tr>
|
|
<tr><td>\<</td><td>prints < char</td></tr>
|
|
<tr><td>\></td><td>prints > char</td></tr>
|
|
<tr><td>\#</td><td>prints # char</td></tr>
|
|
<tr><td>\%</td><td>prints % char</td></tr>
|
|
<tr><td>\"</td><td>prints " char</td></tr>
|
|
<tr><td>\.</td><td>prints . char</td></tr>
|
|
<tr><td>\::</td><td>prints ::</td></tr>
|
|
</table>
|
|
</div>
|
|
<h3><a name="Doxygen_javadoc_unsupported_tags">18.3.3 Unsupported tags
|
|
for Javadoc</a></h3>
|
|
<p> Doxygen has a wealth of tags such as <tt>@latexonly</tt> that have
|
|
no equivalent in Javadoc (all supported tags are listed in <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html">
|
|
Javadoc documentation</a>). As a result several tags have no translation
|
|
or particular use, such as some linking and section tags. These are
|
|
suppressed with their content just printed out (if the tag has any
|
|
sense, typically text content). Here is the list of these tags:</p>
|
|
<div class="diagram"><b> Unsupported Doxygen tags</b>
|
|
<ul style="list-style-type:none;column-count:4;">
|
|
<li>\addindex</li>
|
|
<li>\addtogroup</li>
|
|
<li>\anchor</li>
|
|
<li>\attention</li>
|
|
<li>\brief</li>
|
|
<li>\bug</li>
|
|
<li>\callergraph</li>
|
|
<li>\callgraph</li>
|
|
<li>\category</li>
|
|
<li>\class</li>
|
|
<li>\copybrief</li>
|
|
<li>\copydetails</li>
|
|
<li>\copydoc</li>
|
|
<li>\date</li>
|
|
<li>\def</li>
|
|
<li>\defgroup</li>
|
|
<li>\details</li>
|
|
<li>\dir</li>
|
|
<li>\dontinclude</li>
|
|
<li>\dot</li>
|
|
<li>\dotfile</li>
|
|
<li>\enddot</li>
|
|
<li>\endhtmlonly</li>
|
|
<li>\endinternal</li>
|
|
<li>\endlatexonly</li>
|
|
<li>\endmanonly</li>
|
|
<li>\endmsc</li>
|
|
<li>\endrtfonly</li>
|
|
<li>\endxmlonly</li>
|
|
<li>\enum</li>
|
|
<li>\example</li>
|
|
<li>\extends</li>
|
|
<li>\file</li>
|
|
<li>\fn</li>
|
|
<li>\headerfile</li>
|
|
<li>\hideinitializer</li>
|
|
<li>\htmlinclude</li>
|
|
<li>\htmlonly</li>
|
|
<li>\implements</li>
|
|
<li>\include</li>
|
|
<li>\includelineno</li>
|
|
<li>\ingroup</li>
|
|
<li>\interface</li>
|
|
<li>\internal</li>
|
|
<li>\invariant</li>
|
|
<li>\latexonly</li>
|
|
<li>\line</li>
|
|
<li>\mainpage</li>
|
|
<li>\manonly</li>
|
|
<li>\memberof</li>
|
|
<li>\msc</li>
|
|
<li>\mscfile</li>
|
|
<li>\name</li>
|
|
<li>\namespace</li>
|
|
<li>\nosubgrouping</li>
|
|
<li>\package</li>
|
|
<li>\page</li>
|
|
<li>\paragraph</li>
|
|
<li>\post</li>
|
|
<li>\pre</li>
|
|
<li>\private</li>
|
|
<li>\privatesection</li>
|
|
<li>\property</li>
|
|
<li>\protected</li>
|
|
<li>\protectedsection</li>
|
|
<li>\protocol</li>
|
|
<li>\public</li>
|
|
<li>\publicsection</li>
|
|
<li>\ref</li>
|
|
<li>\related</li>
|
|
<li>\relatedalso</li>
|
|
<li>\relates</li>
|
|
<li>\relatesalso</li>
|
|
<li>\retval</li>
|
|
<li>\rtfonly</li>
|
|
<li>\section</li>
|
|
<li>\short</li>
|
|
<li>\showinitializer</li>
|
|
<li>\skip</li>
|
|
<li>\skipline</li>
|
|
<li>\snippet</li>
|
|
<li>\struct</li>
|
|
<li>\subpage</li>
|
|
<li>\subsection</li>
|
|
<li>\subsubsection</li>
|
|
<li>\tableofcontents</li>
|
|
<li>\test</li>
|
|
<li>\typedef</li>
|
|
<li>\union</li>
|
|
<li>\until</li>
|
|
<li>\var</li>
|
|
<li>\verbinclude</li>
|
|
<li>\weakgroup</li>
|
|
<li>\xmlonly</li>
|
|
<li>\xrefitem</li>
|
|
</ul>
|
|
</div>
|
|
<p> If one of the following Doxygen tags appears as the first tag in a
|
|
comment, the whole comment block is ignored:
|
|
<!-- see parser.y, function isStructuralDoxygen() -->
|
|
</p>
|
|
<div class="diagram"><b> Ignored Doxygen tags</b>
|
|
<ul style="list-style-type:none;column-count:4;">
|
|
<li>\addtogroup</li>
|
|
<li>\callergraph</li>
|
|
<li>\callgraph</li>
|
|
<li>\category</li>
|
|
<li>\class</li>
|
|
<li>\def</li>
|
|
<li>\defgroup</li>
|
|
<li>\dir</li>
|
|
<li>\enum</li>
|
|
<li>\example</li>
|
|
<li>\file</li>
|
|
<li>\fn</li>
|
|
<li>\headerfile</li>
|
|
<li>\hideinitializer</li>
|
|
<li>\interface</li>
|
|
<li>\internal</li>
|
|
<li>\mainpage</li>
|
|
<li>\name</li>
|
|
<li>\namespace</li>
|
|
<li>\nosubgrouping</li>
|
|
<li>\overload</li>
|
|
<li>\package</li>
|
|
<li>\page</li>
|
|
<li>\property</li>
|
|
<li>\protocol</li>
|
|
<li>\relates</li>
|
|
<li>\relatesalso</li>
|
|
<li>\showinitializer</li>
|
|
<li>\struct</li>
|
|
<li>\typedef</li>
|
|
<li>\union</li>
|
|
<li>\var</li>
|
|
<li>\weakgroup</li>
|
|
</ul>
|
|
</div>
|
|
<h2><a name="Doxygen_pydoc">18.4 Doxygen to Pydoc</a></h2>
|
|
<p> If translation is enabled, Pydoc formatted comments should be
|
|
automatically placed in the correct locations in the resulting module
|
|
and proxy files. The problem is that Pydoc has no tag mechanism like
|
|
Doxygen or Javadoc, so most of Doxygen commands are translated by
|
|
merely copying the appropriate command text.</p>
|
|
<h3><a name="Doxygen_pydoc_basic_example">18.4.1 Basic Pydoc example</a></h3>
|
|
<p> Here is an example segment from an included header file</p>
|
|
<div class="code">
|
|
<pre>
|
|
/*! This is describing class Shape
|
|
\author Bob
|
|
*/
|
|
|
|
class Shape {
|
|
public:
|
|
Shape() {
|
|
nshapes++;
|
|
}
|
|
virtual ~Shape() {
|
|
nshapes--;
|
|
};
|
|
double x, y; /*!< Important Variables */
|
|
void move(double dx, double dy); /*!< Moves the Shape */
|
|
virtual double area(void) = 0; /*!< \return the area */
|
|
virtual double perimeter(void) = 0; /*!< \return the perimeter */
|
|
static int nshapes;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Simply running SWIG should result in the following code being
|
|
present in Shapes.py</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
|
|
...
|
|
|
|
class Shape(_object):
|
|
"""
|
|
This is describing class Shape
|
|
Authors:
|
|
Bob
|
|
|
|
"""
|
|
|
|
...
|
|
|
|
def move(self, *args):
|
|
"""
|
|
Moves the Shape
|
|
"""
|
|
return _Shapes.Shape_move(self, *args)
|
|
|
|
def area(self):
|
|
"""
|
|
Return:
|
|
the area
|
|
"""
|
|
return _Shapes.Shape_area(self)
|
|
|
|
def perimeter(self):
|
|
"""
|
|
Return:
|
|
the perimeter
|
|
"""
|
|
return _Shapes.Shape_perimeter(self)
|
|
</pre>
|
|
</div>
|
|
<p> If any parameters of a function or a method are documented in the
|
|
Doxygen comment, their description is copied into the generated output
|
|
using <a href="https://www.sphinx-doc.org/">Sphinx</a> documentation
|
|
conventions. For example</p>
|
|
<div class="code">
|
|
<pre>
|
|
/**
|
|
Set a breakpoint at the given location.
|
|
|
|
@param filename The full path to the file.
|
|
@param line_number The line number in the file.
|
|
*/
|
|
bool SetBreakpoint(const char* filename, int line_number);
|
|
</pre>
|
|
</div>
|
|
<p> would be translated to</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
def SetBreakpoint(filename, line_number):
|
|
r"""
|
|
Set a breakpoint at the given location.
|
|
|
|
:type filename: string
|
|
:param filename: The full path to the file.
|
|
:type line_number: int
|
|
:param line_number: The line number in the file.
|
|
"""
|
|
</pre>
|
|
</div>
|
|
<p> The types used for the parameter documentation come from the
|
|
"doctype" typemap which is defined for all the primitive types and a
|
|
few others (e.g. <tt>std::string</tt> and <tt>shared_ptr<T></tt>) but
|
|
for non-primitive types is taken to be just the C++ name of the type
|
|
with namespace scope delimiters (<tt>::</tt>) replaced with a dot. To
|
|
change this, you can define your own typemaps for the custom types,
|
|
e.g:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(doctype) MyDate "datetime.date"
|
|
</pre>
|
|
</div>
|
|
<p> Currently Doxygen comments assigned to global variables and static
|
|
member variables are not present in generated code, so they have no
|
|
comment translated for them.</p>
|
|
<p><b> Whitespace and tables</b> Whitespace is preserved when
|
|
translating comments, so it makes sense to have Doxygen comments
|
|
formatted in a readable way. This includes tables, where tags <th>,
|
|
<td> and </tr>are translated to '|'. The line after line with <th> tags
|
|
contains dashes. If we take care about whitespace, comments in Python
|
|
are much more readable. Example:<div class="code">
|
|
<pre>
|
|
/**
|
|
* <table border = '1'>
|
|
* <caption>Animals</caption>
|
|
* <tr><th> Column 1 </th><th> Column 2 </th></tr>
|
|
* <tr><td> cow </td><td> dog </td></tr>
|
|
* <tr><td> cat </td><td> mouse </td></tr>
|
|
* <tr><td> horse </td><td> parrot </td></tr>
|
|
* </table>
|
|
*/
|
|
</pre>
|
|
</div></p>
|
|
<p> translates to Python as:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
Animals
|
|
| Column 1 | Column 2 |
|
|
-----------------------
|
|
| cow | dog |
|
|
| cat | mouse |
|
|
| horse | parrot |
|
|
</pre>
|
|
</div>
|
|
<p><b> Overloaded functions</b> Since all the overloaded functions in
|
|
c++ are wrapped into one Python function, Pydoc translator will combine
|
|
every comment of every overloaded function and put it into the comment
|
|
for the one wrapper function.</p>
|
|
<p> If you intend to use resulting generated Python file with the
|
|
Doxygen docs generator, rather than Pydoc, you may want to turn off
|
|
translation completely (doxygen:notranslate feature). Then SWIG will
|
|
just copy the comments to the proxy file and reformat them if needed,
|
|
but all the comment content will be left as is. As Doxygen doesn't
|
|
support special commands in Python comments (see <a href="https://www.doxygen.nl/manual/docblocks.html#pythonblocks">
|
|
Doxygen docs</a>), you may want to use some tool like doxypy (<a href="https://pypi.org/project/doxypy/">
|
|
doxypy</a>) to do the work.</p>
|
|
<h3><a name="Doxygen_pydoc_tags">18.4.2 Pydoc translator</a></h3>
|
|
<p> Here is the list of all Doxygen tags and the description of how they
|
|
are translated to Pydoc</p>
|
|
<div class="diagram">
|
|
<table border="0" summary="Python Doxygen tags">
|
|
<tr><th align="left">Doxygen tags</th></tr>
|
|
<tr><td>\a</td><td>wrapped with '*'</td></tr>
|
|
<tr><td>\arg</td><td>prepended with '* '</td></tr>
|
|
<tr><td>\author</td><td>prints 'Author:'</td></tr>
|
|
<tr><td>\authors</td><td>prints 'Authors:'</td></tr>
|
|
<tr><td>\b</td><td>wrapped with '**'</td></tr>
|
|
<tr><td>\c</td><td>wrapped with '``'</td></tr>
|
|
<tr><td>\cite</td><td>wrapped with single quotes</td></tr>
|
|
<tr><td>\code</td><td>replaced with '.. code-block:: c++'</td></tr>
|
|
<tr><td>\code{<ext>}</td><td>replaced with '.. code-block:: <lang>',
|
|
where the following doxygen code languages are recognized: .c -> C, .py
|
|
-> python, .java > java</td></tr>
|
|
<tr><td>\cond</td><td>translated to 'Conditional comment: <condition>'</td>
|
|
</tr>
|
|
<tr><td>\copyright</td><td>prints 'Copyright:'</td></tr>
|
|
<tr><td>\deprecated</td><td>prints 'Deprecated:'</td></tr>
|
|
<tr><td>\e</td><td>wrapped with '*'</td></tr>
|
|
<tr><td>\else</td><td>replaced with '}Else:{'</td></tr>
|
|
<tr><td>\elseif</td><td>replaced with '}Else if: <condition>{'</td></tr>
|
|
<tr><td>\em</td><td>wrapped with '*'</td></tr>
|
|
<tr><td>\endcond</td><td>replaced with 'End of conditional comment.'</td>
|
|
</tr>
|
|
<tr><td>\endif</td><td>replaced with '}'</td></tr>
|
|
<tr><td>\example</td><td>replaced with 'Example:'</td></tr>
|
|
<tr><td>\exception</td><td>replaced with ':raises:'</td></tr>
|
|
<tr><td>\f$</td><td>rendered using ':math:``'</td></tr>
|
|
<tr><td>\f[</td><td>rendered using '.. math::'</td></tr>
|
|
<tr><td>\f{</td><td>rendered using '.. math::'</td></tr>
|
|
<tr><td>\if</td><td>replaced with 'If: <condition> {'</td></tr>
|
|
<tr><td>\ifnot</td><td>replaced with 'If not: <condition> {'</td></tr>
|
|
<tr><td>\li</td><td>prepended with '* '</td></tr>
|
|
<tr><td>\n</td><td>replaced with newline char</td></tr>
|
|
<tr><td>\note</td><td>replaced with 'Note:'</td></tr>
|
|
<tr><td>\overload</td><td>prints 'This is an overloaded ...' according
|
|
to Doxygen docs</td></tr>
|
|
<tr><td>\p</td><td>wrapped with '``'</td></tr>
|
|
<tr><td>\par</td><td>replaced with 'Title: ...'</td></tr>
|
|
<tr><td>\param</td><td>add ':type:' and ':param:' directives</td></tr>
|
|
<tr><td>\param[<dir>]</td><td>same as \param, but direction ('in';
|
|
'out'; 'in,out') is included in ':type:' directive</td></tr>
|
|
<tr><td>\remark</td><td>replaced with 'Remarks:'</td></tr>
|
|
<tr><td>\remarks</td><td>replaced with 'Remarks:'</td></tr>
|
|
<tr><td>\result</td><td>add ':rtype:' and ':return:' directives</td></tr>
|
|
<tr><td>\return</td><td>add ':rtype:' and ':return:' directives</td></tr>
|
|
<tr><td>\returns</td><td>add ':rtype:' and ':return:' directives</td></tr>
|
|
<tr><td>\sa</td><td>replaced with 'See also:'</td></tr>
|
|
<tr><td>\see</td><td>replaced with 'See also:'</td></tr>
|
|
<tr><td>\since</td><td>replaced with 'Since:'</td></tr>
|
|
<tr><td>\throw</td><td>replaced with ':raises:'</td></tr>
|
|
<tr><td>\throws</td><td>replaced with ':raises:'</td></tr>
|
|
<tr><td>\todo</td><td>replaced with 'TODO:'</td></tr>
|
|
<tr><td>\tparam</td><td>add ':type:' and ':param:' directives</td></tr>
|
|
<tr><td>\verbatim</td><td>content copied verbatim</td></tr>
|
|
<tr><td>\version</td><td>replaced with 'Version:'</td></tr>
|
|
<tr><td>\warning</td><td>translated to 'Warning:'</td></tr>
|
|
<tr><td>\$</td><td>prints $ char</td></tr>
|
|
<tr><td>\@</td><td>prints @ char</td></tr>
|
|
<tr><td>\\</td><td>prints \ char</td></tr>
|
|
<tr><td>\&</td><td>prints & char</td></tr>
|
|
<tr><td>\~</td><td>prints ~ char</td></tr>
|
|
<tr><td>\<</td><td>prints < char</td></tr>
|
|
<tr><td>\></td><td>prints > char</td></tr>
|
|
<tr><td>\#</td><td>prints # char</td></tr>
|
|
<tr><td>\%</td><td>prints % char</td></tr>
|
|
<tr><td>\"</td><td>prints " char</td></tr>
|
|
<tr><td>\.</td><td>prints . character</td></tr>
|
|
<tr><td>\::</td><td>prints ::</td></tr>
|
|
</table>
|
|
</div>
|
|
<h3><a name="Doxygen_pydoc_unsupported_tags">18.4.3 Unsupported tags for
|
|
Pydoc</a></h3>
|
|
<p> Doxygen has a wealth of tags such as <tt>@latexonly</tt> that have
|
|
no equivalent in Pydoc. As a result several tags that have no
|
|
translation (or particular use, such as some linking and section tags)
|
|
are suppressed with their content just printed out (if it has any
|
|
sense, typically text content). Here is the list of these tags:</p>
|
|
<div class="diagram"><b> Unsupported Python Doxygen tags</b>
|
|
<ul style="list-style-type:none;column-count:4;">
|
|
<li>\addindex</li>
|
|
<li>\addtogroup</li>
|
|
<li>\anchor</li>
|
|
<li>\attention</li>
|
|
<li>\brief</li>
|
|
<li>\bug</li>
|
|
<li>\callergraph</li>
|
|
<li>\callgraph</li>
|
|
<li>\category</li>
|
|
<li>\class</li>
|
|
<li>\copybrief</li>
|
|
<li>\copydetails</li>
|
|
<li>\copydoc</li>
|
|
<li>\date</li>
|
|
<li>\def</li>
|
|
<li>\defgroup</li>
|
|
<li>\details</li>
|
|
<li>\dir</li>
|
|
<li>\dontinclude</li>
|
|
<li>\dot</li>
|
|
<li>\dotfile</li>
|
|
<li>\enddot</li>
|
|
<li>\endhtmlonly</li>
|
|
<li>\endinternal</li>
|
|
<li>\endlatexonly</li>
|
|
<li>\endlink</li>
|
|
<li>\endmanonly</li>
|
|
<li>\endmsc</li>
|
|
<li>\endrtfonly</li>
|
|
<li>\endxmlonly</li>
|
|
<li>\enum</li>
|
|
<li>\extends</li>
|
|
<li>\file</li>
|
|
<li>\fn</li>
|
|
<li>\headerfile</li>
|
|
<li>\hideinitializer</li>
|
|
<li>\htmlinclude</li>
|
|
<li>\htmlonly</li>
|
|
<li>\image</li>
|
|
<li>\implements</li>
|
|
<li>\include</li>
|
|
<li>\includelineno</li>
|
|
<li>\ingroup</li>
|
|
<li>\interface</li>
|
|
<li>\internal</li>
|
|
<li>\invariant</li>
|
|
<li>\latexonly</li>
|
|
<li>\line</li>
|
|
<li>\link</li>
|
|
<li>\mainpage</li>
|
|
<li>\manonly</li>
|
|
<li>\memberof</li>
|
|
<li>\msc</li>
|
|
<li>\mscfile</li>
|
|
<li>\name</li>
|
|
<li>\namespace</li>
|
|
<li>\nosubgrouping</li>
|
|
<li>\package</li>
|
|
<li>\page</li>
|
|
<li>\paragraph</li>
|
|
<li>\post</li>
|
|
<li>\pre</li>
|
|
<li>\private</li>
|
|
<li>\privatesection</li>
|
|
<li>\property</li>
|
|
<li>\protected</li>
|
|
<li>\protectedsection</li>
|
|
<li>\protocol</li>
|
|
<li>\public</li>
|
|
<li>\publicsection</li>
|
|
<li>\ref</li>
|
|
<li>\related</li>
|
|
<li>\relatedalso</li>
|
|
<li>\relates</li>
|
|
<li>\relatesalso</li>
|
|
<li>\retval</li>
|
|
<li>\rtfonly</li>
|
|
<li>\section</li>
|
|
<li>\short</li>
|
|
<li>\showinitializer</li>
|
|
<li>\skip</li>
|
|
<li>\skipline</li>
|
|
<li>\snippet</li>
|
|
<li>\struct</li>
|
|
<li>\subpage</li>
|
|
<li>\subsection</li>
|
|
<li>\subsubsection</li>
|
|
<li>\tableofcontents</li>
|
|
<li>\test</li>
|
|
<li>\typedef</li>
|
|
<li>\union</li>
|
|
<li>\until</li>
|
|
<li>\var</li>
|
|
<li>\verbinclude</li>
|
|
<li>\weakgroup</li>
|
|
<li>\xmlonly</li>
|
|
<li>\xrefitem</li>
|
|
</ul>
|
|
</div>
|
|
<h2><a name="Doxygen_csharp">18.5 Doxygen to XML C# documentation</a></h2>
|
|
<p> If translation is enabled, XML formatted comments should be
|
|
automatically placed in the correct locations in the resulting module
|
|
and proxy files.</p>
|
|
<h3><a name="Doxygen_csharp_basic_example">18.5.1 Basic C# example</a></h3>
|
|
<p> Here is an example segment from an included header file</p>
|
|
<div class="code">
|
|
<pre>
|
|
/*! This is describing class Shape
|
|
\author Bob
|
|
*/
|
|
|
|
class Shape {
|
|
public:
|
|
Shape() {
|
|
nshapes++;
|
|
}
|
|
virtual ~Shape() {
|
|
nshapes--;
|
|
};
|
|
/** Important Variables x*/
|
|
double x;
|
|
/** Important Variables y*/
|
|
double y;
|
|
/** Moves the Shape
|
|
* @param dx delta on x
|
|
* @param dy delta on y */
|
|
void move(double dx, double dy);
|
|
/** \return the area */
|
|
virtual double area(void) = 0;
|
|
/** \return the perimeter */
|
|
virtual double perimeter(void) = 0;
|
|
static int nshapes;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Simply running SWIG should result in the following code being
|
|
present in Shapes.cs</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
|
|
/// <summary>This is describing class Shape
|
|
/// Author: Bob
|
|
/// </summary>
|
|
public class Shape {
|
|
|
|
...
|
|
/// Important Variables x
|
|
public double x {
|
|
set {
|
|
ShapesCsPINVOKE.Shape_x_set(swigCPtr, value);
|
|
}
|
|
get {
|
|
double ret = ShapesCsPINVOKE.Shape_x_get(swigCPtr);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
/// Important Variables y
|
|
public double y {
|
|
set {
|
|
ShapesCsPINVOKE.Shape_y_set(swigCPtr, value);
|
|
}
|
|
get {
|
|
double ret = ShapesCsPINVOKE.Shape_y_get(swigCPtr);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
/// Moves the Shape
|
|
/// <param name="dx"> delta on x</param>
|
|
/// <param name="dy"> delta on y</param>
|
|
public void move(double dx, double dy) {
|
|
ShapesCsPINVOKE.Shape_move(swigCPtr, dx, dy);
|
|
}
|
|
|
|
/// <returns>the area</returns>
|
|
public virtual double area() {
|
|
double ret = ShapesCsPINVOKE.Shape_area(swigCPtr);
|
|
return ret;
|
|
}
|
|
|
|
/// <returns>the perimeter</returns>
|
|
public virtual double perimeter() {
|
|
double ret = ShapesCsPINVOKE.Shape_perimeter(swigCPtr);
|
|
return ret;
|
|
}
|
|
|
|
public static int nshapes {
|
|
set {
|
|
ShapesCsPINVOKE.Shape_nshapes_set(value);
|
|
}
|
|
get {
|
|
int ret = ShapesCsPINVOKE.Shape_nshapes_get();
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
</pre>
|
|
</div>
|
|
<p> Otherwise, the code should be identical to what would have been
|
|
generated without the Doxygen functionality enabled. When the Doxygen
|
|
Translator module encounters a comment that contains nothing useful or
|
|
a Doxygen comment that it cannot parse, it will not affect the
|
|
functionality of the SWIG generated code.</p>
|
|
<p> The translator will handle most of the tags conversions (see the
|
|
table below). It will also automatically translate link-objects params,
|
|
in <tt><seealso></tt> tags . Also all <tt>\param</tt> and <tt>\tparam</tt>
|
|
commands are stripped out, if the specified parameter is not present in
|
|
the function. Use <tt>doxygen:nostripparams</tt> to avoid.</p>
|
|
<p> C# translator features summary (see <a href="#Customization_features">
|
|
%feature directives</a>):</p>
|
|
<h3><a name="Doxygen_csharp_tags">18.5.2 C# tags</a></h3>
|
|
<p> Here is the list of all Doxygen tags and the description of how they
|
|
are translated to C# XML</p>
|
|
<div class="diagram">
|
|
<table border="0" summary="CSharp XML Doxygen tags">
|
|
<tr><th align="left">Doxygen tags</th></tr>
|
|
<tr><td>\a</td><td>wrapped with '*' markdown character</td></tr>
|
|
<tr><td>\arg</td><td>prefixed with '*' markdown character</td></tr>
|
|
<tr><td>\author</td><td>Made simple text with prefix 'Author:'</td></tr>
|
|
<tr><td>\authors</td><td>Made simple text with prefix 'Author:'</td></tr>
|
|
<tr><td>\b</td><td>wrapped with '**' markdown character</td></tr>
|
|
<tr><td>\c</td><td>wrapped with `` markdown character</td></tr>
|
|
<tr><td>\cite</td><td>started with ' markdown character</td></tr>
|
|
<tr><td>\code</td><td>wrapped in <code> tag</td></tr>
|
|
<tr><td>\code{<ext>}</td><td>wrapped in <code> tag. code language
|
|
extension is ignored</td></tr>
|
|
<tr><td>\cond</td><td>Ignored</td></tr>
|
|
<tr><td>\copyright</td><td>wrapped in <remark> tag</td></tr>
|
|
<tr><td>\deprecated</td><td>Made simple text with prefix 'Deprecated:'</td>
|
|
</tr>
|
|
<tr><td>\e</td><td>prefixed with '*' markdown character</td></tr>
|
|
<tr><td>\else</td><td>Ignored</td></tr>
|
|
<tr><td>\elseif</td><td>Ignored</td></tr>
|
|
<tr><td>\em</td><td>prefixed with '*' markdown character</td></tr>
|
|
<tr><td>\endcode</td><td>wrapped in <code> tag. code language extension
|
|
is ignored</td></tr>
|
|
<tr><td>\endcond</td><td>Ignored</td></tr>
|
|
<tr><td>\endif</td><td>Ignored</td></tr>
|
|
<tr><td>\endlink</td><td>Ignored</td></tr>
|
|
<tr><td>\endverbatim</td><td>see note for \verbatim</td></tr>
|
|
<tr><td>\exception</td><td>translated to <exception> section</td></tr>
|
|
<tr><td>\f$, \f[, \f], \f{, \f}</td><td>Ignored</td></tr>
|
|
<tr><td>\if</td><td>Ignored</td></tr>
|
|
<tr><td>\ifnot</td><td>Ignored</td></tr>
|
|
<tr><td>\image</td><td>Ignored</td></tr>
|
|
<tr><td>\li</td><td>Ignored</td></tr>
|
|
<tr><td>\link</td><td>Ignored</td></tr>
|
|
<tr><td>\n</td><td>replaced with newline char</td></tr>
|
|
<tr><td>\note</td><td>Content copied</td></tr>
|
|
<tr><td>\overload</td><td>Ignored</td></tr>
|
|
<tr><td>\p</td><td>wrapped with `` markdown characters</td></tr>
|
|
<tr><td>\par</td><td>Made simple text with prefix "Title:"</td></tr>
|
|
<tr><td>\param</td><td>translated to <param> xml section</td></tr>
|
|
<tr><td>\param[<dir>]</td><td>translated to <param> xml section;
|
|
parameter direction ('in'; 'out'; or 'in,out') is ignored</td></tr>
|
|
<tr><td>\remark</td><td>Made simple text with prefix "remarks:"</td></tr>
|
|
<tr><td>\remarks</td><td>Made simple text with prefix "remarks:"</td></tr>
|
|
<tr><td>\result</td><td>translated to <return> xml section</td></tr>
|
|
<tr><td>\return</td><td>translated to <return> xml section</td></tr>
|
|
<tr><td>\returns</td><td>translated to <return> xml section</td></tr>
|
|
<tr><td>\sa</td><td>translated to <seealso> xml section</td></tr>
|
|
<tr><td>\see</td><td>translated to <seealso> xml section</td></tr>
|
|
<tr><td>\since</td><td>Content copied</td></tr>
|
|
<tr><td>\throw</td><td>translated to <exception></td></tr>
|
|
<tr><td>\throws</td><td>translated to <exception></td></tr>
|
|
<tr><td>\todo</td><td>Prefixed with 'TODO:'</td></tr>
|
|
<tr><td>\tparam</td><td>translated to <exception> xml section</td></tr>
|
|
<tr><td>\verbatim</td><td>copied without any processing</td></tr>
|
|
<tr><td>\version</td><td>Made simple text with prefix 'Version:"</td></tr>
|
|
<tr><td>\warning</td><td>Made simple text with prefix 'remarks:"</td></tr>
|
|
<tr><td>\$</td><td>prints $ char</td></tr>
|
|
<tr><td>\@</td><td>prints @ char</td></tr>
|
|
<tr><td>\\</td><td>prints \ char</td></tr>
|
|
<tr><td>\&</td><td>prints & char</td></tr>
|
|
<tr><td>\~</td><td>prints ~ char</td></tr>
|
|
<tr><td>\<</td><td>prints < char</td></tr>
|
|
<tr><td>\></td><td>prints > char</td></tr>
|
|
<tr><td>\#</td><td>prints # char</td></tr>
|
|
<tr><td>\%</td><td>prints % char</td></tr>
|
|
<tr><td>\"</td><td>prints " char</td></tr>
|
|
<tr><td>\.</td><td>prints . char</td></tr>
|
|
<tr><td>\::</td><td>prints ::</td></tr>
|
|
</table>
|
|
</div>
|
|
<h3><a name="Doxygen_csharp_unsupported_tags">18.5.3 Unsupported tags
|
|
for C#</a></h3>
|
|
<p> Doxygen has a wealth of tags such as <tt>@latexonly</tt> that have
|
|
no equivalent in C# XML (all supported tags are listed in <a href="https://www.doxygen.nl/manual/xmlcmds.html">
|
|
XML documentation</a>). As a result several tags have no translation or
|
|
particular use, such as some linking and section tags. These are
|
|
suppressed with their content just printed out (if the tag has any
|
|
sense, typically text content). Here is the list of these tags:</p>
|
|
<div class="diagram"><b> Unsupported Doxygen tags</b>
|
|
<ul style="list-style-type:none;column-count:4;">
|
|
<li>\addindex</li>
|
|
<li>\addtogroup</li>
|
|
<li>\anchor</li>
|
|
<li>\attention</li>
|
|
<li>\brief</li>
|
|
<li>\bug</li>
|
|
<li>\callergraph</li>
|
|
<li>\callgraph</li>
|
|
<li>\category</li>
|
|
<li>\class</li>
|
|
<li>\copybrief</li>
|
|
<li>\copydetails</li>
|
|
<li>\copydoc</li>
|
|
<li>\date</li>
|
|
<li>\def</li>
|
|
<li>\defgroup</li>
|
|
<li>\details</li>
|
|
<li>\dir</li>
|
|
<li>\dontinclude</li>
|
|
<li>\dot</li>
|
|
<li>\dotfile</li>
|
|
<li>\enddot</li>
|
|
<li>\endhtmlonly</li>
|
|
<li>\endinternal</li>
|
|
<li>\endlatexonly</li>
|
|
<li>\endmanonly</li>
|
|
<li>\endmsc</li>
|
|
<li>\endrtfonly</li>
|
|
<li>\endxmlonly</li>
|
|
<li>\enum</li>
|
|
<li>\example</li>
|
|
<li>\extends</li>
|
|
<li>\file</li>
|
|
<li>\fn</li>
|
|
<li>\headerfile</li>
|
|
<li>\hideinitializer</li>
|
|
<li>\htmlinclude</li>
|
|
<li>\htmlonly</li>
|
|
<li>\implements</li>
|
|
<li>\include</li>
|
|
<li>\includelineno</li>
|
|
<li>\ingroup</li>
|
|
<li>\interface</li>
|
|
<li>\internal</li>
|
|
<li>\invariant</li>
|
|
<li>\latexonly</li>
|
|
<li>\line</li>
|
|
<li>\mainpage</li>
|
|
<li>\manonly</li>
|
|
<li>\memberof</li>
|
|
<li>\msc</li>
|
|
<li>\mscfile</li>
|
|
<li>\name</li>
|
|
<li>\namespace</li>
|
|
<li>\nosubgrouping</li>
|
|
<li>\package</li>
|
|
<li>\page</li>
|
|
<li>\paragraph</li>
|
|
<li>\post</li>
|
|
<li>\pre</li>
|
|
<li>\private</li>
|
|
<li>\privatesection</li>
|
|
<li>\property</li>
|
|
<li>\protected</li>
|
|
<li>\protectedsection</li>
|
|
<li>\protocol</li>
|
|
<li>\public</li>
|
|
<li>\publicsection</li>
|
|
<li>\ref</li>
|
|
<li>\related</li>
|
|
<li>\relatedalso</li>
|
|
<li>\relates</li>
|
|
<li>\relatesalso</li>
|
|
<li>\retval</li>
|
|
<li>\rtfonly</li>
|
|
<li>\section</li>
|
|
<li>\short</li>
|
|
<li>\showinitializer</li>
|
|
<li>\skip</li>
|
|
<li>\skipline</li>
|
|
<li>\snippet</li>
|
|
<li>\struct</li>
|
|
<li>\subpage</li>
|
|
<li>\subsection</li>
|
|
<li>\subsubsection</li>
|
|
<li>\tableofcontents</li>
|
|
<li>\test</li>
|
|
<li>\typedef</li>
|
|
<li>\union</li>
|
|
<li>\until</li>
|
|
<li>\var</li>
|
|
<li>\verbinclude</li>
|
|
<li>\weakgroup</li>
|
|
<li>\xmlonly</li>
|
|
<li>\xrefitem</li>
|
|
</ul>
|
|
</div>
|
|
<p> If one of the following Doxygen tags appears as the first tag in a
|
|
comment, the whole comment block is ignored:
|
|
<!-- see parser.y, function isStructuralDoxygen() -->
|
|
</p>
|
|
<div class="diagram"><b> Ignored Doxygen tags</b>
|
|
<ul style="list-style-type:none;column-count:4;">
|
|
<li>\addtogroup</li>
|
|
<li>\callergraph</li>
|
|
<li>\callgraph</li>
|
|
<li>\category</li>
|
|
<li>\class</li>
|
|
<li>\def</li>
|
|
<li>\defgroup</li>
|
|
<li>\dir</li>
|
|
<li>\enum</li>
|
|
<li>\example</li>
|
|
<li>\file</li>
|
|
<li>\fn</li>
|
|
<li>\headerfile</li>
|
|
<li>\hideinitializer</li>
|
|
<li>\interface</li>
|
|
<li>\internal</li>
|
|
<li>\mainpage</li>
|
|
<li>\name</li>
|
|
<li>\namespace</li>
|
|
<li>\nosubgrouping</li>
|
|
<li>\overload</li>
|
|
<li>\package</li>
|
|
<li>\page</li>
|
|
<li>\property</li>
|
|
<li>\protocol</li>
|
|
<li>\relates</li>
|
|
<li>\relatesalso</li>
|
|
<li>\showinitializer</li>
|
|
<li>\struct</li>
|
|
<li>\typedef</li>
|
|
<li>\union</li>
|
|
<li>\var</li>
|
|
<li>\weakgroup</li>
|
|
</ul>
|
|
</div>
|
|
<h2><a name="Doxygen_troubleshooting">18.6 Troubleshooting</a></h2>
|
|
<p> When running SWIG with command line option <tt>-doxygen</tt>, it may
|
|
happen that SWIG will fail to parse the code, which is valid C++ code
|
|
and is parsed without problems without the option. The problem is, that
|
|
Doxygen comments are not tokens (the C/C++ compiler actually never sees
|
|
them) and that they can appear anywhere in the code. That's why it is
|
|
practically impossible to handle all corner cases with the parser.
|
|
However, these problems can usually be avoided by minor changes in the
|
|
code or comment. Known problems and solutions are shown in this
|
|
section.</p>
|
|
<p> Recommended approach is to first run SWIG without command line
|
|
option <tt>-doxygen</tt>. When it successfully processes the code,
|
|
include the option and fix problems with Doxygen comments.</p>
|
|
<h3><a name="troubleshooting_ifndef">18.6.1 Problem with conditional
|
|
compilation</a></h3>
|
|
<p> Inserting a conditional compilation preprocessor directive between a
|
|
Doxygen comment and a commented item may break parsing:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class A {
|
|
/**
|
|
* Some func.
|
|
*/
|
|
<font color="#ff0000">#ifndef SWIG</font>
|
|
void myfunc()
|
|
{
|
|
}
|
|
#endif
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The solution is to move the directive above the comment:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class A {
|
|
<font color="#00d000">#ifndef SWIG</font>
|
|
/**
|
|
* Some func.
|
|
*/
|
|
void myfunc()
|
|
{
|
|
}
|
|
#endif
|
|
};
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Doxygen_developer_details">18.7 Developer information</a></h2>
|
|
<p> This section contains information for developers enhancing the
|
|
Doxygen translator.</p>
|
|
<h3><a name="Doxygen_translator_design">18.7.1 Doxygen translator design</a>
|
|
</h3>
|
|
<p> If this functionality is turned on, SWIG places all comments found
|
|
into the SWIG parse tree. Nodes contain an additional attribute called <tt>
|
|
doxygen</tt> when a comment is present. Individual nodes containing
|
|
Doxygen with Structural Indicators, such as <tt>@file</tt>, as their
|
|
first command, are also present in the parse tree. These individual
|
|
"blobs" of Doxygen such as :</p>
|
|
<div class="code">
|
|
<pre>
|
|
/*! This is describing function Foo
|
|
\param x some random variable
|
|
\author Bob
|
|
\return Foo
|
|
*/
|
|
</pre>
|
|
</div>
|
|
<p> are passed on individually to the Doxygen Translator module. This
|
|
module builds its own private parse tree and hands it to a separate
|
|
class for translation into the target documentation language. For
|
|
example, <tt>JavaDocConverter</tt> is the Javadoc module class.</p>
|
|
<h3><a name="Doxygen_debugging_commands">18.7.2 Debugging the Doxygen
|
|
parser and translator</a></h3>
|
|
<p> There are two handy command line options, that enable lots of
|
|
detailed debug information printing.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
-debug-doxygen-parser - Display Doxygen parser module debugging information
|
|
-debug-doxygen-translator - Display Doxygen translator module debugging information
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Doxygen_tests">18.7.3 Tests</a></h3>
|
|
<p> Doxygen tests have been added to the regular SWIG test-suite. There
|
|
are a number of tests beginning <tt>doxygen_</tt> in the
|
|
Examples/test-suite sub-directory.</p>
|
|
<p> Like any other SWIG test case, the tests are included in
|
|
Examples/test-suite/common.mk and can be tested with commands like <tt>
|
|
make check-test-suite</tt> or <tt>make check-python-test-suite</tt>. To
|
|
run them individually, type <tt>make -s <testname>.cpptest</tt> in the
|
|
language-specific sub-directory in <tt>Examples/test-suite</tt>
|
|
directory. For example:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
Examples/test-suite/java $ make -s doxygen_parsing.cpptest
|
|
</pre>
|
|
</div>
|
|
<p> If the test fails, both expected and translated comments are printed
|
|
to std out, but also written to files<i> expected.txt</i> and<i>
|
|
got.txt</i>. Since it is often difficult to find a single character
|
|
difference in several lines of text, we can use some diff tool, for
|
|
example:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
Examples/test-suite/java $ kdiff3 expected.txt got.txt
|
|
</pre>
|
|
</div>
|
|
<p> Runtime tests in Java are implemented using Javadoc doclets. To make
|
|
that work, you should have tools.jar from the JDK in your classpath. Or
|
|
you should have JAVA_HOME environment variable defined and pointing to
|
|
the JDK location.</p>
|
|
<p> The Java's comment parsing code (the testing part) is located in
|
|
commentParser.java. It checks the generated code. It is possible to run
|
|
this file as a stand-alone program, with <tt>java commentParser <some
|
|
java package></tt>, and it will print the list of comments found in the
|
|
specified directory (in the format it has used in the runtime tests).
|
|
So, when you want to create a new Doxygen test case, just copy an
|
|
existing one and replace the actual comment content (section of entries
|
|
in form 'wantedComments.put(...)' with the output of the above command.</p>
|
|
<p> Runtime tests in Python are just plain string comparisons of the
|
|
__doc__ properties.</p>
|
|
<h2><a name="Doxygen_language_extension">18.8 Extending to other
|
|
languages</a></h2>
|
|
<p> In general, an extension to another language requires a fairly deep
|
|
understanding of the target language module, such as Modules/python.cxx
|
|
for Python. Searching for "doxygen" in the java.cxx module can give you
|
|
a good idea of the process for placing documentation comments into the
|
|
correct areas. The basic gist is that anywhere a comment may reside on
|
|
a node, there needs to be a catch for it in front of where that
|
|
function, class, or other object is written out to a target language
|
|
file. The other half of extension is building a target documentation
|
|
language comment generator that handles one blob at a time. However,
|
|
this is relatively simple and nowhere near as complex as the wrapper
|
|
generating modules in SWIG. See Source/Doxygen/javadoc.cxx for a good
|
|
example. The target language module passes the Doxygen Translator the
|
|
blob to translate, and receives back the translated text.</p>
|
|
<p><b> What is given to the Doxygen Translator</b></p>
|
|
<div class="code">
|
|
<pre>
|
|
/*! This is describing function Foo
|
|
\param x some random variable
|
|
\author Bob
|
|
\return Foo
|
|
*/
|
|
</pre>
|
|
</div>
|
|
<p><b> What is received back by java.cxx</b></p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
/** This is describing function Foo
|
|
*
|
|
* @param x some random variable
|
|
* @author Bob
|
|
* @return Foo
|
|
*/
|
|
</pre>
|
|
</div>
|
|
<p> Development of the comment translator itself is simplified by the
|
|
fact that the Doxygen Translator module can easily include a <tt>main</tt>
|
|
function and thus be developed, compiled, and tested independently of
|
|
SWIG.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Warnings">19 Warning Messages</a></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-559)</a></li>
|
|
<li><a href="#Warnings_doxygen">Doxygen comments (560-599)</a></li>
|
|
<li><a href="#Warnings_nn15">Language module specific (700-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">19.1 Introduction</a></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">19.2 Warning message suppression</a></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="#Customization_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">19.3 Enabling extra warnings</a></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> Preprocessor warning 202 ("Could not evaluate expression<em> expr</em>
|
|
.") was formally off by default and enabled by <tt>-Wextra</tt>, but
|
|
since SWIG 4.1.0 this warning is on by default because suppressing it
|
|
tends to hide genuine problems. If you really don't want to see it, you
|
|
can suppress it with <tt>-w202</tt> or using <tt>%warnfilter</tt> as
|
|
described below. Both will work with older versions of SWIG too.</p>
|
|
<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
|
|
suppressed.</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">19.4 Issuing a warning message</a></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 usage of $1_type $1_name") blah * {
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> In this case, the warning message will be printed whenever the
|
|
typemap is actually used and the <a href="#Typemaps_special_variables">
|
|
special variables</a> will be expanded as appropriate, for example:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:23: Warning 901: You are really going to regret this usage of blah * self
|
|
example.i:24: Warning 901: You are really going to regret this usage of blah * stuff
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Warnings_symbolic_symbols">19.5 Symbolic symbols</a></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">19.6 Commentary</a></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">19.7 Warnings as errors</a></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">19.8 Message output format</a></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(1).
|
|
$ swig -python -Fmicrosoft example.i
|
|
example.i(4) : Syntax error in input(1).
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Warnings_nn9">19.9 Warning number reference</a></h2>
|
|
<h3><a name="Warnings_nn10">19.9.1 Deprecated features (100-199)</a></h3>
|
|
<p>None currently.</p>
|
|
<h3><a name="Warnings_nn11">19.9.2 Preprocessor (200-299)</a></h3>
|
|
<ul>
|
|
<li>201. Unable to find<em> filename</em>.</li>
|
|
<li>202. Could not evaluate expression<em> expr</em>.</li>
|
|
<li>203. Both includeall and importall are defined: using includeall.</li>
|
|
<li>204. CPP #warning, "<em>warning</em>".</li>
|
|
<li>205. CPP #error, "<em>error</em>".</li>
|
|
<li>206. Unexpected tokens after #<em>directive</em> directive.</li>
|
|
</ul>
|
|
<h3><a name="Warnings_nn12">19.9.3 C/C++ Parser (300-399)</a></h3>
|
|
<ul>
|
|
<li>301. <tt>class</tt> keyword used, but not in C++ mode.</li>
|
|
<li>302. Redefinition of identifier '<em>name</em>' as<em> decl</em>
|
|
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>308. Namespace alias '<em>name</em>' not allowed here. Assuming '<em>
|
|
name</em>'</li>
|
|
<li>309. [private | protected] inheritance ignored.</li>
|
|
<li>312. Unnamed nested class 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>317. Specialization of non-template '<em>name</em>'.</li>
|
|
<li>318. Instantiation of template '<em>name</em>' is ambiguous,
|
|
instantiation<em> templ</em> used, instantiation<em> templ</em>
|
|
ignored.</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 identifier '<em>name</em>' as<em>
|
|
decl</em> ignored.</li>
|
|
<li>323. Recursive scope inheritance of '<em>name</em>'.</li>
|
|
<li>324. Named nested template instantiations not supported. Processing
|
|
as if no name was given to %template().</li>
|
|
<li>325. Nested<em> kind</em> not currently supported (<em>name</em>
|
|
ignored).</li>
|
|
<li>326. Deprecated %extend name used - the<em> kind</em> name '<em>name</em>
|
|
' should be used instead of the typedef name '<em>name</em>'.</li>
|
|
<li>327. Extern template ignored.</li>
|
|
<li>328. Value assigned to<em> name</em> not used due to limited parsing
|
|
implementation.</li>
|
|
<li>329. Using declaration '<em>name</em>' for inheriting constructors
|
|
uses base '<em>name</em>' which is not an immediate base of '<em>name</em>
|
|
'.</li>
|
|
<li>330. Template forward class '<em>name</em>' cannot be used to
|
|
instantiate a full template class with name '<em>name</em>'.</li>
|
|
<li>331. Unsupported template nested class '<em>name</em>' cannot be
|
|
used to instantiate a full template class with name '<em>name</em>'.</li>
|
|
<li>340. Lambda expressions and closures are not fully supported yet.</li>
|
|
<li>344. Unable to deduce decltype for '<em>expr</em>'.</li>
|
|
<li>345. Unable to deduce auto return type for '<em>name</em>'
|
|
(ignored).</li>
|
|
<li>346. Unable to deduce auto type for variable '<em>name</em>'
|
|
(ignored).</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>
|
|
<li>396. operator*() ignored.</li>
|
|
<li>397. operator<=> delete[] ignored.</li>
|
|
</ul>
|
|
<h3><a name="Warnings_nn13">19.9.4 Types and typemaps (400-499)</a></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>404. Duplicate template instantiation of '<em>type</em>' with name '<em>
|
|
name</em>' ignored, previous instantiation of '<em>type</em>' with name
|
|
'<em>name</em>'.</li>
|
|
<li>405. Method with rvalue ref-qualifier<em> name</em> ignored.</li>
|
|
<li>406. Ignoring nspace setting (<em>setting</em>) for '<em>type</em>',
|
|
as it conflicts with the nspace setting (<em>setting</em>) for outer
|
|
class '<em>type</em>'</li>
|
|
<li>450. Reserved</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>454. Setting a pointer/reference variable may leak memory</li>
|
|
<li>455. Setting a const wchar_t * variable may leak memory.</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 (incomplete type
|
|
checking rule - no precedence level in typecheck typemap 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>472. Overloaded method<em> method</em> with no explicit typecheck
|
|
typemap for arg<em> number</em> of type '<em>type</em>'. Dispatching
|
|
calls to this method may not work correctly, see the 'Typemaps and
|
|
Overloading' section in the Typemaps chapter of the SWIG documentation.</li>
|
|
<li>473. Returning a reference, pointer or pointer wrapper in a director
|
|
method is not recommended.</li>
|
|
<li>474. Method<em> method</em> usage of the optimal attribute ignored
|
|
in the out typemap 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.</li>
|
|
<li>476. Initialization using std::initializer_list.</li>
|
|
<li>477. No directorthrows typemap defined for<em> type</em></li>
|
|
<li>490. Fragment '<em>name</em>' not found.</li>
|
|
</ul>
|
|
<h3><a name="Warnings_nn14">19.9.5 Code generation (500-559)</a></h3>
|
|
<ul>
|
|
<li>501. Overloaded declaration ignored.<em> decl</em>. Previous
|
|
declaration is<em> decl</em>.</li>
|
|
<li>502. Overloaded constructor ignored.<em> decl</em>. Previous
|
|
declaration is<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. Ignored.</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->(), previous declaration of'<em>declaration</em>'.</li>
|
|
<li>509. Overloaded method<em> declaration</em> effectively ignored, as
|
|
it is shadowed by<em> declaration</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 method<em> declaration</em> ignored, using non-const
|
|
method<em> declaration</em> instead.</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, using<em>
|
|
declaration</em> instead.</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>
|
|
<li>520.<em> Base/Derived</em> class '<em>classname1</em>' of '<em>
|
|
classname2</em>' is not similarly marked as a smart pointer.</li>
|
|
<li>521. Illegal destructor name<em> name</em>. Ignored.</li>
|
|
<li>522. Use of an illegal constructor name '<em>name</em>' in %extend
|
|
is deprecated, the constructor name should be '<em>name</em>'.</li>
|
|
<li>523. Use of an illegal destructor name '<em>name</em>' in %extend is
|
|
deprecated, the destructor name should be '<em>name</em>'.</li>
|
|
<li>524. Experimental target language. Target language<em> language</em>
|
|
specified by<em> lang</em> is an experimental language. See the 'Target
|
|
Languages' section in the Introduction chapter of the SWIG
|
|
documentation.</li>
|
|
<li>525. Destructor<em> declaration</em> is final,<em> name</em> cannot
|
|
be a director class.</li>
|
|
<li>526. Using declaration<em> declaration</em>, with name '<em>name</em>
|
|
', is not actually using the method from<em> declaration</em>, with name
|
|
'<em>name</em>', as the names are different.</li>
|
|
<li>527. Deprecated target language. Target language<em> language</em>
|
|
specified by<em> lang</em> is a deprecated language. It will be removed
|
|
in the next release of SWIG unless a new maintainer steps forward to
|
|
bring it up to at least experimental status. See the 'Target Languages'
|
|
section in the Introduction chapter of the SWIG documentation.</li>
|
|
</ul>
|
|
<h3><a name="Warnings_doxygen">19.9.6 Doxygen comments (560-599)</a></h3>
|
|
<ul>
|
|
<li>560: Unknown Doxygen command:<em> command</em>.</li>
|
|
<li>561: Unexpected end of Doxygen comment encountered.</li>
|
|
<li>562: Expected Doxygen command:<em> command</em></li>
|
|
<li>563: Doxygen HTML error for tag<em> tag</em>:<em> error text</em>.</li>
|
|
<li>564: Error parsing Doxygen command<em> command</em>:<em> error text</em>
|
|
. Command ignored."</li>
|
|
</ul>
|
|
<h3><a name="Warnings_nn15">19.9.7 Language module specific (700-899)</a>
|
|
</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>
|
|
<li>825. "directorconnect" attribute missing in<em> type</em>
|
|
"javaconstruct" typemap. (Java).</li>
|
|
<li>826. The nspace feature is used on '<em>type</em>' without -package.
|
|
The generated code may not compile as Java does not support types
|
|
declared in a named package accessing types declared in an unnamed
|
|
package. (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. (Php).</li>
|
|
<li>871. Unrecognized pragma<em> pragma</em>. (Php).</li>
|
|
</ul>
|
|
<h3><a name="Warnings_nn16">19.9.8 User defined (900-999)</a></h3>
|
|
<p> These numbers can be used by your own application.</p>
|
|
<h2><a name="Warnings_nn17">19.10 History</a></h2>
|
|
<p> The ability to control warning messages was first added to
|
|
SWIG-1.3.12.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Modules">20 Working with Modules</a></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="#Modules_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">20.1 Modules Introduction</a></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 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">20.2 Basics</a></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
|
|
|
|
%{
|
|
#include "base.h"
|
|
%}
|
|
|
|
%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. Often 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
|
|
|
|
%{
|
|
#include "base.h"
|
|
%}
|
|
|
|
%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">20.3 The SWIG runtime code</a></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="Modules_external_run_time">20.4 External access to the
|
|
runtime</a></h2>
|
|
<p>As described in <a href="#Typemaps_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, SWIG can be run in a different mode via <tt>
|
|
-external-runtime</tt> to generate the run-time instead of the normal
|
|
mode of processing an input interface file. For example:<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">20.5 A word of caution about static libraries</a>
|
|
</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">20.6 References</a></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">20.7 Reducing the wrapper file size</a></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">21 Using SWIG with ccache - ccache-swig(1) manpage</a>
|
|
</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">21.1 NAME</a></h2>
|
|
<p> ccache-swig - a fast compiler cache</p>
|
|
<p></p>
|
|
<h2><a name="CCache_nn3">21.2 SYNOPSIS</a></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">21.3 DESCRIPTION</a></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">21.4 OPTIONS SUMMARY</a></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">21.5 OPTIONS</a></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">21.6 INSTALLATION</a></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">21.7 EXTRA OPTIONS</a></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">21.8 ENVIRONMENT VARIABLES</a></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">21.9 CACHE SIZE MANAGEMENT</a></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">21.10 CACHE COMPRESSION</a></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">21.11 HOW IT WORKS</a></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">21.12 USING CCACHE WITH DISTCC</a></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">21.13 SHARING A CACHE</a></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">21.14 HISTORY</a></h2>
|
|
<p> ccache was inspired by the compilercache shell 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">21.15 DIFFERENCES FROM COMPILERCACHE</a></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">21.16 CREDITS</a></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">21.17 AUTHOR</a></h2>
|
|
<p> ccache was written by Andrew Tridgell <a href="https://www.samba.org/~tridge/">
|
|
https://www.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="https://www.swig.org/mail.html">
|
|
https://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>
|
|
<h1><a name="Android">22 SWIG and Android</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Android_overview">Overview</a></li>
|
|
<li><a href="#Android_examples">Android examples</a>
|
|
<ul>
|
|
<li><a href="#Android_examples_intro">Examples introduction</a></li>
|
|
<li><a href="#Android_example_simple">Simple C example</a></li>
|
|
<li><a href="#Android_example_class">C++ class example</a></li>
|
|
<li><a href="#Android_examples_other">Other examples</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Android_stl">C++ STL</a></li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> This chapter describes SWIG's support of Android.</p>
|
|
<h2><a name="Android_overview">22.1 Overview</a></h2>
|
|
<p> The Android chapter is fairly short as support for Android is the
|
|
same as for Java, where the Java Native Interface (JNI) is used to call
|
|
from Android Java into C or C++ compiled code. Everything in the <a href="#Java">
|
|
Java chapter</a> applies to generating code for access from Android Java
|
|
code. This chapter contains a few Android specific notes and examples.</p>
|
|
<h2><a name="Android_examples">22.2 Android examples</a></h2>
|
|
<h3><a name="Android_examples_intro">22.2.1 Examples introduction</a></h3>
|
|
<p> The examples require the <a href="https://developer.android.com/sdk/">
|
|
Android SDK</a> and <a href="https://developer.android.com/ndk/">Android
|
|
NDK</a> which can be installed as per instructions in the links. The
|
|
Eclipse version is not required for these examples as just the command
|
|
line tools are used (shown for Linux as the host, but Windows will be
|
|
very similar, if not identical in most places). Add the SDK tools and
|
|
NDK tools to your path and create a directory somewhere for your
|
|
Android projects (adjust PATH as necessary to where you installed the
|
|
tools):</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ export PATH=$HOME/android/android-sdk-linux_x86/tools:$HOME/android/android-sdk-linux_x86/platform-tools:$HOME/android/android-ndk-r6b:$PATH
|
|
$ mkdir AndroidApps
|
|
$ cd AndroidApps
|
|
</pre>
|
|
</div>
|
|
<p> The examples use a target id of 1. This might need changing
|
|
depending on your setup. After installation of the Android SDK, the
|
|
available target ids can be viewed by running the command below. Please
|
|
adjust the id to suit your target device.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ android list targets
|
|
</pre>
|
|
</div>
|
|
<p> The following examples are shipped with SWIG under the
|
|
Examples/android directory and include a Makefile to build and install
|
|
each example.</p>
|
|
<h3><a name="Android_example_simple">22.2.2 Simple C example</a></h3>
|
|
<p> This simple C example shows how to call a C function as well as read
|
|
and modify a global variable. First we'll create and build a pure Java
|
|
Android app. Afterwards the JNI code will be generated by SWIG and
|
|
built into the app. First create and build an app called <tt>SwigSimple</tt>
|
|
in a subdirectory called <tt>simple</tt> using the commands below.
|
|
Adjust the <tt>--target</tt> id as mentioned earlier in the <a href="#Android_examples_intro">
|
|
Examples introduction</a>. <a href="http://developer.android.com/guide/developing/projects/projects-cmdline.html">
|
|
Managing Projects from the Command Line</a> on the Android developer's
|
|
site is a useful reference for these steps.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ android create project --target 1 --name SwigSimple --path ./simple --activity SwigSimple --package org.swig.simple
|
|
$ cd simple
|
|
$ ant debug
|
|
</pre>
|
|
</div>
|
|
<p> Modify <tt>src/org/swig/simple/SwigSimple.java</tt> from the default
|
|
to:</p>
|
|
<div class="code">
|
|
<pre>
|
|
package org.swig.simple;
|
|
|
|
import android.app.Activity;
|
|
import android.os.Bundle;
|
|
import android.view.View;
|
|
import android.widget.Button;
|
|
import android.widget.TextView;
|
|
import android.widget.ScrollView;
|
|
import android.text.method.ScrollingMovementMethod;
|
|
|
|
public class SwigSimple extends Activity
|
|
{
|
|
TextView outputText = null;
|
|
ScrollView scroller = null;
|
|
|
|
/** Called when the activity is first created. */
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState)
|
|
{
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.main);
|
|
|
|
outputText = (TextView)findViewById(R.id.OutputText);
|
|
outputText.setText("Press 'Run' to start...\n");
|
|
outputText.setMovementMethod(new ScrollingMovementMethod());
|
|
|
|
scroller = (ScrollView)findViewById(R.id.Scroller);
|
|
}
|
|
|
|
public void onRunButtonClick(View view)
|
|
{
|
|
outputText.append("Started...\n");
|
|
nativeCall();
|
|
outputText.append("Finished!\n");
|
|
|
|
// Ensure scroll to end of text
|
|
scroller.post(new Runnable() {
|
|
public void run() {
|
|
scroller.fullScroll(ScrollView.FOCUS_DOWN);
|
|
}
|
|
});
|
|
}
|
|
|
|
/** Calls into C/C++ code */
|
|
public void nativeCall()
|
|
{
|
|
// TODO
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The above simply adds a<i> Run</i> button and scrollable text view
|
|
as the GUI aspects of the program. The associated resources need to be
|
|
created, modify <tt>res/layout/main.xml</tt> as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
android:orientation="vertical"
|
|
android:layout_width="fill_parent"
|
|
android:layout_height="fill_parent"
|
|
>
|
|
<Button
|
|
android:id="@+id/RunButton"
|
|
android:layout_width="wrap_content"
|
|
android:layout_height="wrap_content"
|
|
android:text="Run..."
|
|
android:onClick="onRunButtonClick"
|
|
/>
|
|
<ScrollView
|
|
android:id="@+id/Scroller"
|
|
android:layout_width="fill_parent"
|
|
android:layout_height="fill_parent"
|
|
>
|
|
<TextView
|
|
android:id="@+id/OutputText"
|
|
android:layout_width="wrap_content"
|
|
android:layout_height="wrap_content"
|
|
/>
|
|
</ScrollView>
|
|
</LinearLayout>
|
|
</pre>
|
|
</div>
|
|
<p> Rebuild the project with your changes:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ ant debug
|
|
</pre>
|
|
</div>
|
|
<p> Although there are no native function calls in the code, yet, you
|
|
may want to check that this simple pure Java app runs before adding in
|
|
the native calls. First, set up your Android device for hardware
|
|
debugging, see <a href="http://developer.android.com/guide/developing/device.html">
|
|
Using hardware devices</a> on the Android developer's site. When
|
|
complete your device should be listed in those attached, something
|
|
like:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ adb devices
|
|
List of devices attached
|
|
A32-6DBE0001-9FF80000-015D62C3-02018028 device
|
|
</pre>
|
|
</div>
|
|
<p> This means you are now ready to install the application...</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ adb install bin/SwigSimple-debug.apk
|
|
95 KB/s (4834 bytes in 0.049s)
|
|
pkg: /data/local/tmp/SwigSimple-debug.apk
|
|
Success
|
|
</pre>
|
|
</div>
|
|
<p> The newly installed 'SwigSimple' app will be amongst all your other
|
|
applications on the home screen. Run the app and it will show a<i> Run</i>
|
|
button text box below it. Press the<i> Run</i> button to see the simple
|
|
text output.</p>
|
|
<p> The application can be uninstalled like any other application and in
|
|
fact must be uninstalled before installing an updated version.
|
|
Uninstalling is quite easy too from your host computer:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ adb uninstall org.swig.simple
|
|
Success
|
|
</pre>
|
|
</div>
|
|
<p> Now that you have a pure Java Android app working, let's add some
|
|
JNI code generated from SWIG.</p>
|
|
<p> First create a <tt>jni</tt> subdirectory and then create some C
|
|
source code in <tt>jni/example.c</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File : example.c */
|
|
|
|
/* A global variable */
|
|
double Foo = 3.0;
|
|
|
|
/* Compute the greatest common divisor of positive integers */
|
|
int gcd(int x, int y) {
|
|
int g;
|
|
g = y;
|
|
while (x > 0) {
|
|
g = x;
|
|
x = y % x;
|
|
y = g;
|
|
}
|
|
return g;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Create a SWIG interface file for this C code, <tt>jni/example.i</tt>
|
|
:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File : example.i */
|
|
%module example
|
|
|
|
%inline %{
|
|
extern int gcd(int x, int y);
|
|
extern double Foo;
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> Invoke SWIG as follows:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -java -package org.swig.simple -outdir src/org/swig/simple -o jni/example_wrap.c jni/example.i
|
|
</pre>
|
|
</div>
|
|
<p> SWIG generates the following files:</p>
|
|
<ul>
|
|
<li><tt>src/org/swig/simple/exampleJNI.java</tt></li>
|
|
<li><tt>src/org/swig/simple/example.java</tt></li>
|
|
<li><tt>jni/example_wrap.c</tt></li>
|
|
</ul>
|
|
<p> Next we need to create a standard Android NDK build system file <tt>
|
|
jni/Android.mk</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
# File: Android.mk
|
|
LOCAL_PATH := $(call my-dir)
|
|
|
|
include $(CLEAR_VARS)
|
|
|
|
LOCAL_MODULE := example
|
|
LOCAL_SRC_FILES := example_wrap.c example.c
|
|
|
|
include $(BUILD_SHARED_LIBRARY)
|
|
</pre>
|
|
</div>
|
|
<p> See the <a href="https://developer.android.com/ndk/">Android NDK
|
|
documentation</a> for more on the NDK build system and getting started
|
|
with the NDK. A simple invocation of ndk-build will compile the .c
|
|
files and generate a shared object/system library. Output will be
|
|
similar to:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ ndk-build
|
|
Compile thumb : example <= example_wrap.c
|
|
Compile thumb : example <= example.c
|
|
SharedLibrary : libexample.so
|
|
Install : libexample.so => libs/armeabi/libexample.so
|
|
</pre>
|
|
</div>
|
|
<p> Now that the C JNI layer has been built, we can write Java code to
|
|
call into the this layer. Modify the <tt>nativeCall</tt> method in <tt>
|
|
src/org/swig/simple/SwigSimple.java</tt> to call the JNI code as follows
|
|
and add the static constructor to load the system library containing
|
|
the compiled JNI C code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/** Calls into C/C++ code */
|
|
public void nativeCall()
|
|
{
|
|
// Call our gcd() function
|
|
|
|
int x = 42;
|
|
int y = 105;
|
|
int g = example.gcd(x, y);
|
|
outputText.append("The greatest common divisor of " + x + " and " + y + " is " + g + "\n");
|
|
|
|
// Manipulate the Foo global variable
|
|
|
|
// Output its current value
|
|
double foo = example.getFoo();
|
|
outputText.append("Foo = " + foo + "\n");
|
|
|
|
// Change its value
|
|
example.setFoo(3.1415926);
|
|
|
|
// See if the change took effect
|
|
outputText.append("Foo = " + example.getFoo() + "\n");
|
|
|
|
// Restore value
|
|
example.setFoo(foo);
|
|
}
|
|
|
|
/** static constructor */
|
|
static {
|
|
System.loadLibrary("example");
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Compile the Java code as usual, uninstall the old version of the app
|
|
if still installed and re-install the new app:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ ant debug
|
|
$ adb uninstall org.swig.simple
|
|
$ adb install bin/SwigSimple-debug.apk
|
|
</pre>
|
|
</div>
|
|
<p> Run the app again and this time you will see the output pictured
|
|
below, showing the result of calls into the C code:</p>
|
|
<center><img alt="Android screenshot of SwigSimple example" HEIGHT="400" src="android-simple.png"
|
|
WIDTH="256"></center>
|
|
<h3><a name="Android_example_class">22.2.3 C++ class example</a></h3>
|
|
<p> The steps for calling C++ code are almost identical to those in the
|
|
previous C code example. All the steps required to compile and use a
|
|
simple hierarchy of classes for shapes are shown in this example.</p>
|
|
<p> First create an Android project called <tt>SwigClass</tt> in a
|
|
subdirectory called <tt>class</tt>. The steps below create and build
|
|
the JNI C++ app. Adjust the <tt>--target</tt> id as mentioned earlier
|
|
in the <a href="#Android_examples_intro">Examples introduction</a>.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ android create project --target 1 --name SwigClass --path ./class --activity SwigClass --package org.swig.classexample
|
|
$ cd class
|
|
</pre>
|
|
</div>
|
|
<p> Now create a <tt>jni</tt> subdirectory and then create a C++ header
|
|
file <tt>jni/example.h</tt> which defines our hierarchy of shape
|
|
classes:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File : example.h */
|
|
|
|
class Shape {
|
|
public:
|
|
Shape() {
|
|
nshapes++;
|
|
}
|
|
virtual ~Shape() {
|
|
nshapes--;
|
|
}
|
|
double x, y;
|
|
void move(double dx, double dy);
|
|
virtual double area() = 0;
|
|
virtual double perimeter() = 0;
|
|
static int nshapes;
|
|
};
|
|
|
|
class Circle : public Shape {
|
|
private:
|
|
double radius;
|
|
public:
|
|
Circle(double r) : radius(r) { }
|
|
virtual double area();
|
|
virtual double perimeter();
|
|
};
|
|
|
|
class Square : public Shape {
|
|
private:
|
|
double width;
|
|
public:
|
|
Square(double w) : width(w) { }
|
|
virtual double area();
|
|
virtual double perimeter();
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> and create the implementation in the <tt>jni/example.cpp</tt> file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File : example.cpp */
|
|
|
|
#include "example.h"
|
|
#define M_PI 3.14159265358979323846
|
|
|
|
/* Move the shape to a new location */
|
|
void Shape::move(double dx, double dy) {
|
|
x += dx;
|
|
y += dy;
|
|
}
|
|
|
|
int Shape::nshapes = 0;
|
|
|
|
double Circle::area() {
|
|
return M_PI*radius*radius;
|
|
}
|
|
|
|
double Circle::perimeter() {
|
|
return 2*M_PI*radius;
|
|
}
|
|
|
|
double Square::area() {
|
|
return width*width;
|
|
}
|
|
|
|
double Square::perimeter() {
|
|
return 4*width;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Create a SWIG interface file for this C++ code in <tt>jni/example.i</tt>
|
|
:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File : example.i */
|
|
%module example
|
|
|
|
%{
|
|
#include "example.h"
|
|
%}
|
|
|
|
/* Let's just grab the original header file here */
|
|
%include "example.h"
|
|
</pre>
|
|
</div>
|
|
<p> Invoke SWIG as follows, note that the -c++ option is required for
|
|
C++ code:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c++ -java -package org.swig.classexample -outdir src/org/swig/classexample -o jni/example_wrap.cpp jni/example.i
|
|
</pre>
|
|
</div>
|
|
<p> SWIG generates the following files:</p>
|
|
<ul>
|
|
<li><tt>src/org/swig/classexample/Square.java</tt></li>
|
|
<li><tt>src/org/swig/classexample/exampleJNI.java</tt></li>
|
|
<li><tt>src/org/swig/classexample/example.java</tt></li>
|
|
<li><tt>src/org/swig/classexample/Circle.java</tt></li>
|
|
<li><tt>src/org/swig/classexample/Shape.java</tt></li>
|
|
<li><tt>jni/example_wrap.cpp</tt></li>
|
|
</ul>
|
|
<p> Next we need to create an Android NDK build system file for
|
|
compiling the C++ code <tt>jni/Android.mk</tt>. The <tt>-frtti</tt>
|
|
compiler flag isn't strictly needed for this example, but is needed for
|
|
any code that uses C++ RTTI:</p>
|
|
<div class="code">
|
|
<pre>
|
|
# File: Android.mk
|
|
LOCAL_PATH := $(call my-dir)
|
|
|
|
include $(CLEAR_VARS)
|
|
|
|
LOCAL_MODULE := example
|
|
LOCAL_SRC_FILES := example_wrap.cpp example.cpp
|
|
LOCAL_CFLAGS := -frtti
|
|
|
|
include $(BUILD_SHARED_LIBRARY)
|
|
</pre>
|
|
</div>
|
|
<p> A simple invocation of ndk-build will compile the .cpp files and
|
|
generate a shared object/system library. Output will be similar to:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ ndk-build
|
|
Compile++ thumb : example <= example_wrap.cpp
|
|
Compile++ thumb : example <= example.cpp
|
|
StaticLibrary : libstdc++.a
|
|
SharedLibrary : libexample.so
|
|
Install : libexample.so => libs/armeabi/libexample.so
|
|
</pre>
|
|
</div>
|
|
<p> Now that the C JNI layer has been built, we can write Java code to
|
|
call into this layer. Modify <tt>
|
|
src/org/swig/classexample/SwigClass.java</tt> from the default to:</p>
|
|
<div class="code">
|
|
<pre>
|
|
package org.swig.classexample;
|
|
|
|
import android.app.Activity;
|
|
import android.os.Bundle;
|
|
import android.view.View;
|
|
import android.widget.Button;
|
|
import android.widget.TextView;
|
|
import android.widget.ScrollView;
|
|
import android.text.method.ScrollingMovementMethod;
|
|
|
|
public class SwigClass extends Activity
|
|
{
|
|
TextView outputText = null;
|
|
ScrollView scroller = null;
|
|
|
|
/** Called when the activity is first created. */
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState)
|
|
{
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.main);
|
|
|
|
outputText = (TextView)findViewById(R.id.OutputText);
|
|
outputText.setText("Press 'Run' to start...\n");
|
|
outputText.setMovementMethod(new ScrollingMovementMethod());
|
|
|
|
scroller = (ScrollView)findViewById(R.id.Scroller);
|
|
}
|
|
|
|
public void onRunButtonClick(View view)
|
|
{
|
|
outputText.append("Started...\n");
|
|
nativeCall();
|
|
outputText.append("Finished!\n");
|
|
|
|
// Ensure scroll to end of text
|
|
scroller.post(new Runnable() {
|
|
public void run() {
|
|
scroller.fullScroll(ScrollView.FOCUS_DOWN);
|
|
}
|
|
});
|
|
}
|
|
|
|
/** Calls into C/C++ code */
|
|
public void nativeCall()
|
|
{
|
|
// ----- Object creation -----
|
|
|
|
outputText.append( "Creating some objects:\n" );
|
|
Circle c = new Circle(10);
|
|
outputText.append( " Created circle " + c + "\n");
|
|
Square s = new Square(10);
|
|
outputText.append( " Created square " + s + "\n");
|
|
|
|
// ----- Access a static member -----
|
|
|
|
outputText.append( "\nA total of " + Shape.getNshapes() + " shapes were created\n" );
|
|
|
|
// ----- Member data access -----
|
|
|
|
// Notice how we can do this using functions specific to
|
|
// the 'Circle' class.
|
|
c.setX(20);
|
|
c.setY(30);
|
|
|
|
// Now use the same functions in the base class
|
|
Shape shape = s;
|
|
shape.setX(-10);
|
|
shape.setY(5);
|
|
|
|
outputText.append( "\nHere is their current position:\n" );
|
|
outputText.append( " Circle = (" + c.getX() + " " + c.getY() + ")\n" );
|
|
outputText.append( " Square = (" + s.getX() + " " + s.getY() + ")\n" );
|
|
|
|
// ----- Call some methods -----
|
|
|
|
outputText.append( "\nHere are some properties of the shapes:\n" );
|
|
Shape[] shapes = {c, s};
|
|
for (int i=0; i<shapes.length; i++)
|
|
{
|
|
outputText.append( " " + shapes[i].toString() + "\n" );
|
|
outputText.append( " area = " + shapes[i].area() + "\n" );
|
|
outputText.append( " perimeter = " + shapes[i].perimeter() + "\n" );
|
|
}
|
|
|
|
// Notice how the area() and perimeter() functions really
|
|
// invoke the appropriate virtual method on each object.
|
|
|
|
// ----- Delete everything -----
|
|
|
|
outputText.append( "\nGuess I'll clean up now\n" );
|
|
|
|
// Note: this invokes the virtual destructor
|
|
// You could leave this to the garbage collector
|
|
c.delete();
|
|
s.delete();
|
|
|
|
outputText.append( Shape.getNshapes() + " shapes remain\n" );
|
|
outputText.append( "Goodbye\n" );
|
|
}
|
|
|
|
/** static constructor */
|
|
static {
|
|
System.loadLibrary("example");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Note the static constructor and the interesting JNI code is in the <tt>
|
|
nativeCall</tt> method. The remaining code deals with the GUI aspects
|
|
which are identical to the previous C simple example. Modify <tt>
|
|
res/layout/main.xml</tt> to contain the xml for the 'Run' button and
|
|
scrollable text view:</p>
|
|
<div class="code">
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
android:orientation="vertical"
|
|
android:layout_width="fill_parent"
|
|
android:layout_height="fill_parent"
|
|
>
|
|
<Button
|
|
android:id="@+id/RunButton"
|
|
android:layout_width="wrap_content"
|
|
android:layout_height="wrap_content"
|
|
android:text="Run..."
|
|
android:onClick="onRunButtonClick"
|
|
/>
|
|
<ScrollView
|
|
android:id="@+id/Scroller"
|
|
android:layout_width="fill_parent"
|
|
android:layout_height="fill_parent"
|
|
>
|
|
<TextView
|
|
android:id="@+id/OutputText"
|
|
android:layout_width="wrap_content"
|
|
android:layout_height="wrap_content"
|
|
/>
|
|
</ScrollView>
|
|
</LinearLayout>
|
|
</pre>
|
|
</div>
|
|
<p> Compile the Java code as usual, uninstall the old version of the app
|
|
if installed and re-install the new app:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ ant debug
|
|
$ adb uninstall org.swig.classexample
|
|
$ adb install bin/SwigClass-debug.apk
|
|
</pre>
|
|
</div>
|
|
<p> Run the app to see the result of calling the C++ code from Java:</p>
|
|
<center><img alt="Android screenshot of SwigClass example" HEIGHT="400" src="android-class.png"
|
|
WIDTH="256"></center>
|
|
<h3><a name="Android_examples_other">22.2.4 Other examples</a></h3>
|
|
<p> The Examples/android directory contains further examples which can
|
|
be run and installed in a similar manner to the previous two examples.</p>
|
|
<p> Note that the 'extend' example is demonstrates the directors
|
|
feature. Normally C++ exception handling and the STL is not available
|
|
by default in the version of g++ shipped with Android, but this example
|
|
turns these features on as described in the next section.</p>
|
|
<h2><a name="Android_stl">22.3 C++ STL</a></h2>
|
|
<p> Should the C++ Standard Template Library (STL) be required, an <tt>
|
|
Application.mk</tt> file needs to be created in the same directory as
|
|
the <tt>Android.mk</tt> directory containing information about the STL
|
|
to use. See the NDK documentation in the $NDKROOT/docs folder
|
|
especially CPLUSPLUS-SUPPORT.html. Below is an example of the <tt>
|
|
Application.mk</tt> file to make the STLport static library available
|
|
for use:</p>
|
|
<div class="code">
|
|
<pre>
|
|
# File: Application.mk
|
|
APP_STL := gnustl_static
|
|
</pre>
|
|
</div><HR NOSHADE>
|
|
<h1><a name="CSharp">23 SWIG and C#</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#CSharp_introduction">Introduction</a>
|
|
<ul>
|
|
<li><a href="#CSharp_introduction_swig2_compatibility">SWIG 2
|
|
Compatibility</a></li>
|
|
<li><a href="#CSharp_commandline">Additional command line options</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#CSharp_differences_java">Differences to the Java module</a>
|
|
</li>
|
|
<li><a href="#CSharp_type_mapping">Type mapping</a>
|
|
<ul>
|
|
<li><a href="#CSharp_primitive_types">Primitive types</a></li>
|
|
<li><a href="#CSharp_other_type_mappings">Other types</a></li>
|
|
<li><a href="#CSharp_void_pointers">Void pointers</a></li>
|
|
</ul>
|
|
</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_multiple_modules">Multiple modules</a></li>
|
|
<li><a href="#CSharp_named_arguments">C# named and optional arguments</a>
|
|
</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_date_pre_post_directors">Date example demonstrating
|
|
the 'pre' and 'post' typemap attributes for directors</a></li>
|
|
<li><a href="#CSharp_partial_classes">Turning proxy classes into partial
|
|
classes</a></li>
|
|
<li><a href="#CSharp_sealed_proxy_class">Turning proxy classes into
|
|
sealed classes</a></li>
|
|
<li><a href="#CSharp_extending_proxy_class">Extending proxy classes with
|
|
additional C# code</a></li>
|
|
<li><a href="#CSharp_enum_underlying_type">Underlying type for enums</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<h2><a name="CSharp_introduction">23.1 Introduction</a></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="https://msdn.microsoft.com/en-us/ie/aa290048(v=vs.94)">
|
|
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="https://www.mono-project.com/Main_Page/">Mono</a>.</p>
|
|
<p> SWIG 3 and later requires .NET 2.0 at a minimum. There are some
|
|
minor exceptions, where the minimum required is .NET 4.0. This is when
|
|
using the <tt>std::complex</tt> and <tt>std::list</tt> STL containers.</p>
|
|
<p> To get the most out of this chapter an understanding of interop is
|
|
required. The <a href="https://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="https://www.mono-project.com/docs/advanced/pinvoke/">
|
|
Interop with native libraries</a>.</p>
|
|
<h3><a name="CSharp_introduction_swig2_compatibility">23.1.1 SWIG 2
|
|
Compatibility</a></h3>
|
|
<p> In order to minimize name collisions between names generated based
|
|
on input to SWIG and names used in the generated code from the .NET
|
|
framework, SWIG 3 fully qualifies the use of all .NET types.
|
|
Furthermore, SWIG 3 avoids <tt>using</tt> directives in generated code.
|
|
This breaks backwards compatibility with typemaps, pragmas, etc written
|
|
for use with SWIG 2 that assume the presence of <tt>using System;</tt>
|
|
or <tt>using System.Runtime.InteropServices;</tt> directives in the
|
|
intermediate class imports, module imports, or proxy imports. SWIG 3
|
|
supports backwards compatibility though the use of the <tt>SWIG2_CSHARP</tt>
|
|
macro. If <tt>SWIG2_CSHARP</tt> is defined, SWIG 3 generates <tt>using</tt>
|
|
directives in the intermediate class, module class, and proxy class
|
|
code similar to those generated by SWIG 2. This can be done without
|
|
modifying any of the input code by passing the <tt>-DSWIG2_CSHARP</tt>
|
|
commandline parameter when executing <tt>swig</tt>.</p>
|
|
<h3><a name="CSharp_commandline">23.1.2 Additional command line options</a>
|
|
</h3>
|
|
<p> The following table lists the additional commandline options
|
|
available for the C# module. They can also be seen by using:</p>
|
|
<div class="code">
|
|
<pre>
|
|
swig -csharp -help
|
|
</pre>
|
|
</div>
|
|
<table summary="C# specific options">
|
|
<tr><th>C# specific options</th></tr>
|
|
<tr><td>-dllimport <dl></td><td>Override DllImport attribute name to
|
|
<dl></td></tr>
|
|
<tr><td>-namespace <nm></td><td>Generate wrappers into C# namespace <nm></td>
|
|
</tr>
|
|
<tr><td>-noproxy</td><td>Generate the low-level functional interface
|
|
instead of proxy classes</td></tr>
|
|
<tr><td>-oldvarnames</td><td>Old intermediary method names for variable
|
|
wrappers</td></tr>
|
|
<tr><td>-outfile <file></td><td>Write all C# into a single <file>
|
|
located in the output directory</td></tr>
|
|
<tr><td>-doxygen</td><td> Convert C++ doxygen comments to CSharp
|
|
comments</td></tr>
|
|
</table>
|
|
<p> The -outfile option combines all the generated C# code into a single
|
|
output file instead of creating multiple C# files. The default, when
|
|
this option is not provided, is to generate separate .cs files for the
|
|
module class, intermediary class and each of the generated proxy and
|
|
type wrapper classes. Note that the file extension (.cs) will not be
|
|
automatically added and needs to be provided. Due to possible compiler
|
|
limits it is not advisable to use <tt>-outfile</tt> for large projects.</p>
|
|
<h2><a name="CSharp_differences_java">23.2 Differences to the Java
|
|
module</a></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 <a href="#SWIGPlus_nspace">nspace feature</a> is also supported
|
|
as described in this general section with a C# example. Unlike Java
|
|
which requires the use of the -package option when using the <tt>nspace</tt>
|
|
feature, the -namespace option is not mandatory for C#.</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 -> csdisposing and csdispose
|
|
javadestruct_derived -> csdisposing_derived and csdispose_derived
|
|
javainterfacemodifiers -> csinterfacemodifiers
|
|
javainterfacecode -> csinterfacecode
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>Typemap macros:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIG_JAVABODY_PROXY -> SWIG_CSBODY_PROXY
|
|
SWIG_JAVABODY_TYPEWRAPPER -> SWIG_CSBODY_TYPEWRAPPER
|
|
</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>Additional typemap attributes:</p>
|
|
<p> The "null" attribute in the "out" typemap can be specified to
|
|
provide a value for <tt>$null</tt> to expand into for wrapped functions
|
|
that return non-void. Normally the default value of <tt>0</tt> is used.
|
|
For example this is needed if you change the return type to void:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(ctype) Status "void"
|
|
%typemap(out, null="") Status { ... }
|
|
</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
|
|
$javaclazzname -> $csclazzname
|
|
$javainput -> $csinput
|
|
$jnicall -> $imcall
|
|
$javainterfacename -> $csinterfacename
|
|
$&javainterfacename -> $&csinterfacename
|
|
$*javainterfacename -> $*csinterfacename
|
|
</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 "csdirectorin"
|
|
typemap supports additional optional attributes called '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. Please see the <a href="#CSharp_date_pre_post_directors">
|
|
Date marshalling director example</a> for further understanding of the
|
|
"csdirectorin" 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="global::System.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 global::System.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. The 'imtype' typemap can also have an optional <tt>
|
|
directorinattributes</tt> and <tt>directoroutattributes</tt> typemap
|
|
attribute which attaches to director delegates, an implementation
|
|
detail of directors, see <a href="#CSharp_directors_implementation">
|
|
directors implementation</a>. Note that there are C# attributes and
|
|
typemap attributes, don't get confused between the two!! 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="[global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStr)]",
|
|
outattributes="[return: global::System.Runtime.InteropServices.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 {
|
|
...
|
|
[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_GetMsg")]
|
|
[return: global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStr)]
|
|
public static extern String GetMsg();
|
|
|
|
[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_SetMsg")]
|
|
public static extern void SetMsg([global::System.Runtime.InteropServices.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>
|
|
<p> The <tt>directorinattributes</tt> and <tt>directoroutattributes</tt>
|
|
typemap attribute are attached to the delegates in the director class,
|
|
for example, the SwigDelegateBase_0</p>
|
|
</li>
|
|
<li>
|
|
<p> Support for attaching C# attributes to wrapped methods, variables
|
|
and enum values. This is done using the <tt>%csattributes</tt> feature,
|
|
see <a href="#Customization_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 : global::System.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>
|
|
<p> An example for attaching attributes to the enum and enum values is
|
|
shown below.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(csattributes) Couleur "[global::System.ComponentModel.Description(\"Colours\")]"
|
|
%csattributes Rouge "[global::System.ComponentModel.Description(\"Red\")]"
|
|
%csattributes Vert "[global::System.ComponentModel.Description(\"Green\")]"
|
|
%inline %{
|
|
enum Couleur { Rouge, Orange, Vert };
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> which will result in the following C# enum:</p>
|
|
<div class="code">
|
|
<pre>
|
|
[global::System.ComponentModel.Description("Colours")]
|
|
public enum Couleur {
|
|
[global::System.ComponentModel.Description("Red")]
|
|
Rouge,
|
|
Orange,
|
|
[global::System.ComponentModel.Description("Green")]
|
|
Vert
|
|
}
|
|
</pre>
|
|
</div></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> <a name="CSharp_begin"></a>
|
|
<p> The <tt>%module</tt> directive supports the <tt>csbegin</tt> option
|
|
for adding code to the start of every generated C# file. This is useful
|
|
for adding common comments, using statements and/or preprocessor
|
|
statements into all generated .cs files. For example, C# 8 nullable
|
|
reference types can be enabled via a C# preprocessor directive by
|
|
adding <tt>#nullable enable</tt> into C# files as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(csbegin="#nullable enable\n") mymodule
|
|
</pre>
|
|
</div>
|
|
<p> It might be easier to use a macro for multiple lines of code, for
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%define CSBEGIN_CODE
|
|
"
|
|
/* Copyright statement */
|
|
using System.Text;
|
|
#nullable enable
|
|
"
|
|
%enddef
|
|
|
|
%module(csbegin=CSBEGIN_CODE) mymodule
|
|
</pre>
|
|
</div></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><b> <tt>$imfuncname</tt></b>
|
|
<br> This special variable expands to the name of the function in the
|
|
intermediary class that will be used in $imcall. Like, $imcall, this
|
|
special variable is only expanded in the "csout", "csvarin" and
|
|
"csvarout" typemaps.</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.
|
|
This also works with newer versions of Visual Studio if you allow it to
|
|
convert the solution to the latest version. 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. After
|
|
SWIG has run and both the C# and C/C++ compilers have finished
|
|
building, the examples will be run, by either running <tt>runme.exe</tt>
|
|
or by running <tt>mono runme.exe</tt> (Mono C# compiler). Windows users
|
|
can also get the examples working using a <a href="http://www.cygwin.com">
|
|
Cygwin</a> or <a href="https://osdn.net/projects/mingw/">MinGW</a>
|
|
environment for automatic configuration of the example makefiles. Any
|
|
one of the C# compilers (Mono or Microsoft) can be detected from within
|
|
a Cygwin or MinGW environment if installed in your path.</p>
|
|
<h2><a name="CSharp_type_mapping">23.3 Type mapping</a></h2>
|
|
<p> The marshalling of the types and typemaps used for marshalling
|
|
across the managed/unmanaged layers are discussed in this section. The
|
|
interested reader will find the implementation in the csharp.swg file.</p>
|
|
<h3><a name="CSharp_primitive_types">23.3.1 Primitive types</a></h3>
|
|
<p> Primitive types are marshalled between the unmanaged and managed
|
|
layers as blittable types.</p>
|
|
<ul>
|
|
<li> The first column in the table below shows various C/C++ types that
|
|
might be parsed by SWIG.</li>
|
|
<li> The second column contains the default type provided by the 'ctype'
|
|
typemap, that is, the type used for marshalling on the C side.</li>
|
|
<li> The third column shows the default type provided by both the
|
|
'imtype' and the 'cstype' typemaps, that is, the equivalent type on the
|
|
C# side.</li>
|
|
<li> The fourth column shows the size or number of bytes of the
|
|
'imtype'/'cstype', which may or may not match the size of the C/C++
|
|
type and is discussed next.</li>
|
|
</ul>
|
|
<table BORDER summary="Default primitive type mappings">
|
|
<tr><td><b>C/C++ type</b></td><td><b>ctype</b></td><td><b>imtype/cstype</b>
|
|
</td><td><b>Size</b></td></tr>
|
|
<tr><td>bool
|
|
<br> const bool &</td><td>unsigned int</td><td>bool</td><td>1</td></tr>
|
|
<tr><td>char
|
|
<br>const char &</td><td>char</td><td>char</td><td>1</td></tr>
|
|
<tr><td>signed char
|
|
<br>const signed char &</td><td>signed char</td><td>sbyte</td><td>1</td></tr>
|
|
<tr><td>unsigned char
|
|
<br>const unsigned char &</td><td>unsigned char</td><td>byte</td><td>1</td>
|
|
</tr>
|
|
<tr><td>short
|
|
<br>const short &</td><td>short</td><td>short</td><td>2</td></tr>
|
|
<tr><td>unsigned short
|
|
<br> const unsigned short &</td><td>unsigned short</td><td>ushort</td><td>
|
|
2</td></tr>
|
|
<tr><td>int
|
|
<br> const int &</td><td>int</td><td>int</td><td>4</td></tr>
|
|
<tr><td>unsigned int
|
|
<br> const unsigned int &</td><td>unsigned int</td><td>uint</td><td>4</td>
|
|
</tr>
|
|
<tr><td>long
|
|
<br>const long &</td><td>int</td><td>int</td><td>4</td></tr>
|
|
<tr><td>unsigned long
|
|
<br>const unsigned long &</td><td>unsigned int</td><td>uint</td><td>4</td>
|
|
</tr>
|
|
<tr><td>long long
|
|
<br> const long long &</td><td>long long</td><td>long</td><td>8</td></tr>
|
|
<tr><td>unsigned long long
|
|
<br>const unsigned long long &</td><td>unsigned long long</td><td>ulong</td><td>
|
|
8</td></tr>
|
|
<tr><td>float
|
|
<br>const float &</td><td>float</td><td>float</td><td>4</td></tr>
|
|
<tr><td>double
|
|
<br> const double &</td><td>double</td><td>double</td><td>8</td></tr>
|
|
<tr><td>size_t
|
|
<br> const size_t &</td><td>unsigned int</td><td>uint</td><td>4</td></tr>
|
|
</table>
|
|
<p> The size in bytes of the C type, 'ctype', should match the C# type,
|
|
'imtype' for blitting across the managed/unmanaged layers. They do
|
|
match across the common 32-bit and 64-bit operating systems, Unix,
|
|
Windows and MacOS, except for the C long/unsigned long and size_t
|
|
types. From the table above the default is to handle C long and size_t
|
|
as a 32-bit (4 byte) type, so large numbers could be truncated on some
|
|
64-bit operating systems. If <tt>SWIGWORDSIZE64</tt> is defined the C
|
|
long type is instead handled as a 64-bit (8 byte) type, as per the
|
|
table below.</p>
|
|
<table BORDER summary="SWIGWORDSIZE64 primitive type mappings">
|
|
<tr><td><b>C/C++ type</b></td><td><b>ctype</b></td><td><b>imtype/cstype</b>
|
|
</td><td><b>Size</b></td></tr>
|
|
<tr><td>long
|
|
<br>const long &</td><td>long long</td><td>long</td><td>8</td></tr>
|
|
<tr><td>unsigned long
|
|
<br>const unsigned long &</td><td>unsigned long long</td><td>ulong</td><td>
|
|
8</td></tr>
|
|
</table>
|
|
<p> However, truncation may then occur when the C long type is actually
|
|
32-bits (4 bytes). It's best to avoid using C long for portability
|
|
across different operating systems!</p>
|
|
<p> If you need to support long on a range of systems where the size of
|
|
long varies, then steps must be taken before invoking SWIG to determine
|
|
whether or not to define <tt>SWIGWORDSIZE64</tt> when invoking SWIG.</p>
|
|
<p> In order to treat the C size_t type as a 64-bit (8 byte) type, apply
|
|
the 64-bit typemaps as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%apply unsigned long long { size_t };
|
|
%apply const unsigned long long & { const size_t & };
|
|
</pre>
|
|
</div>
|
|
<p> The net effect then changes from the default shown earlier to:</p>
|
|
<table BORDER summary="size_t long long mappings">
|
|
<tr><td><b>C/C++ type</b></td><td><b>ctype</b></td><td><b>imtype/cstype</b>
|
|
</td><td><b>Size</b></td></tr>
|
|
<tr><td>size_t
|
|
<br>const size_t &</td><td>unsigned long long</td><td>ulong</td><td>8</td>
|
|
</tr>
|
|
</table>
|
|
<p> If you need to support size_t on a range of systems where the size
|
|
of size_t varies, then steps must be taken before invoking SWIG to
|
|
determine whether or not to apply the typemaps. Conditionally applying
|
|
the typemaps using a macro is easily done. For example define <tt>
|
|
MY_SIZET_WORDSIZE64</tt> to generate 64-bit (8 byte) handling using the
|
|
following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#if defined(MY_SIZET_WORDSIZE64)
|
|
%apply unsigned long long { size_t };
|
|
%apply const unsigned long long & { const size_t & };
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CSharp_other_type_mappings">23.3.2 Other types</a></h3>
|
|
<p> The table below shows the equivalent mappings for pointers and
|
|
strings. Classes and structs are marshalled using a pointer to the
|
|
instance of the object. Note the types in the 'imtype' and 'cstype'
|
|
typemaps can be different.</p>
|
|
<ul>
|
|
<li> The 'imtype' type is used for marshalling across the managed and
|
|
unmanaged boundary.</li>
|
|
<li> The 'cstype' is the final C# proxy or intermediary class type.</li>
|
|
<li> In the table below, the 'imtype' type is used for marshalling from
|
|
the managed to the unmanaged layer.</li>
|
|
<li> The 'imtype out' type is used for marshalling from the unmanaged to
|
|
the managed layer.</li>
|
|
</ul>
|
|
<table BORDER summary="Other type mappings">
|
|
<tr><td><b>C/C++ type</b></td><td><b>ctype</b></td><td><b>imtype</b></td><td>
|
|
<b>imtype out</b></td><td><b>cstype</b></td></tr>
|
|
<tr><td>char *
|
|
<br>char []</td><td>char *</td><td>string</td><td>string</td><td>string</td>
|
|
</tr>
|
|
<tr><td>void *</td><td>void *</td><td>
|
|
System.Runtime.InteropServices.HandleRef</td><td>System.IntPtr</td><td>
|
|
SWIGTYPE_p_void</td></tr>
|
|
</table>
|
|
<h3><a name="CSharp_void_pointers">23.3.3 Void pointers</a></h3>
|
|
<p> By default SWIG treats <tt>void *</tt> as any other pointer and
|
|
hence marshalls it as a type wrapper class called <tt>SWIGTYPE_p_void</tt>
|
|
, as shown in the table in the previous section. If you want to marshall
|
|
with the .NET <tt>System.IntPtr</tt> type instead, there is a simple
|
|
set of named typemaps called <tt>void *VOID_INT_PTR</tt> that can be
|
|
used. The net effect is then:</p>
|
|
<table BORDER summary="VOID_INT_PTR type mappings">
|
|
<tr><td><b>C/C++ type</b></td><td><b>ctype</b></td><td><b>imtype</b></td><td>
|
|
<b>imtype out</b></td><td><b>cstype</b></td></tr>
|
|
<tr><td>void *VOID_INT_PTR</td><td>void *</td><td>System.IntPtr</td><td>
|
|
System.IntPtr</td><td>System.IntPtr</td></tr>
|
|
</table>
|
|
<p> This is achieved by applying them like any other named typemaps:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%apply void *VOID_INT_PTR { void * }
|
|
void * f(void *v);
|
|
</pre>
|
|
</div>
|
|
<h2><a name="CSharp_arrays">23.4 C# Arrays</a></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">23.4.1 The SWIG C arrays
|
|
library</a></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">23.4.2
|
|
Managed arrays using P/Invoke default array marshalling</a></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 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="https://docs.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-for-arrays">
|
|
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>
|
|
[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_myArrayCopy")]
|
|
public static extern void myArrayCopy([global::System.Runtime.InteropServices.In, global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPArray)]int[] jarg1,
|
|
[global::System.Runtime.InteropServices.Out, global::System.Runtime.InteropServices.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 intermediary class method</p>
|
|
<div class="code">
|
|
<pre>
|
|
[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_myArraySwap")]
|
|
public static extern void myArraySwap([global::System.Runtime.InteropServices.In, global::System.Runtime.InteropServices.Out, global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPArray)]int[] jarg1,
|
|
[global::System.Runtime.InteropServices.In, global::System.Runtime.InteropServices.Out, global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPArray)]int[] jarg2,
|
|
int jarg3);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CSharp_arrays_pinning">23.4.3 Managed arrays using pinning</a>
|
|
</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="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/fixed-statement">
|
|
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((global::System.IntPtr)swig_ptrTo_sourceArray, (global::System.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 intermediary 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>
|
|
[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_myArrayCopy")]
|
|
public static extern void myArrayCopy(global::System.IntPtr jarg1, global::System.IntPtr jarg2, int jarg3);
|
|
</pre>
|
|
</div>
|
|
<h2><a name="CSharp_exceptions">23.5 C# Exceptions</a></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="#Customization_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">23.5.1 C# exception
|
|
example using "check" typemap</a></h3>
|
|
<p> Let's 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">23.5.2 C#
|
|
exception example using %exception</a></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="#Customization_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());
|
|
return $null;
|
|
}
|
|
%}
|
|
|
|
%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">23.5.3
|
|
C# exception example using exception specifications</a></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">23.5.4 Custom C#
|
|
ApplicationException example</a></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);
|
|
|
|
[global::System.Runtime.InteropServices.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 : global::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">23.6 C# Directors</a></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">23.6.1 Directors example</a></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)
|
|
{
|
|
global::System.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">23.6.2 Directors
|
|
implementation</a></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>
|
|
public class Base : global::System.IDisposable {
|
|
private global::System.Runtime.InteropServices.HandleRef swigCPtr;
|
|
protected bool swigCMemOwn;
|
|
|
|
internal Base(global::System.IntPtr cPtr, bool cMemoryOwn) {
|
|
swigCMemOwn = cMemoryOwn;
|
|
swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
|
|
}
|
|
|
|
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Base obj) {
|
|
return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
|
|
}
|
|
|
|
~Base() {
|
|
Dispose();
|
|
}
|
|
|
|
public virtual void Dispose() {
|
|
lock(this) {
|
|
if(swigCPtr.Handle != global::System.IntPtr.Zero && swigCMemOwn) {
|
|
swigCMemOwn = false;
|
|
examplePINVOKE.delete_Base(swigCPtr);
|
|
}
|
|
swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
|
|
global::System.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(SwigDirectorMethodUIntMethod);
|
|
if (SwigDerivedClassHasMethod("BaseBoolMethod", swigMethodTypes1))
|
|
swigDelegate1 = new SwigDelegateBase_1(SwigDirectorMethodBaseBoolMethod);
|
|
examplePINVOKE.Base_director_connect(swigCPtr, swigDelegate0, swigDelegate1);
|
|
}
|
|
|
|
private bool SwigDerivedClassHasMethod(string methodName, global::System.global::System.Type[] methodTypes) {
|
|
System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, methodTypes);
|
|
bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(Base));
|
|
return hasDerivedMethod;
|
|
}
|
|
|
|
private uint SwigDirectorMethodUIntMethod(uint x) {
|
|
return UIntMethod(x);
|
|
}
|
|
|
|
private void SwigDirectorMethodBaseBoolMethod(global::System.IntPtr b, bool flag) {
|
|
BaseBoolMethod(new Base(b, false), flag);
|
|
}
|
|
|
|
public delegate uint SwigDelegateBase_0(uint x);
|
|
public delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
|
|
|
|
private SwigDelegateBase_0 swigDelegate0;
|
|
private SwigDelegateBase_1 swigDelegate1;
|
|
|
|
private static global::System.Type[] swigMethodTypes0 = new global::System.Type[] { typeof(uint) };
|
|
private static global::System.Type[] swigMethodTypes1 = new global::System.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>SwigDirectorMethodBaseBoolMethod</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>
|
|
SwigDirectorMethodBaseBoolMethod</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>
|
|
<p> The delegates from the above example are <tt>public</tt> by default:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public delegate uint SwigDelegateBase_0(uint x);
|
|
public delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
|
|
</pre>
|
|
</div>
|
|
<p> These can be changed if desired via the <tt>
|
|
csdirectordelegatemodifiers</tt> <a href="#Customization_features">
|
|
%feature directive</a>. For example, using <tt>
|
|
%feature("csdirectordelegatemodifiers") "internal"</tt> before SWIG
|
|
parses the Base class will change all the delegates to <tt>internal</tt>
|
|
:</p>
|
|
<div class="code">
|
|
<pre>
|
|
internal delegate uint SwigDelegateBase_0(uint x);
|
|
internal delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CSharp_director_caveats">23.6.3 Director caveats</a></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_multiple_modules">23.7 Multiple modules</a></h2>
|
|
<p> When using <a href="#Modules">multiple modules</a> it is possible to
|
|
compile each SWIG generated wrapper into a different assembly. However,
|
|
by default the generated code may not compile if generated classes in
|
|
one assembly use generated classes in another assembly. The visibility
|
|
of the <tt>getCPtr()</tt> and pointer constructor generated from the <tt>
|
|
csbody</tt> typemaps needs changing. The default visibility is <tt>
|
|
internal</tt> but it needs to be <tt>public</tt> for access from a
|
|
different assembly. Just changing 'internal' to 'public' in the typemap
|
|
achieves this. Two macros are available in <tt>csharp.swg</tt> to make
|
|
this easier and using them is the preferred approach over simply
|
|
copying the typemaps and modifying as this is forward compatible with
|
|
any changes in the <tt>csbody</tt> typemap in future versions of SWIG.
|
|
The macros are for the proxy and typewrapper classes and can
|
|
respectively be used to to make the method and constructor public:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIG_CSBODY_PROXY(public, public, SWIGTYPE)
|
|
SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
|
|
</pre>
|
|
</div>
|
|
<p> Alternatively, instead of exposing these as public, consider using
|
|
the <tt>[assembly:InternalsVisibleTo("Name")]</tt> attribute available
|
|
in the .NET framework when you know which assemblies these can be
|
|
exposed to.</p>
|
|
<p> Another approach would be to make these public, but also to hide
|
|
them from intellisense by using the <tt>
|
|
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
|
</tt> attribute if you don't want users to easily stumble upon these so
|
|
called 'internal workings' of the wrappers. You can do this like so:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#define PUBLIC_BUT_HIDDEN [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public
|
|
SWIG_CSBODY_PROXY(PUBLIC_BUT_HIDDEN, PUBLIC_BUT_HIDDEN, SWIGTYPE)
|
|
SWIG_CSBODY_TYPEWRAPPER(PUBLIC_BUT_HIDDEN, PUBLIC_BUT_HIDDEN, PUBLIC_BUT_HIDDEN, SWIGTYPE)
|
|
</pre>
|
|
</div>
|
|
<h2><a name="CSharp_named_arguments">23.8 C# named and optional
|
|
arguments</a></h2>
|
|
<p> In C++ you can specify default arguments for functions, methods, and
|
|
constructors. C# offers named arguments. This feature, specific to C#,
|
|
lets you bind default argument functions with default arguments in C#.
|
|
SWIG also allows you to add default arguments to C# functions which
|
|
don't have default arguments in C++.</p>
|
|
<p> The <tt>cs:defaultargs</tt> feature enables C# named arguments with
|
|
C# default values. Using this feature will turn off SWIG's default
|
|
handling for default arguments, which would create an override for each
|
|
defaulted argument.</p>
|
|
<p>For this feature, you first specify the function/method/constructor
|
|
you want it to impact. Inside the feature call you specify each
|
|
argument you want to override. If you specify none, it will take the
|
|
literal text from c++ for each argument and apply that in C#. That
|
|
often works fine, but when it doesn't you can supply a string literal
|
|
with a C# expression to be used as an override. Or you can supply an
|
|
int literal, or a float literal. If you want to give a literal string
|
|
you need to include an escaped quote at the start and end of the
|
|
literal such as <tt>"\"a string\""</tt>.</p>
|
|
<p> Let's consider an example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("cs:defaultargs") Foo::Foo;
|
|
%feature("cs:defaultargs", x=0, z=4) Foo::bar;
|
|
%feature("cs:defaultargs", x="\"five\"") Foo::zoo;
|
|
|
|
%inline %{
|
|
class Foo {
|
|
public:
|
|
Foo(int a, int b=1, int c=2)
|
|
{
|
|
}
|
|
int bar(int x, int y=2, int z=3)
|
|
{
|
|
return x+y+z;
|
|
}
|
|
int bat(int x=1, int y=2, int z=3)
|
|
{
|
|
return x+y+z;
|
|
}
|
|
int zoo(std::string x="four")
|
|
{
|
|
return (int)x.size();
|
|
}
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The generated C# proxy class contains:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public class Foo : global::System.IDisposable {
|
|
...
|
|
public Foo(int a, int b=1, int c=2) ...
|
|
|
|
public int bar(int x=0, int y=2, int z=4) ...
|
|
|
|
public int bat(int x, int y, int z) ...
|
|
public int bat(int x, int y) ...
|
|
public int bat(int x) ...
|
|
public int bat() ...
|
|
|
|
public int zoo(string x="five") ...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Note that:</p>
|
|
<ol>
|
|
<li> The constructor uses the default arguments exactly as taken from
|
|
C++.</li>
|
|
<li> The <tt>bar</tt> method uses the default arguments exactly as taken
|
|
from C++ apart from <tt>z</tt> whose default value is changed to 4, and
|
|
<tt>x</tt> did not have a default value in C++, but does in the
|
|
generated C#.</li>
|
|
<li> The <tt>bat</tt> method does not use the <tt>cs:defaultargs</tt>
|
|
feature and so the default handling of one overloaded C# method per
|
|
defaulted C++ argument is generated.</li>
|
|
<li> The <tt>zoo</tt> method's string value is overridden by the new
|
|
string value from the feature.</li>
|
|
</ol>
|
|
<p><b> Compatibility Note:</b> SWIG-4.2.0 added support for the <tt>
|
|
cs:defaultargs</tt> feature.</p>
|
|
<h2><a name="CSharp_typemap_examples">23.9 C# Typemap examples</a></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">23.9.1 Memory
|
|
management when returning references to member variables</a></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 = 0) : 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();
|
|
global::System.Console.WriteLine("wheel size: " + wheel.size);
|
|
// Simulate a garbage collection
|
|
global::System.GC.Collect();
|
|
global::System.GC.WaitForPendingFinalizers();
|
|
global::System.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 {
|
|
global::System.IntPtr cPtr = $imcall;$excode
|
|
$csclassname ret = null;
|
|
if (cPtr != global::System.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 : global::System.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 : global::System.IDisposable {
|
|
...
|
|
public Wheel getWheel() {
|
|
global::System.IntPtr cPtr = examplePINVOKE.Bike_getWheel(swigCPtr);
|
|
Wheel ret = null;
|
|
if (cPtr != global::System.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">23.9.2 Memory management
|
|
for objects passed to the C++ layer</a></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 occurring...</p>
|
|
<div class="code">
|
|
<pre>
|
|
Container container = new Container();
|
|
Element element = new Element(20);
|
|
container.setElement(element);
|
|
global::System.Console.WriteLine("element.value: " + container.getElement().value);
|
|
// Simulate a garbage collection
|
|
global::System.GC.Collect();
|
|
global::System.GC.WaitForPendingFinalizers();
|
|
global::System.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 : global::System.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;
|
|
|
|
public void setElement(Element e) {
|
|
examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
|
|
elementReference = e;
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The following typemaps can be used to generate this code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%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;
|
|
%}
|
|
|
|
%typemap(csin,
|
|
post=" elementReference = $csinput;"
|
|
) Element *e "Element.getCPtr($csinput)"
|
|
</pre>
|
|
</div>
|
|
<p> The 'cscode' typemap simply adds in the specified code into the C#
|
|
proxy class. The 'csin' typemap matches the input parameter type and
|
|
name for the <tt>setElement</tt> method and the 'post' typemap
|
|
attribute allows adding code after the PInvoke call. The 'post' code is
|
|
generated into a finally block after the PInvoke call so the resulting
|
|
code isn't quite as mentioned earlier, <tt>setElement</tt> is actually:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public void setElement(Element e) {
|
|
try {
|
|
examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
|
|
} finally {
|
|
elementReference = e;
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CSharp_date_marshalling">23.9.3 Date marshalling using the
|
|
csin typemap and associated attributes</a></h3>
|
|
<p> The <a href="#Java_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 : global::System.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
|
|
modified 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 : global::System.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 global::System.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">23.9.4 A date example demonstrating
|
|
marshalling of C# properties</a></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">
|
|
Structure 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 {
|
|
global::System.IntPtr cPtr = $imcall;
|
|
CDate tempDate = (cPtr == global::System.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 {
|
|
global::System.IntPtr cPtr = examplePINVOKE.ImportantDate_get();
|
|
CDate tempDate = (cPtr == global::System.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_date_pre_post_directors">23.9.5 Date example
|
|
demonstrating the 'pre' and 'post' typemap attributes for directors</a></h3>
|
|
<p> The 'pre' and 'post' attributes in the "csdirectorin" typemap act
|
|
like the attributes of the same name in the "csin" typemap. For example
|
|
if we modify the <a href="#CSharp_date_marshalling">Date marshalling
|
|
example</a> like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class CDate {
|
|
...
|
|
void setYear(int);
|
|
void setMonth(int);
|
|
void setDay(int);
|
|
};
|
|
struct Action {
|
|
virtual void someCallback(CDate &date);
|
|
virtual ~Action();
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> and declare <tt>%feature ("director")</tt> for the <tt>Action</tt>
|
|
class, we would have to define additional marshalling rules for <tt>
|
|
CDate &</tt> parameter. The typemap may look like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(csdirectorin,
|
|
pre="System.DateTime temp$iminput = new System.DateTime();",
|
|
post="CDate temp2$iminput = new CDate($iminput, false);\n"
|
|
"temp2$iminput.setYear(tempdate.Year);\n"
|
|
"temp2$iminput.setMonth(tempdate.Month);\n"
|
|
"temp2$iminput.setDay(tempdate.Day);"
|
|
) CDate &date "out temp$iminput"
|
|
</pre>
|
|
</div>
|
|
<p> The generated proxy class code will then contain the following
|
|
wrapper for calling user-overloaded <tt>someCallback()</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
...
|
|
private void SwigDirectorMethodsomeCallback(global::System.IntPtr date) {
|
|
System.DateTime tempdate = new System.DateTime();
|
|
try {
|
|
someCallback(out tempdate);
|
|
} finally {
|
|
// we create a managed wrapper around the existing C reference, just for convenience
|
|
CDate temp2date = new CDate(date, false);
|
|
temp2date.setYear(tempdate.Year);
|
|
temp2date.setMonth(tempdate.Month);
|
|
temp2date.setDay(tempdate.Day);
|
|
}
|
|
}
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> Pay special attention to the memory management issues, using these
|
|
attributes.</p>
|
|
<h3><a name="CSharp_partial_classes">23.9.6 Turning proxy classes into
|
|
partial classes</a></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 : global::System.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 : global::System.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 : global::System.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_sealed_proxy_class">23.9.7 Turning proxy classes
|
|
into sealed classes</a></h3>
|
|
<p> The technique in the previous section can be used to make the proxy
|
|
class a sealed class. Consider a C++ class <tt>NotABaseClass</tt> that
|
|
you don't want to be derived from in C#:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct NotABaseClass {
|
|
NotABaseClass();
|
|
~NotABaseClass();
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The default C# proxy class method generated with Dispose method is:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public class NotABaseClass : global::System.IDisposable {
|
|
...
|
|
public virtual void Dispose() {
|
|
...
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>csclassmodifiers</tt> typemap can be used to modify the
|
|
class modifiers and the <tt>csmethodmodifiers</tt> feature can be used
|
|
on the destructor to modify the proxy's <tt>Dispose</tt> method:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(csclassmodifiers) NotABaseClass "public sealed class"
|
|
%csmethodmodifiers NotABaseClass::~NotABaseClass "public /*virtual*/";
|
|
</pre>
|
|
</div>
|
|
<p> The relevant generated code is thus:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public sealed class NotABaseClass : global::System.IDisposable {
|
|
...
|
|
public /*virtual*/ void Dispose() {
|
|
...
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Any attempt to derive from the <tt>NotABaseClass</tt> in C# will
|
|
result in a C# compiler error, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public class Derived : NotABaseClass {
|
|
};
|
|
</pre>
|
|
</div><div class="shell">
|
|
<pre>
|
|
runme.cs(6,14): error CS0509: `Derived': cannot derive from sealed type `NotABaseClass'
|
|
</pre>
|
|
</div>
|
|
<p> Finally, if you get a warning about use of 'protected' in the
|
|
generated base class:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
NotABaseClass.cs(14,18): warning CS0628: `NotABaseClass.swigCMemOwn': new protected member declared in sealed class
|
|
</pre>
|
|
</div>
|
|
<p> Either suppress the warning or modify the generated code by copying
|
|
and tweaking the default 'csbody' typemap code in csharp.swg by
|
|
modifying swigCMemOwn to not be protected.</p>
|
|
<h3><a name="CSharp_extending_proxy_class">23.9.8 Extending proxy
|
|
classes with additional C# code</a></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 : global::System.IDisposable {
|
|
...
|
|
public int Part3() {
|
|
return 3;
|
|
}
|
|
public int Part1() {
|
|
...
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="CSharp_enum_underlying_type">23.9.9 Underlying type for
|
|
enums</a></h3>
|
|
<p> C# enums use int as the underlying type for each enum item, unless
|
|
there is a C++11 enum base specifying the underlying C++ enum type. If
|
|
there is a C++ base enum then this is automatically converted to the
|
|
equivalent C# integral type. If you wish to change the underlying type
|
|
to something else, then use the <tt>csbase</tt> typemap. For example
|
|
when your C++ code uses a value larger than int, this is necessary as
|
|
the C# compiler will not compile values which are too large to fit into
|
|
an int. Here is an example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(csbase) BigNumbers "uint"
|
|
%inline %{
|
|
enum BigNumbers { big=0x80000000, bigger };
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The generated enum will then use the given underlying type and
|
|
compile correctly:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
public enum BigNumbers : uint {
|
|
big = 0x80000000,
|
|
bigger
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> If a C++11 enum base is specified, such as <tt>unsigned short</tt>
|
|
in the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%inline %{
|
|
enum SmallNumbers : unsigned short { tiny, small=1 };
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The underlying type is automatically converted to the C# equivalent,
|
|
<tt>ushort</tt>:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
public enum SmallNumbers : ushort {
|
|
tiny,
|
|
small = 1
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The underlying C# type can still be changed to something else using
|
|
the csbase typemap but the <tt>replace</tt> attribute must be set to
|
|
avoid an ignored warnings as there are effectively two specified bases,
|
|
which of course is not possible. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(csbase, replace="1") SmallNumbers "byte"
|
|
%inline %{
|
|
enum SmallNumbers : unsigned short { tiny, small=1 };
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> which generates the desired underlying enum type:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
public enum SmallNumbers : byte {
|
|
tiny,
|
|
small = 1
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> If SWIG cannot find appropriate type information for the C++ enum
|
|
base, then a type wrapper class (something like SWIGTYPE_p_xxxx) is
|
|
generated for the C# enum base. This will not compile in C#, as a C#
|
|
integral base is required. To fix this, make sure the C++ enum base
|
|
type information is parsed by SWIG; this is usually a typedef to an
|
|
integral type. Note that SWIG uses the cstype typemap to lookup the C#
|
|
type for any given C++ type. Using the csbase typemap, as described
|
|
above, overrides the default cstype for looking up the C# integral base
|
|
type.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="D">24 SWIG and D</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#D_introduction">Introduction</a></li>
|
|
<li><a href="#D_command_line_invocation">Command line invocation</a></li>
|
|
<li><a href="#D_typemaps">Typemaps</a>
|
|
<ul>
|
|
<li><a href="#D_typemap_name_comparison">C# <-> D name comparison</a></li>
|
|
<li><a href="#D_ctype_imtype_dtype">ctype, imtype, dtype</a></li>
|
|
<li><a href="#D_in_out_directorin_direcetorout">in, out, directorin,
|
|
directorout</a></li>
|
|
<li><a href="#D_din_dout_ddirectorin_ddirectorout">din, dout,
|
|
ddirectorin, ddirectorout</a></li>
|
|
<li><a href="#D_typecheck_typemaps">typecheck typemaps</a></li>
|
|
<li><a href="#D_code_injection_typemaps">Code injection typemaps</a></li>
|
|
<li><a href="#D_special_variables">Special variable macros</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#D_other_code_control">Other D code control features</a>
|
|
<ul>
|
|
<li><a href="#D_module">D begin</a></li>
|
|
<li><a href="#D_features">D and %feature</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#D_pragmas">Pragmas</a></li>
|
|
<li><a href="#D_exceptions">D Exceptions</a></li>
|
|
<li><a href="#D_directors">D Directors</a></li>
|
|
<li><a href="#D_other_features">Other features</a>
|
|
<ul>
|
|
<li><a href="#D_nspace">Extended namespace support (nspace)</a></li>
|
|
<li><a href="#D_native_pointer_support">Native pointer support</a></li>
|
|
<li><a href="#D_operator_overloading">Operator overloading</a></li>
|
|
<li><a href="#D_test_suite">Running the test-suite</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#D_typemap_examples">D Typemap examples</a></li>
|
|
<li><a href="#D_planned_features">Work in progress and planned features</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<h2><a name="D_introduction">24.1 Introduction</a></h2>
|
|
<p>From the <a href="https://www.digitalmars.com/d/">D Programming
|
|
Language</a> web site:<em> D is a systems programming language. Its
|
|
focus is on combining the power and high performance of C and C++ with
|
|
the programmer productivity of modern languages like Ruby and Python.
|
|
[...] The D language is statically typed and compiles directly to
|
|
machine code.</em> As such, it is not very surprising that D is able to
|
|
directly <a href="https://www.digitalmars.com/d/1.0/interfaceToC.html">
|
|
interface with C libraries</a>. Why would a SWIG module for D be needed
|
|
then in the first place?</p>
|
|
<p>Well, besides the obvious downside that the C header files have to be
|
|
manually converted to D modules for this to work, there is one major
|
|
inconvenience with this approach: D code usually is on a higher
|
|
abstraction level than C, and many of the features that make D
|
|
interesting are simply not available when dealing with C libraries,
|
|
requiring you e.g. to manually convert strings between pointers to <tt>
|
|
\0</tt>-terminated char arrays and D char arrays, making the algorithms
|
|
from the D2 standard library unusable with C arrays and data
|
|
structures, and so on.</p>
|
|
<p>While these issues can be worked around relatively easy by
|
|
hand-coding a thin wrapper layer around the C library in question,
|
|
there is another issue where writing wrapper code per hand is not
|
|
feasible: C++ libraries. Support for C++ was added in D2 via <tt>
|
|
extern(C++)</tt> but this support is still very limited, and a custom
|
|
wrapper layer is still required in many cases.</p>
|
|
<p>To help addressing these issues, the SWIG C# module has been forked
|
|
to support D. Is has evolved quite a lot since then, but there are
|
|
still many similarities, so if you do not find what you are looking for
|
|
on this page, it might be worth having a look at the chapter on <a href="#CSharp">
|
|
C#</a> (and also on <a href="#Java">Java</a>, since the C# module was in
|
|
turn forked from it).</p>
|
|
<h2><a name="D_command_line_invocation">24.2 Command line invocation</a></h2>
|
|
<p>To activate the D module, pass the <tt>-d</tt> option to SWIG at the
|
|
command line. The same standard command line options as with any other
|
|
language module are available, plus the following D specific ones:</p>
|
|
<dl>
|
|
<dt><tt>-d2</tt></dt>
|
|
<dd>
|
|
<p>Prior to SWIG 4.2.0, SWIG generated wrappers for D1/Tango by default
|
|
and <tt>-d2</tt> could be used to generate D2/Phobos wrappers instead.
|
|
SWIG 4.2.0 dropped support for D1, and D2 wrappers are now produced by
|
|
default. This option is still recognised to allow existing build
|
|
systems calling SWIG to work, but is now a no-op.</p>
|
|
</dd>
|
|
<dt><a name="D_splitproxy"></a><tt>-splitproxy</tt></dt>
|
|
<dd>
|
|
<p>By default, SWIG generates two D modules: the<em> proxy</em> module,
|
|
named like the source module (either specified via the <tt>%module</tt>
|
|
directive or via the <tt>module</tt> command line option), which
|
|
contains all the proxy classes, functions, enums, etc., and the<em>
|
|
intermediary</em> module (named like the proxy module, but suffixed
|
|
with <tt>_im</tt>), which contains all the <tt>extern(C)</tt> function
|
|
declarations and other private parts only used internally by the proxy
|
|
module.</p>
|
|
<p>If the split proxy mode is enabled by passing this option at the
|
|
command line, all proxy classes and enums are emitted to their own D
|
|
module instead. The main proxy module only contains free functions and
|
|
constants in this case.</p>
|
|
</dd>
|
|
<dt><tt>-package <pkg></tt></dt>
|
|
<dd>
|
|
<p>By default, the proxy D modules and the intermediary D module are
|
|
written to the root package. Using this option, you can specify another
|
|
target package instead.</p>
|
|
</dd>
|
|
<dt><tt>-wrapperlibrary <wl></tt></dt>
|
|
<dd>
|
|
<p>The code SWIG generates to dynamically load the C/C++ wrapper layer
|
|
looks for a library called <tt>$module_wrap</tt> by default. With this
|
|
option, you can override the name of the file the wrapper code loads at
|
|
runtime (the <tt>lib</tt> prefix and the suffix for shared libraries
|
|
are appended automatically, depending on the OS).</p>
|
|
<p>This might especially be useful if you want to invoke SWIG several
|
|
times on separate modules, but compile the resulting code into a single
|
|
shared library.</p>
|
|
</dd>
|
|
</dl>
|
|
<h2><a name="D_typemaps">24.3 Typemaps</a></h2>
|
|
<h3><a name="D_typemap_name_comparison">24.3.1 C# <-> D name comparison</a>
|
|
</h3>
|
|
<p>If you already know the SWIG C# module, you might find the following
|
|
name comparison table useful:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
ctype <-> ctype
|
|
imtype <-> imtype
|
|
cstype <-> dtype
|
|
csin <-> din
|
|
csout <-> dout
|
|
csdirectorin <-> ddirectorin
|
|
csdirectorout <-> ddirectorout
|
|
csinterfaces <-> dinterfaces
|
|
csinterfaces_derived <-> dinterfaces_derived
|
|
csbase <-> dbase
|
|
csclassmodifiers <-> dclassmodifiers
|
|
cscode <-> dcode
|
|
csimports <-> dimports
|
|
csbody <-> dbody
|
|
csfinalize <-> ddestructor
|
|
csdisposing <-> ddispose
|
|
csdisposing_derived <-> ddispose_derived
|
|
</pre>
|
|
</div>
|
|
<h3><a name="D_ctype_imtype_dtype">24.3.2 ctype, imtype, dtype</a></h3>
|
|
<p>Mapping of types between the C/C++ library, the C/C++ library wrapper
|
|
exposing the C functions, the D wrapper module importing these
|
|
functions and the D proxy code.</p>
|
|
<p>The <tt>ctype</tt> typemap is used to determine the types to use in
|
|
the C wrapper functions. The types from the <tt>imtype</tt> typemap are
|
|
used in the extern(C) declarations of these functions in the
|
|
intermediary D module. The <tt>dtype</tt> typemap contains the D types
|
|
used in the D proxy module/class.</p>
|
|
<h3><a name="D_in_out_directorin_direcetorout">24.3.3 in, out,
|
|
directorin, directorout</a></h3>
|
|
<p>Used for converting between the types for C/C++ and D when generating
|
|
the code for the wrapper functions (on the C++ side).</p>
|
|
<p>The code from the <tt>in</tt> typemap is used to convert arguments to
|
|
the C wrapper function to the type used in the wrapped code (<tt>ctype</tt>
|
|
->original C++ type), the <tt>out</tt> typemap is utilized to convert
|
|
values from the wrapped code to wrapper function return types (original
|
|
C++ type-><tt>ctype</tt>).</p>
|
|
<p>The <tt>directorin</tt> typemap is used to convert parameters to the
|
|
type used in the D director callback function, its return value is
|
|
processed by <tt>directorout</tt> (see below).</p>
|
|
<h3><a name="D_din_dout_ddirectorin_ddirectorout">24.3.4 din, dout,
|
|
ddirectorin, ddirectorout</a></h3>
|
|
<p>Typemaps for code generation in D proxy and type wrapper classes.</p>
|
|
<p><a name="D_din"></a>The <tt>din</tt> typemap is used for converting
|
|
function parameter types from the type used in the proxy module or
|
|
class to the type used in the intermediary D module (the <a href="#D_dinput">
|
|
$dinput</a> macro is replaced). To inject further parameter processing
|
|
code before or after the call to the intermediary layer, the <tt>pre</tt>
|
|
, <tt>post</tt> and <tt>terminator</tt> attributes can be used (please
|
|
refer to the <a href="#CSharp_date_marshalling">C# date marshalling
|
|
example</a> for more information on these).</p>
|
|
<p><a name="D_dout"></a>The <tt>dout</tt> typemap is used for converting
|
|
function return values from the return type used in the intermediary D
|
|
module to the type returned by the proxy function. The <tt>$excode</tt>
|
|
special variable in <tt>dout</tt> typemaps is replaced by the <tt>
|
|
excode</tt> typemap attribute code if the method can throw any
|
|
exceptions from unmanaged code, otherwise by nothing (the <a href="#D_imcall">
|
|
<tt>$imcall</tt> and <tt>$owner</tt></a> macros are replaced).</p>
|
|
<p><a name="D_ddirectorinout"></a>The code from the <tt>ddirectorin</tt>
|
|
and <tt>ddirectorout</tt> typemaps is used for conversion in director
|
|
callback functions. Arguments are converted to the type used in the
|
|
proxy class method they are calling by using the code from <tt>
|
|
ddirectorin</tt>, the proxy class method return value is converted to
|
|
the type the C++ code expects via the <tt>ddirectorout</tt> typemap
|
|
(the <a href="#D_dpcall"><tt>$dcall</tt> and <tt>$winput</tt></a>
|
|
macros are replaced).</p>
|
|
<p>The full chain of type conversions when a director callback is
|
|
invoked looks like this:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
type CPPClass::method(type a)
|
|
↑ ↓
|
|
<directorout> <directorin>
|
|
↑ ↓
|
|
ctype methodCallback(ctype a) C++
|
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
imtype methodCallback(imtype a) D
|
|
↑ ↓
|
|
<ddirectorout> <ddirectorin>
|
|
↑ ↓
|
|
dtype DClass.method(dtype a)</pre>
|
|
</div>
|
|
<h3><a name="D_typecheck_typemaps">24.3.5 typecheck typemaps</a></h3>
|
|
<p>Because, unlike many scripting languages supported by SWIG, D does
|
|
not need any dynamic dispatch helper to access an overloaded function,
|
|
the purpose of these is merely to issue a warning for overloaded C++
|
|
functions that cannot be overloaded in D (as more than one C++ type
|
|
maps to a single D type).</p>
|
|
<h3><a name="D_code_injection_typemaps">24.3.6 Code injection typemaps</a>
|
|
</h3>
|
|
<p>These typemaps are used for generating the skeleton of proxy classes
|
|
for C++ types.</p>
|
|
<p>By overriding <tt>dbase</tt>, <tt>dinterfaces</tt> or <tt>
|
|
dinterfaces_derived</tt>, the inheritance chain of the generated proxy
|
|
class for a type can be modified. <tt>dclassmodifiers</tt> allows you
|
|
to add any custom modifiers around the class keyword.</p>
|
|
<p>Using <tt>dcode</tt> and <tt>dimports</tt>, you can specify
|
|
additional D code which will be emitted into the class body
|
|
respectively the imports section of the D module the class is written
|
|
to.</p>
|
|
<p><a name="D_class_code_typemaps"></a><tt>dconstructor</tt>, <tt>
|
|
ddestructor</tt>, <tt>ddispose</tt> and <tt>ddispose_derived</tt> are
|
|
used to generate the class constructor, destructor and <tt>dispose()</tt>
|
|
method, respectively. The auxiliary code for handling the pointer to
|
|
the C++ object is stored in <tt>dbody</tt> and <tt>dbody_derived</tt>.
|
|
You can override them for specific types.</p>
|
|
<p> Code can also be injected into the D proxy class using <tt>
|
|
%proxycode</tt>.</p>
|
|
<h3><a name="D_special_variables">24.3.7 Special variable macros</a></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>When generating D wrappers, a few additional macros are available:</p>
|
|
<dl>
|
|
<dt><tt>$dclassname</tt> (C#: <tt>$csclassname</tt>)</dt>
|
|
<dd>
|
|
<p>This special variable works similar to <a href="#Typemaps_special_variables">
|
|
<tt>$n_type</tt></a> in that it returns the name of a type - it expands
|
|
to the D proxy class name of the type being wrapped. If the type does
|
|
not have an associated proxy class, it expands to the type wrapper
|
|
class name, for example, <tt>SWIGTYPE_p_p_SomeCppClass</tt> is
|
|
generated when wrapping <tt>SomeCppClass **</tt>.</p>
|
|
<p>There are two other variants available, <tt>$&dclassname</tt> and <tt>
|
|
$*dclassname</tt>. The former adds a level of indirection, while the
|
|
latter removes one. For instance, when wrapping <tt>Foo **</tt>, <tt>
|
|
$*dclassname</tt> would be replaced by the proxy class name
|
|
corresponding to <tt>Foo *</tt>.</p>
|
|
</dd>
|
|
<dt><tt>$dclazzname</tt> (C#: <tt>$csclazzname</tt>)</dt>
|
|
<dd>
|
|
<p>This special variable expands the fully qualified C++ class into the
|
|
package name, if used by the <a href="#SWIGPlus_nspace"><tt>nspace</tt>
|
|
feature</a>, and the proxy class name, mangled for use as a function
|
|
name. For example, <tt>Namespace1::Namespace2::Klass</tt> is expanded
|
|
into <tt>Namespace1_Namespace2_Klass_</tt>.</p>
|
|
<p>This special variable might be useful for calling certain functions
|
|
in the wrapper layer (e.g. upcast wrappers) which are mangled like
|
|
this.</p>
|
|
</dd>
|
|
<dt><tt>$null</tt></dt>
|
|
<dd>
|
|
<p>In code inserted into the generated C/C++ wrapper functions, this
|
|
variable is replaced by either <tt>0</tt> or nothing at all, depending
|
|
on whether the function has a return value or not. It can be used to
|
|
bail out early e.g. in case of errors (<tt>return $null;</tt>).</p>
|
|
</dd>
|
|
<dt><a name="D_dinput"></a><tt>$dinput</tt> (C#: <tt>$csinput</tt>)</dt>
|
|
<dd>
|
|
<p>This variable is used in <tt><a href="#D_din">din</a></tt> typemaps
|
|
and is replaced by the expression which is to be passed to C/C++.</p>
|
|
<p>For example, this input</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(din) SomeClass * "SomeClass.getCPointer($dinput)"
|
|
|
|
%inline %{
|
|
class SomeClass {};
|
|
void foo(SomeClass *arg);
|
|
%}</pre>
|
|
</div>
|
|
<p>leads to the following D proxy code being generated:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
void foo(SomeClass arg) {
|
|
example_im.foo(SomeClass.getCPointer(arg));
|
|
}</pre>
|
|
</div></dd>
|
|
<dt><a name="D_imcall"></a><tt>$imcall</tt> and <tt>$owner</tt> (C#: <tt>
|
|
$imcall</tt>)</dt>
|
|
<dd>
|
|
<p>These variables are used in <tt><a href="#D_dout">dout</a></tt>
|
|
typemaps. <tt>$imcall</tt> contains the call to the intermediary module
|
|
which provides the value to be used, and <tt>$owner</tt> signals if the
|
|
caller is responsible for managing the object lifetime (that is, if the
|
|
called method is a constructor or has been marked via <tt>%newobject</tt>
|
|
).</p>
|
|
<p>Consider the following example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(dout) SomeClass * {
|
|
return new SomeClass($imcall, $owner);
|
|
}
|
|
|
|
%inline %{
|
|
class SomeClass;
|
|
SomeClass *foo();
|
|
|
|
%newobject bar();
|
|
SomeClass *bar();
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like
|
|
this:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
SomeClass foo() {
|
|
return new SomeClass(example_im.foo(), false);
|
|
}
|
|
|
|
SomeClass bar() {
|
|
return new SomeClass(example_im.bar(), true);
|
|
}
|
|
</pre>
|
|
</div></dd>
|
|
<dt><tt>$dcall</tt> and <tt>$winput</tt> (C#: <tt>$cscall</tt>, <tt>
|
|
$iminput</tt>)</dt>
|
|
<dd><a name="D_dpcall"></a>
|
|
<p>These variables are used in the director-specific typemaps <a href="#D_ddirectorinout">
|
|
<tt>ddirectorin</tt></a> and <a href="#D_ddirectorinout"><tt>
|
|
ddirectorout</tt></a>. They are more or less the reverse of the <tt>
|
|
$imcall</tt> and <tt>$dinput</tt> macros: <tt>$dcall</tt> contains the
|
|
invocation of the D proxy method of which the return value is to be
|
|
passed back to C++, <tt>$winput</tt> contains the parameter value from
|
|
C++.</p>
|
|
</dd>
|
|
<dt><tt>$excode</tt></dt>
|
|
<dd>
|
|
<p>This variable is used in <tt>dout</tt> and <tt>dconstructor</tt>
|
|
typemaps and is filled with the contents of the <tt>excode</tt> typemap
|
|
attribute if an exception could be thrown from the C++ side. See the <a href="#CSharp_exceptions">
|
|
C# documentation</a> for details.</p>
|
|
</dd>
|
|
<dt><tt>$dbaseclass</tt></dt>
|
|
<dd>
|
|
<p>Currently for internal use only, it contains the D name of the C++
|
|
base class (if any) inside proxy classes.</p>
|
|
</dd>
|
|
<dt><tt>$directorconnect</tt></dt>
|
|
<dd>
|
|
<p>This macro is only valid inside the <tt><a href="#D_class_code_typemaps">
|
|
dconstructor</a></tt> typemap and contains the value of the <tt>
|
|
dconstructor</tt> typemap attribute if the currently wrapped class has
|
|
directors enabled.</p>
|
|
<p>This is how the default <tt>dconstructor</tt> typemap looks like (you
|
|
usually do not want to specify a custom one):</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(dconstructor, excode=SWIGEXCODE,
|
|
directorconnect="\n swigDirectorConnect();") SWIGTYPE {
|
|
this($imcall, true);$excode$directorconnect
|
|
}
|
|
</pre>
|
|
</div></dd>
|
|
<dt><tt>$imfuncname</tt></dt>
|
|
<dd>
|
|
<p> This special variable expands to the name of the function in the
|
|
intermediary class that will be used in $imcall. Like, $imcall, this
|
|
special variable is only expanded in the "dout" typemap.</p>
|
|
</dd>
|
|
<dt><a name="D_importtype"></a><tt>$importtype(SomeDType)</tt></dt>
|
|
<dd>
|
|
<p>This macro is used in the <tt>dimports</tt> typemap if a dependency
|
|
on another D type generated by SWIG is added by a custom typemap.</p>
|
|
<p>Consider the following code snippet:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface"
|
|
</pre>
|
|
</div>
|
|
<p>This causes SWIG to add <tt>AnInterface</tt> and <tt>AnotherInterface</tt>
|
|
to the base class list of <tt>SomeClass</tt>:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class SomeClass : AnInterface, AnotherInterface {
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt>
|
|
have to be in scope. If SWIG is not in split proxy mode, this is
|
|
already the case, but if it is, they have to be added to the import
|
|
list via the <tt>dimports</tt> typemap. Additionally, the import
|
|
statement depends on the package SWIG is configured to emit the modules
|
|
to.</p>
|
|
<p>The <tt>$importtype</tt> macro helps you to elegantly solve this
|
|
problem:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(dimports) RemoteMpe %{
|
|
$importtype(AnInterface)
|
|
$importtype(AnotherInterface)
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p>If SWIG is in split proxy mode, it expands to an <tt>import</tt>
|
|
statement for the specified type, to nothing if not.</p>
|
|
</dd>
|
|
<dt><tt>$module</tt></dt>
|
|
<dd>
|
|
<p>Expands to the name of the main proxy D module.</p>
|
|
</dd>
|
|
<dt><tt>$imdmodule</tt></dt>
|
|
<dd>
|
|
<p>Contains the fully qualified name of the intermediary D module.</p>
|
|
</dd>
|
|
</dl>
|
|
<h2><a name="D_other_code_control">24.4 Other D code control features</a>
|
|
</h2>
|
|
<h3><a name="D_module">24.4.1 D begin</a></h3>
|
|
<p> It is possible to add a common comment at the start of every
|
|
generated D file. The <tt>%module</tt> directive supports the <tt>
|
|
dbegin</tt> option for this. The provided text is generated at the very
|
|
beginning of each generated D file. As it is generated before the D
|
|
module statement, is only really useful for adding in a common comment
|
|
into all generated D files. For example, copyright text for each file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(dbegin="/* Common comment. Copyright (C) 2000 Mr Nobody. */\n") nobodymodule
|
|
</pre>
|
|
</div>
|
|
<h3><a name="D_features">24.4.2 D and %feature</a></h3>
|
|
<p>The D module defines a number of directives which modify the <a href="#Customization_features">
|
|
SWIG features</a> set globally or for a specific declaration:</p>
|
|
<dl>
|
|
<dt><tt>%dmanifestconst</tt> and <tt>%dconstvalue(value)</tt></dt>
|
|
<dd>
|
|
<p>Out of the box, SWIG generates accessor methods for C <tt>#defines</tt>
|
|
and C++ constants. The <tt>%dmanifestconst</tt> directive enables
|
|
wrapping these constants as D manifest constants (<tt>enum</tt> in D2).</p>
|
|
<p>For this to work, the C/C++ code for the constant value must directly
|
|
compile as D code, though. If this is not the case, you can manually
|
|
override the expression written to the D proxy module using the <tt>
|
|
%dconstvalue</tt> directive, passing the new value as parameter.</p>
|
|
<p>For <tt>enum</tt>s, again <tt>%dconstvalue</tt> can be used to
|
|
override the value of an enum item if the initializer should not
|
|
compile in D.</p>
|
|
</dd>
|
|
<dt><tt>%dmethodmodifiers</tt></dt>
|
|
<dd>
|
|
<p>This directive can be used to override the modifiers for a proxy
|
|
function. For instance, you could make a <tt>public</tt> C++ member
|
|
function <tt>private</tt> in D like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%dmethodmodifiers A::foo "private";
|
|
|
|
%inline %{
|
|
struct A {
|
|
void foo();
|
|
};
|
|
%}
|
|
</pre>
|
|
</div></dd>
|
|
</dl>
|
|
<h2><a name="D_pragmas">24.5 Pragmas</a></h2>
|
|
<p>There are a few SWIG pragmas specific to the D module, which you can
|
|
use to influence the D code SWIG generates:</p>
|
|
<dl>
|
|
<dt><tt>%pragma(d) imdmodulecode</tt></dt>
|
|
<dd>
|
|
<p>The passed text (D code) is copied verbatim to the intermediary D
|
|
module. For example, it can be (and is, internally) used to emit
|
|
additional private helper code for the use by proxy typemaps.</p>
|
|
</dd>
|
|
<dt><tt>%pragma(d) imdmoduleimports</tt></dt>
|
|
<dd>
|
|
<p>Additional code to be emitted to the imports section of the
|
|
intermediary D module (the <a href="#D_importtype">$importtype</a>
|
|
macro can be used here). You probably want to use this in conjunction
|
|
with the <tt>imdmodulecode</tt> pragma.</p>
|
|
</dd>
|
|
<dt><tt>%pragma(d) proxydmodulecode</tt></dt>
|
|
<dd>
|
|
<p>Just like <tt>proxydmodulecode</tt>, the argument is copied to the
|
|
proxy D module (if SWIG is in <a href="#D_splitproxy">split proxy mode</a>
|
|
and/or the <tt>nspace</tt> feature is used, it is emitted to the main
|
|
proxy D module only).</p>
|
|
</dd>
|
|
<dt><tt>%pragma(d) globalproxyimports</tt></dt>
|
|
<dd>
|
|
<p>The D module currently does not support specifying dependencies on
|
|
external modules (e.g. from the standard library) for the D typemaps.
|
|
To add the import statements to the proxy modules (resp. to<em> all</em>
|
|
proxy modules if in split proxy mode), you can use the <tt>
|
|
globalproxyimports</tt> directive.</p>
|
|
<p>For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(din) char[] "($dinput ? tango.stdc.stringz.toStringz($dinput) : null)"
|
|
%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
|
|
</pre>
|
|
</div></dd>
|
|
<dt><tt>%pragma(d) wrapperloadercode</tt></dt>
|
|
<dd>
|
|
<p>The D code for loading the wrapper library (it is copied to the
|
|
intermediary D module). The <tt>$wrapperloaderbindcode</tt> variable is
|
|
replaced by the list of commands for binding the functions from the
|
|
wrapper library to the symbols in the intermediary D module.</p>
|
|
<p>Each time this pragma is specified, the previous value is
|
|
overwritten.</p>
|
|
</dd>
|
|
<dt><tt>%pragma(d) wrapperloaderbindcommand</tt></dt>
|
|
<dd>
|
|
<p>The D command to use for binding the wrapper functions from the C/C++
|
|
library to the symbols in the intermediary D module. The <tt>$function</tt>
|
|
variable contains the name of the D function in the wrap module, the <tt>
|
|
$symbol</tt> variable is replaced by the name of the symbol in the
|
|
library.</p>
|
|
<p>Each time this pragma is specified, the previous value is
|
|
overwritten.</p>
|
|
</dd>
|
|
</dl>
|
|
<h2><a name="D_exceptions">24.6 D Exceptions</a></h2>
|
|
<p>Out of the box, C++ exceptions are fundamentally incompatible to
|
|
their equivalent in the D world and cannot simply be propagated to a
|
|
calling D method. There is, however, an easy way to solve this problem:
|
|
Just catch the exception in the C/C++ wrapper layer, pass the contents
|
|
to D, and make the wrapper code rethrow the exception in the D world.</p>
|
|
<p>The implementation details of this are a bit crude, but the SWIG D
|
|
module automatically takes care of this, as long as it is able to
|
|
detect that an exception could potentially be thrown (e.g. because the
|
|
C++ method has a <tt>throw(...)</tt> exception specification).</p>
|
|
<p>As this feature is implemented in exactly the same way it is for C#,
|
|
please see the <a href="#CSharp_exceptions">C# documentation</a> for a
|
|
more detailed explanation.</p>
|
|
<h2><a name="D_directors">24.7 D Directors</a></h2>
|
|
<p>When the directors feature is activated, SWIG generates extra code on
|
|
both the C++ and the D side to enable cross-language polymorphism.
|
|
Essentially, this means that if you subclass a proxy class in D, C++
|
|
code can access any overridden virtual methods just as if you created a
|
|
derived class in C++.</p>
|
|
<p>There is no D specific documentation yet, but the way the feature is
|
|
implemented is very similar to how it is done in <a href="#Java_directors">
|
|
Java</a> and <a href="#CSharp_directors">C#</a>.</p>
|
|
<h2><a name="D_other_features">24.8 Other features</a></h2>
|
|
<h3><a name="D_nspace">24.8.1 Extended namespace support (nspace)</a></h3>
|
|
<p>By default, SWIG flattens all C++ namespaces into a flattened D
|
|
module hierarchy, but as for Java and C#, the <a href="#SWIGPlus_nspace">
|
|
<tt>nspace</tt></a> feature is supported for D. If the feature is
|
|
active, C++ namespaces are mapped to D packages/modules. This includes
|
|
the <tt>nspace</tt> feature flag for mirroring the C++ namespaces into
|
|
D namespaces as a scoped D module/package name. It also includes <tt>
|
|
%nspacemove</tt> for transforming a C++ namespace into a completely
|
|
different scoped D module/package name. Note, however, that like for
|
|
the other languages,<em> free</em> variables and functions are not
|
|
supported yet; currently, they are all available in the main proxy D
|
|
module.</p>
|
|
<h3><a name="D_native_pointer_support">24.8.2 Native pointer support</a></h3>
|
|
<p>Contrary to many of the scripting languages supported by SWIG, D
|
|
fully supports C-style pointers. The D module thus includes a custom
|
|
mechanism to wrap C pointers directly as D pointers where applicable,
|
|
that is, if the type that is pointed to is represented the same in C
|
|
and D (on the bit-level), dubbed a<em> primitive type</em> below.</p>
|
|
<p>Central to this custom pointer handling scheme are two typemap
|
|
attributes: the <tt>cprimitive</tt> attribute on the <tt>dtype</tt>
|
|
typemap and the <tt>nativepointer</tt> attribute on all the typemaps
|
|
which influence the D side of the code (<tt>dtype</tt>, <tt>din</tt>, <tt>
|
|
dout</tt>, ...). When a D typemap is looked up, the following happens
|
|
behind the scenes:</p>
|
|
<p>First, the matching typemap is determined by the usual typemap lookup
|
|
rules. Then, it is checked if the result has the <tt>nativepointer</tt>
|
|
attribute set. If it is present, it means that its value should replace
|
|
the typemap value<em> if and only if</em> the actual type the typemap
|
|
is looked up for is a primitive type, a pointer to a primitive type
|
|
(through an arbitrary level of indirections), or a function pointer
|
|
with only primitive types in its signature.</p>
|
|
<p>To determine if a type should be considered primitive, the <tt>
|
|
cprimitive</tt> attribute on its <tt>dtype</tt> attribute is used. For
|
|
example, the <tt>dtype</tt> typemap for <tt>float</tt> has <tt>
|
|
cprimitive="1"</tt>, so the code from the <tt>nativepointer</tt>
|
|
attribute is taken into account e.g. for <tt>float **</tt> or the
|
|
function pointer <tt>float (*)(float *)</tt>.</p>
|
|
<h3><a name="D_operator_overloading">24.8.3 Operator overloading</a></h3>
|
|
<p>The D module comes with basic operator overloading support. There
|
|
are, however, a few limitations arising from conceptual differences
|
|
between C++ and D:</p>
|
|
<p>The first key difference is that C++ supports free functions as
|
|
operators (along with argument-dependent lookup), while D requires
|
|
operators to be member functions of the class they are operating on.
|
|
SWIG can only automatically generate wrapping code for member function
|
|
operators; if you want to use operators defined as free functions in D,
|
|
you need to handle them manually.</p>
|
|
<p>Another set of differences between C++ and D concerns individual
|
|
operators. For example, there are quite a few operators which are
|
|
overloadable in C++, but not in D, for example <tt>&&</tt> and <tt>||</tt>
|
|
, but also <tt>!</tt>, and postfix increment/decrement operators (see
|
|
the <a href="https://www.digitalmars.com/d/2.0/operatoroverloading.html">
|
|
D documentation</a> for details).</p>
|
|
<p>There are also some cases where the operators can be translated to D,
|
|
but the differences in the implementation details are big enough that a
|
|
rather involved scheme would be required for automatic wrapping them,
|
|
which has not been implemented yet. This affects, for example, the
|
|
array subscript operator, <tt>[]</tt>, in combination with assignments
|
|
- while <tt>operator []</tt> in C++ simply returns a reference which is
|
|
then written to, D resorts to a separate <tt>opIndexAssign</tt> method
|
|
-, or implicit casting (which was introduced in D2 via <tt>alias this</tt>
|
|
). Despite the lack of automatic support, manually handling these cases
|
|
should be perfectly possible.</p>
|
|
<h3><a name="D_test_suite">24.8.4 Running the test-suite</a></h3>
|
|
<p>As with any other language, the SWIG test-suite can be built for D
|
|
using the <tt>*-d-test-suite</tt> targets of the top-level Makefile.</p>
|
|
<p>Note: If you want to use GDC on Linux or another platform which
|
|
requires you to link <tt>libdl</tt> for dynamically loading the shared
|
|
library, you might have to add <tt>-ldl</tt> manually to the <tt>
|
|
d_compile</tt> target in <tt>Examples/Makefile</tt>, because GDC does
|
|
not currently honor the <tt>pragma(lib, ...)</tt> statement.</p>
|
|
<h2><a name="D_typemap_examples">24.9 D Typemap examples</a></h2>
|
|
<p>There are no D-specific typemap examples yet. However, with the above
|
|
<a href="#D_typemap_name_comparison">name comparison table</a>, you
|
|
should be able to get an idea what can be done by looking at the <a href="#CSharp_typemap_examples">
|
|
corresponding C# section</a>.</p>
|
|
<h2><a name="D_planned_features">24.10 Work in progress and planned
|
|
features</a></h2>
|
|
<p>There are a couple of features which are not implemented yet, but
|
|
would be very useful and might be added in the near future:</p>
|
|
<ul>
|
|
<li><em>Static linking:</em> Currently, the C wrapper code is compiled
|
|
into a dynamic library, out of which the symbol addresses are looked up
|
|
at runtime by the D part. If statically linking the different languages
|
|
into one binary was supported, a tool-chain capable of performing IPO
|
|
at link time could inline the wrapping code, effectively reducing the
|
|
overhead for simple calls to zero.</li>
|
|
<li><em>C array handling:</em> Many data structures in some C/C++
|
|
libraries contain array containing of a pointer to the first element
|
|
and the element count. Currently, one must manually writing wrapper
|
|
code to be able to access these from D. It should be possible to add a
|
|
set of SWIG macros to semi-automatically generate conversion code.</li>
|
|
</ul>
|
|
<p>Some generated code might also be a bit rough around the edges,
|
|
particularly in the following areas:</p>
|
|
<ul>
|
|
<li><em>Memory management:</em> Although the currently generated wrapper
|
|
code works fine with regard to the GC for the test-suite, there might
|
|
be issues coming up in real-world multi-threaded usage.</li>
|
|
<li><em>D2 support</em>: Originally, the module has been developed for
|
|
the use with D1, D2/Phobos support has been added in later. The basic
|
|
features should work equally well for both, but there<em> could</em> be
|
|
issues concerning const-correctness etc.</li>
|
|
</ul>
|
|
<HR NOSHADE>
|
|
<h1><a name="Go">25 SWIG and Go</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Go_overview">Overview</a></li>
|
|
<li><a href="#Go_examples">Examples</a></li>
|
|
<li><a href="#Go_running_swig">Running SWIG with Go</a>
|
|
<ul>
|
|
<li><a href="#Go_commandline">Go-specific Commandline Options</a></li>
|
|
<li><a href="#Go_outputs">Generated Wrapper Files</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Go_basic_tour">A tour of basic C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a href="#Go_package">Go Package Name</a></li>
|
|
<li><a href="#Go_names">Go Names</a></li>
|
|
<li><a href="#Go_constants">Go Constants</a></li>
|
|
<li><a href="#Go_enumerations">Go Enumerations</a></li>
|
|
<li><a href="#Go_classes">Go Classes</a>
|
|
<ul>
|
|
<li><a href="#Go_class_memory">Go Class Memory Management</a></li>
|
|
<li><a href="#Go_class_inheritance">Go Class Inheritance</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Go_templates">Go Templates</a></li>
|
|
<li><a href="#Go_threads">Go and C/C++ Threads</a></li>
|
|
<li><a href="#Go_exceptions">Go and C++ Exceptions</a></li>
|
|
<li><a href="#Go_director_classes">Go Director Classes</a>
|
|
<ul>
|
|
<li><a href="#Go_director_example_cpp_code">Example C++ code</a></li>
|
|
<li><a href="#Go_director_enable">Enable director feature</a></li>
|
|
<li><a href="#Go_director_ctor_dtor">Constructor and destructor</a></li>
|
|
<li><a href="#Go_director_overriding">Override virtual methods</a></li>
|
|
<li><a href="#Go_director_base_methods">Call base methods</a></li>
|
|
<li><a href="#Go_director_subclass">Subclass via embedding</a></li>
|
|
<li><a href="#Go_director_finalizer">Memory management with
|
|
runtime.SetFinalizer</a></li>
|
|
<li><a href="#Go_director_foobargo_class">Complete FooBarGo example
|
|
class</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Go_primitive_type_mappings">Default Go primitive type
|
|
mappings</a></li>
|
|
<li><a href="#Go_output_arguments">Output arguments</a></li>
|
|
<li><a href="#Go_adding_additional_code">Adding additional go code</a></li>
|
|
<li><a href="#Go_typemaps">Go typemaps</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> This chapter describes SWIG's support of Go. For more information on
|
|
the Go programming language see <a href="https://golang.org/">
|
|
golang.org</a>.</p>
|
|
<h2><a name="Go_overview">25.1 Overview</a></h2>
|
|
<p> Go does not support direct calling of functions written in C/C++.
|
|
The <a href="https://golang.org/cmd/cgo/">cgo program</a> may be used
|
|
to generate wrappers to call C code from Go, but there is no convenient
|
|
way to call C++ code. SWIG fills this gap.</p>
|
|
<p> There are (at least) two different Go compilers. The first is the gc
|
|
compiler of the <a href="https://golang.org/doc/install">Go
|
|
distribution</a>, normally invoked via the <a href="https://golang.org/cmd/go/">
|
|
go tool</a>. SWIG supports the gc compiler version 1.2 or later. The
|
|
second Go compiler is the <a href="https://golang.org/doc/install/gccgo">
|
|
gccgo compiler</a>, which is a frontend to the GCC compiler suite. The
|
|
interface to C/C++ code is completely different for the two Go
|
|
compilers. SWIG supports both Go compilers, selected by the <tt>-gccgo</tt>
|
|
command line option.</p>
|
|
<p> Go is a type-safe compiled language and the wrapper code generated
|
|
by SWIG is type-safe as well. In case of type issues the build will
|
|
fail and hence SWIG's <a href="#Modules_nn2">runtime library</a> and <a href="#Typemaps_runtime_type_checker">
|
|
runtime type checking</a> are not used.</p>
|
|
<h2><a name="Go_examples">25.2 Examples</a></h2>
|
|
<p> Working examples can be found in the <a href="https://github.com/swig/swig/tree/master/Examples/go">
|
|
SWIG source tree</a> .</p>
|
|
<p> Please note that the examples in the SWIG source tree use makefiles
|
|
with the .i SWIG interface file extension for backwards compatibility
|
|
with Go 1.</p>
|
|
<h2><a name="Go_running_swig">25.3 Running SWIG with Go</a></h2>
|
|
<p> Most Go programs are built using the <a href="https://golang.org/cmd/go/">
|
|
go tool</a>. Since Go 1.1 the go tool has support for SWIG. To use it,
|
|
give your SWIG interface file the extension .swig (for C code) or
|
|
.swigcxx (for C++ code). Put that file in a GOPATH/src directory as
|
|
usual for Go sources. Put other C/C++ code in the same directory with
|
|
extensions of .c and .cxx. The <tt>go build</tt> and <tt>go install</tt>
|
|
commands will automatically run SWIG for you and compile the generated
|
|
wrapper code. To check the SWIG command line options the go tool uses
|
|
run <tt>go build -x</tt>. To access the automatically generated files
|
|
run <tt>go build -work</tt>. You'll find the files under the temporary
|
|
WORK directory.</p>
|
|
<p> To manually generate and compile C/C++ wrapper code for Go, use the <tt>
|
|
-go</tt> option with SWIG. By default SWIG will generate code for the Go
|
|
compiler of the Go distribution. To generate code for gccgo, you should
|
|
also use the <tt>-gccgo</tt> option.</p>
|
|
<p> By default SWIG will generate files that can be used directly by <tt>
|
|
go build</tt>. This requires Go 1.2 or later. Put your SWIG interface
|
|
file in a directory under GOPATH/src, and give it a name that does<b>
|
|
not</b> end in the .swig or .swigcxx extension. Typically the SWIG
|
|
interface file extension is .i in this case.</p>
|
|
<div class="code">
|
|
<pre>
|
|
% swig -go example.i
|
|
% go install
|
|
</pre>
|
|
</div>
|
|
<p> You will now have a Go package that you can import from other Go
|
|
packages as usual.</p>
|
|
<h3><a name="Go_commandline">25.3.1 Go-specific Commandline Options</a></h3>
|
|
<p> These are the command line options for SWIG's Go module. They can
|
|
also be seen by using:</p>
|
|
<div class="code">
|
|
<pre>
|
|
swig -go -help
|
|
</pre>
|
|
</div>
|
|
<table summary="Go-specific options">
|
|
<tr><th>Go-specific options</th></tr>
|
|
<tr><td>-cgo</td><td>Generate files to be used as input for the Go cgo
|
|
tool. This is the default.</td></tr>
|
|
<tr><td>-no-cgo</td><td>This option is no longer supported.</td></tr>
|
|
<tr><td>-intgosize <s></td><td>Set the size for the Go type <tt>int</tt>
|
|
. This controls the size that the C/C++ code expects to see. The <s>
|
|
argument should be 32 or 64. This option was required during the
|
|
transition from Go 1.0 to Go 1.1, as the size of <tt>int</tt> on 64-bit
|
|
x86 systems changed between those releases (from 32 bits to 64 bits).
|
|
It was made optional in SWIG 4.1.0 and if not specified SWIG will
|
|
assume that the size of <tt>int</tt> is the size of a C pointer.</td></tr>
|
|
<tr><td>-gccgo</td><td>Generate code for gccgo. The default is to
|
|
generate code for the Go compiler of the Go distribution.</td></tr>
|
|
<tr><td>-package <name></td><td>Set the name of the Go package to
|
|
<name>. The default package name is the SWIG module name.</td></tr>
|
|
<tr><td>-use-shlib</td><td>Tell SWIG to emit code that uses a shared
|
|
library. This is only meaningful for the Go compiler of the Go
|
|
distribution, which needs to know at compile time whether a shared
|
|
library will be used.</td></tr>
|
|
<tr><td>-soname <name></td><td>Set the runtime name of the shared
|
|
library that the dynamic linker should include at runtime. The default
|
|
is the package name with ".so" appended. This is only used when
|
|
generating code for the Go compiler of the Go distribution; when using
|
|
gccgo, the equivalent name will be taken from the <code>-soname</code>
|
|
option passed to the linker. Using this option implies the -use-shlib
|
|
option.</td></tr>
|
|
<tr><td>-go-pkgpath <pkgpath></td><td>When generating code for gccgo,
|
|
set the pkgpath to use. This corresponds to the <tt>-fgo-pkgpath</tt>
|
|
option to gccgo.</td></tr>
|
|
<tr><td>-go-prefix <prefix></td><td>When generating code for gccgo, set
|
|
the prefix to use. This corresponds to the <tt>-fgo-prefix</tt> option
|
|
to gccgo. If <tt>-go-pkgpath</tt> is used, <tt>-go-prefix</tt> will be
|
|
ignored.</td></tr>
|
|
<tr><td>-import-prefix <prefix></td><td>A prefix to add when turning a
|
|
%import prefix in the SWIG interface file into an import statement in
|
|
the Go file. For example, with <code>-import-prefix mymodule</code>, a
|
|
SWIG interface file <code>%import mypackage</code> will become a Go
|
|
import statement <code>import "mymodule/mypackage"</code>.</td></tr>
|
|
</table>
|
|
<h3><a name="Go_outputs">25.3.2 Generated Wrapper Files</a></h3>
|
|
<p> SWIG will generate the following files when generating wrapper code:</p>
|
|
<ul>
|
|
<li> MODULE.go will contain the Go functions that your Go code will
|
|
call. These functions will be wrappers for the C++ functions defined by
|
|
your module. This file should, of course, be compiled with the Go
|
|
compiler.</li>
|
|
<li> MODULE_wrap.c or MODULE_wrap.cxx will contain C/C++ functions will
|
|
be invoked by the Go wrapper code. This file should be compiled with
|
|
the usual C or C++ compiler.</li>
|
|
<li> MODULE_wrap.h will be generated if you use the directors feature.
|
|
It provides a definition of the generated C++ director classes. It is
|
|
generally not necessary to use this file, but in some special cases it
|
|
may be helpful to include it in your code, compiled with the usual C or
|
|
C++ compiler.</li>
|
|
</ul>
|
|
<h2><a name="Go_basic_tour">25.4 A tour of basic C/C++ wrapping</a></h2>
|
|
<p> By default, SWIG attempts to build a natural Go interface to your
|
|
C/C++ code. However, the languages are somewhat different, so some
|
|
modifications have to occur. This section briefly covers the essential
|
|
aspects of this wrapping.</p>
|
|
<h3><a name="Go_package">25.4.1 Go Package Name</a></h3>
|
|
<p> All Go source code lives in a package. The name of this package will
|
|
default to the name of the module from SWIG's <tt>%module</tt>
|
|
directive. You may override this by using SWIG's <tt>-package</tt>
|
|
command line option.</p>
|
|
<h3><a name="Go_names">25.4.2 Go Names</a></h3>
|
|
<p> In Go, a function is only visible outside the current package if the
|
|
first letter of the name is uppercase. This is quite different from
|
|
C/C++. Because of this, C/C++ names are modified when generating the Go
|
|
interface: the first letter is forced to be uppercase if it is not
|
|
already. This affects the names of functions, methods, variables,
|
|
constants, enums, and classes.</p>
|
|
<p> C/C++ variables are wrapped with setter and getter functions in Go.
|
|
First the first letter of the variable name will be forced to
|
|
uppercase, and then <tt>Get</tt> or <tt>Set</tt> will be prepended. For
|
|
example, if the C/C++ variable is called <tt>var</tt>, then SWIG will
|
|
define the functions <tt>GetVar</tt> and <tt>SetVar</tt>. If a variable
|
|
is declared as <tt>const</tt>, or if SWIG's <a href="#SWIG_readonly_variables">
|
|
<tt>%immutable</tt> directive</a> is used for the variable, then only
|
|
the getter will be defined.</p>
|
|
<p> C++ classes will be discussed further below. Here we'll note that
|
|
the first letter of the class name will be forced to uppercase to give
|
|
the name of a type in Go. A constructor will be named <tt>New</tt>
|
|
followed by that name, and the destructor will be named <tt>Delete</tt>
|
|
followed by that name.</p>
|
|
<h3><a name="Go_constants">25.4.3 Go Constants</a></h3>
|
|
<p> C/C++ constants created via <tt>#define</tt> or the <tt>%constant</tt>
|
|
directive become Go constants, declared with a <tt>const</tt>
|
|
declaration.</p>
|
|
<h3><a name="Go_enumerations">25.4.4 Go Enumerations</a></h3>
|
|
<p> C/C++ enumeration types will cause SWIG to define an integer type
|
|
with the name of the enumeration (with first letter forced to uppercase
|
|
as usual). The values of the enumeration will become variables in Go;
|
|
code should avoid modifying those variables.</p>
|
|
<h3><a name="Go_classes">25.4.5 Go Classes</a></h3>
|
|
<p> Go has interfaces, methods and inheritance, but it does not have
|
|
classes in the same sense as C++. This sections describes how SWIG
|
|
represents C++ classes represented in Go.</p>
|
|
<p> For a C++ class <tt>ClassName</tt>, SWIG will define two types in
|
|
Go: an underlying type, which will just hold a pointer to the C++ type,
|
|
and an interface type. The interface type will be named <tt>ClassName</tt>
|
|
. SWIG will define a function <tt>NewClassName</tt> which will take any
|
|
constructor arguments and return a value of the interface type <tt>
|
|
ClassName</tt>. SWIG will also define a destructor <tt>DeleteClassName</tt>
|
|
.</p>
|
|
<p> SWIG will represent any methods of the C++ class as methods on the
|
|
underlying type, and also as methods of the interface type. Thus C++
|
|
methods may be invoked directly using the usual <tt>val.MethodName</tt>
|
|
syntax. Public members of the C++ class will be given getter and setter
|
|
functions defined as methods of the class.</p>
|
|
<p> SWIG will represent static methods of C++ classes as ordinary Go
|
|
functions. SWIG will use names like <tt>ClassNameMethodName</tt>. SWIG
|
|
will give static members getter and setter functions with names like <tt>
|
|
GetClassNameVarName</tt>.</p>
|
|
<p> Given a value of the interface type, Go code can retrieve the
|
|
pointer to the C++ type by calling the <tt>Swigcptr</tt> method. This
|
|
will return a value of type <tt>SwigcptrClassName</tt>, which is just a
|
|
name for <tt>uintptr</tt>. A Go type conversion can be used to convert
|
|
this value to a different C++ type, but note that this conversion will
|
|
not be type checked and is essentially equivalent to <tt>
|
|
reinterpret_cast</tt>. This should only be used for very special cases,
|
|
such as where C++ would use a <tt>dynamic_cast</tt>.</p>
|
|
<p>Note that C++ pointers to compound objects are represented in go as
|
|
objects themselves, not as go pointers. So, for example, if you wrap
|
|
the following function:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class MyClass {
|
|
int MyMethod();
|
|
static MyClass *MyFactoryFunction();
|
|
};
|
|
|
|
</pre>
|
|
</div>
|
|
<p>You will get go code that looks like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
type MyClass interface {
|
|
Swigcptr() uintptr
|
|
SwigIsMyClass()
|
|
MyMethod() int
|
|
}
|
|
|
|
func MyClassMyFactoryFunction() MyClass {
|
|
// swig magic here
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p>Note that the factory function does not return a go pointer; it
|
|
actually returns a go interface. If the returned pointer can be null,
|
|
you can check for this by calling the Swigcptr() method.</p>
|
|
<h4><a name="Go_class_memory">25.4.5.1 Go Class Memory Management</a></h4>
|
|
<p> Calling <tt>NewClassName</tt> for a C++ class <tt>ClassName</tt>
|
|
will allocate memory using the C++ memory allocator. This memory will
|
|
not be automatically freed by Go's garbage collector as the object
|
|
ownership is not tracked. When you are done with the C++ object you
|
|
must free it using <tt>DeleteClassName</tt>.
|
|
<br>
|
|
<br> The most Go idiomatic way to manage the memory for some C++ class
|
|
is to call <tt>NewClassName</tt> followed by a <tt><a href="https://golang.org/doc/effective_go.html#defer">
|
|
defer</a></tt> of the <tt>DeleteClassName</tt> call. Using <tt>defer</tt>
|
|
ensures that the memory of the C++ object is freed as soon as the
|
|
function containing the <tt>defer</tt> statement returns. Furthermore <tt>
|
|
defer</tt> works great for short-lived objects and fits nicely C++'s
|
|
RAII idiom. Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
func UseClassName(...) ... {
|
|
o := NewClassName(...)
|
|
defer DeleteClassName(o)
|
|
// Use the ClassName object
|
|
return ...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> With increasing complexity, especially complex C++ object
|
|
hierarchies, the correct placement of <tt>defer</tt> statements becomes
|
|
harder and harder as C++ objects need to be freed in the correct order.
|
|
This problem can be eased by keeping a C++ object function local so
|
|
that it is only available to the function that creates a C++ object and
|
|
functions called by this function. Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
func WithClassName(constructor args, f func(ClassName, ...interface{}) error, data ...interface{}) error {
|
|
o := NewClassName(constructor args)
|
|
defer DeleteClassName(o)
|
|
return f(o, data...)
|
|
}
|
|
|
|
func UseClassName(o ClassName, data ...interface{}) (err error) {
|
|
// Use the ClassName object and additional data and return error.
|
|
}
|
|
|
|
func main() {
|
|
WithClassName(constructor args, UseClassName, additional data)
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Using <tt>defer</tt> has limitations though, especially when it
|
|
comes to long-lived C++ objects whose lifetimes are hard to predict.
|
|
For such C++ objects a common technique is to store the C++ object into
|
|
a Go object, and to use the Go function <tt>runtime.SetFinalizer</tt>
|
|
to add a finalizer which frees the C++ object when the Go object is
|
|
freed. It is strongly recommended to read the <a href="https://golang.org/pkg/runtime/#SetFinalizer">
|
|
runtime.SetFinalizer</a> documentation before using this technique to
|
|
understand the <tt>runtime.SetFinalizer</tt> limitations.
|
|
<br></p>
|
|
<p> Common pitfalls with <tt>runtime.SetFinalizer</tt> are:</p>
|
|
<ul>
|
|
<li> If a hierarchy of C++ objects will be automatically freed by Go
|
|
finalizers then the Go objects that store the C++ objects need to
|
|
replicate the hierarchy of the C++ objects to prevent that C++ objects
|
|
are freed prematurely while other C++ objects still rely on them.</li>
|
|
<li> The usage of Go finalizers is problematic with C++'s RAII idiom as
|
|
it isn't predictable when the finalizer will run and this might require
|
|
a Close or Delete method to be added the Go object that stores a C++
|
|
object to mitigate.</li>
|
|
</ul>
|
|
<p> <tt>runtime.SetFinalizer</tt> Example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
import (
|
|
"runtime"
|
|
"wrap" // SWIG generated wrapper code
|
|
)
|
|
|
|
type GoClassName struct {
|
|
wcn wrap.ClassName
|
|
}
|
|
|
|
func NewGoClassName() *GoClassName {
|
|
o := &GoClassName{wcn: wrap.NewClassName()}
|
|
runtime.SetFinalizer(o, deleteGoClassName)
|
|
return o
|
|
}
|
|
|
|
func deleteGoClassName(o *GoClassName) {
|
|
// Runs typically in a different OS thread!
|
|
wrap.DeleteClassName(o.wcn)
|
|
o.wcn = nil
|
|
}
|
|
|
|
func (o *GoClassName) Close() {
|
|
// If the C++ object has a Close method.
|
|
o.wcn.Close()
|
|
|
|
// If the GoClassName object is no longer in an usable state.
|
|
runtime.SetFinalizer(o, nil) // Remove finalizer.
|
|
deleteGoClassName() // Free the C++ object.
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Go_class_inheritance">25.4.5.2 Go Class Inheritance</a></h4>
|
|
<p> C++ class inheritance is automatically represented in Go due to its
|
|
use of interfaces. The interface for a child class will be a superset
|
|
of the interface of its parent class. Thus a value of the child class
|
|
type in Go may be passed to a function which expects the parent class.
|
|
Doing the reverse will require an explicit type assertion, which will
|
|
be checked dynamically.</p>
|
|
<h3><a name="Go_templates">25.4.6 Go Templates</a></h3>
|
|
<p> In order to use C++ templates in Go, you must tell SWIG to create
|
|
wrappers for a particular template instantiation. To do this, use the <tt>
|
|
%template</tt> directive.</p>
|
|
<h3><a name="Go_threads">25.4.7 Go and C/C++ Threads</a></h3>
|
|
<p> C and C++ code can use operating system threads and thread local
|
|
storage. Go code uses goroutines, which are multiplexed onto operating
|
|
system threads. This multiplexing means that Go code can change to run
|
|
on a different thread at any time. C/C++ code, on the other hand, may
|
|
assume that it runs on a single thread; this is true in particular if
|
|
the C/C++ code uses thread local storage.</p>
|
|
<p> In order to use Go code with C/C++ code that expects to run on a
|
|
single thread, the Go code must call the <a href="https://pkg.go.dev/runtime#LockOSThread">
|
|
<code>runtime.LockOSThread</code></a> function to lock the goroutine
|
|
onto a single thread.</p>
|
|
<h3><a name="Go_exceptions">25.4.8 Go and C++ Exceptions</a></h3>
|
|
<p> C++ exceptions do not interoperate with Go code. Attempts to throw
|
|
C++ exceptions through a Go caller are unreliable: in many cases the
|
|
C++ exception handler will be unable to unwind the stack, and the
|
|
program will crash. The only safe way to handle C++ exceptions is to
|
|
catch them in C++ before returning to Go.</p>
|
|
<h3><a name="Go_director_classes">25.4.9 Go Director Classes</a></h3>
|
|
<p> SWIG's director feature permits a Go type to act as the subclass of
|
|
a C++ class. This is complicated by the fact that C++ and Go define
|
|
inheritance differently. SWIG normally represents the C++ class
|
|
inheritance automatically in Go via interfaces but with a Go type
|
|
representing a subclass of a C++ class some manual work is necessary.</p>
|
|
<p> This subchapter gives a step by step guide how to properly subclass
|
|
a C++ class with a Go type. In general it is strongly recommended to
|
|
follow this guide completely to avoid common pitfalls with directors in
|
|
Go.</p>
|
|
<h4><a name="Go_director_example_cpp_code">25.4.9.1 Example C++ code</a></h4>
|
|
<p> The step by step guide is based on two example C++ classes.
|
|
FooBarAbstract is an abstract C++ class and the FooBarCpp class
|
|
inherits from it. This guide explains how to implement a FooBarGo class
|
|
similar to the FooBarCpp class.</p>
|
|
<p> <tt>FooBarAbstract</tt> abstract C++ class:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class FooBarAbstract
|
|
{
|
|
public:
|
|
FooBarAbstract() {};
|
|
virtual ~FooBarAbstract() {};
|
|
|
|
std::string FooBar() {
|
|
return this->Foo() + ", " + this->Bar();
|
|
};
|
|
|
|
protected:
|
|
virtual std::string Foo() {
|
|
return "Foo";
|
|
};
|
|
|
|
virtual std::string Bar() = 0;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> <tt>FooBarCpp</tt> C++ class:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class FooBarCpp : public FooBarAbstract
|
|
{
|
|
protected:
|
|
virtual std::string Foo() {
|
|
return "C++ " + FooBarAbstract::Foo();
|
|
}
|
|
|
|
virtual std::string Bar() {
|
|
return "C++ Bar";
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Returned string by the <tt>FooBarCpp::FooBar</tt> method is:</p>
|
|
<div class="code">
|
|
<pre>
|
|
C++ Foo, C++ Bar
|
|
</pre>
|
|
</div>
|
|
<p> The complete example, including the <tt>FooBarGoo</tt> class
|
|
implementation, can be found in <a href="#Go_director_foobargo_class">
|
|
the end of the guide</a>.</p>
|
|
<h4><a name="Go_director_enable">25.4.9.2 Enable director feature</a></h4>
|
|
<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> Second, you must use the %feature("director") directive to tell SWIG
|
|
which classes should get directors. In the example the FooBarAbstract
|
|
class needs the director feature enabled so that the FooBarGo class can
|
|
inherit from it, like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director") FooBarAbstract;
|
|
</pre>
|
|
</div>
|
|
<p> For a more detailed documentation of the director feature and how to
|
|
enable or disable it for specific classes and virtual methods see
|
|
SWIG's Java documentation on directors.</p>
|
|
<h4><a name="Go_director_ctor_dtor">25.4.9.3 Constructor and destructor</a>
|
|
</h4>
|
|
<p> SWIG creates an additional set of constructor and destructor
|
|
functions once the director feature has been enabled for a C++ class. <tt>
|
|
NewDirectorClassName</tt> allows overriding virtual methods on the new
|
|
object instance and <tt>DeleteDirectorClassName</tt> needs to be used
|
|
to free a director object instance created with <tt>
|
|
NewDirectorClassName</tt>. More on overriding virtual methods follows
|
|
later in this guide under <a href="#Go_director_overriding">overriding
|
|
virtual methods</a>.</p>
|
|
<p> The default constructor and destructor functions <tt>NewClassName</tt>
|
|
and <tt>DeleteClassName</tt> can still be used as before so that
|
|
existing code doesn't break just because the director feature has been
|
|
enabled for a C++ class. The behavior is undefined if the default and
|
|
director constructor and destructor functions get mixed and so great
|
|
care needs to be taken that only one of the constructor and destructor
|
|
function pairs is used for any object instance. Both constructor
|
|
functions, the default and the director one, return the same interface
|
|
type. This makes it potentially hard to know which destructor function,
|
|
the default or the director one, needs to be called to delete an object
|
|
instance.</p>
|
|
<p> In<b> theory</b> the <tt>DirectorInterface</tt> method could be used
|
|
to determine if an object instance was created via <tt>
|
|
NewDirectorClassName</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
if o.DirectorInterface() != nil {
|
|
DeleteDirectorClassName(o)
|
|
} else {
|
|
DeleteClassName(o)
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> In<b> practice</b> it is strongly recommended to embed a director
|
|
object instance in a Go struct so that a director object instance will
|
|
be represented as a distinct Go type that subclasses a C++ class. For
|
|
this Go type custom constructor and destructor functions take care of
|
|
the director constructor and destructor function calls and the
|
|
resulting Go class will appear to the user as any other SWIG wrapped
|
|
C++ class. More on properly subclassing a C++ class follows later in
|
|
this guide under <a href="#Go_director_subclass">subclass via embedding</a>
|
|
.</p>
|
|
<h4><a name="Go_director_overriding">25.4.9.4 Override virtual methods</a>
|
|
</h4>
|
|
<p> In order to override virtual methods on a C++ class with Go methods
|
|
the <tt>NewDirectorClassName</tt> constructor functions receives a <tt>
|
|
DirectorInterface</tt> argument. The methods in the <tt>
|
|
DirectorInterface</tt> are a subset of the public and protected virtual
|
|
methods of the C++ class. Virtual methods that have a final specifier
|
|
are unsurprisingly excluded. If the <tt>DirectorInterface</tt> contains
|
|
a method with a matching signature to a virtual method of the C++ class
|
|
then the virtual C++ method will be overwritten with the Go method. As
|
|
Go doesn't support protected methods all overridden protected virtual
|
|
C++ methods will be public in Go.</p>
|
|
<p> As an example see part of the <tt>FooBarGo</tt> class:</p>
|
|
<div class="code">
|
|
<pre>
|
|
type overwrittenMethodsOnFooBarAbstract struct {
|
|
fb FooBarAbstract
|
|
}
|
|
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
|
...
|
|
}
|
|
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
|
|
...
|
|
}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om)
|
|
om.fb = fb
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The complete example, including the <tt>FooBarGoo</tt> class
|
|
implementation, can be found in <a href="#Go_director_foobargo_class">
|
|
the end of the guide</a>. In this part of the example the virtual
|
|
methods <tt>FooBarAbstract::Foo</tt> and <tt>FooBarAbstract::Bar</tt>
|
|
have been overwritten with Go methods similarly to how the <tt>
|
|
FooBarAbstract</tt> virtual methods are overwritten by the <tt>FooBarCpp</tt>
|
|
class.</p>
|
|
<p> The <tt>DirectorInterface</tt> in the example is implemented by the <tt>
|
|
overwrittenMethodsOnFooBarAbstract</tt> Go struct type. A pointer to a <tt>
|
|
overwrittenMethodsOnFooBarAbstract</tt> struct instance will be given to
|
|
the <tt>NewDirectorFooBarAbstract</tt> constructor function. The
|
|
constructor return value implements the <tt>FooBarAbstract</tt>
|
|
interface. <tt>overwrittenMethodsOnFooBarAbstract</tt> could in theory
|
|
be any Go type but in practice a struct is used as it typically
|
|
contains at least a value of the C++ class interface so that the
|
|
overwritten methods can use the rest of the C++ class. If the <tt>
|
|
FooBarGo</tt> class would receive additional constructor arguments then
|
|
these would also typically be stored in the <tt>
|
|
overwrittenMethodsOnFooBarAbstract</tt> struct so that they can be used
|
|
by the Go methods.</p>
|
|
<h4><a name="Go_director_base_methods">25.4.9.5 Call base methods</a></h4>
|
|
<p> Often a virtual method will be overwritten to extend the original
|
|
behavior of the method in the base class. This is also the case for the
|
|
<tt>FooBarCpp::Foo</tt> method of the example code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
virtual std::string Foo() {
|
|
return "C++ " + FooBarAbstract::Foo();
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> To use base methods the <tt>DirectorClassNameMethodName</tt> wrapper
|
|
functions are automatically generated by SWIG for public and protected
|
|
virtual methods. The <tt>FooBarGo.Foo</tt> implementation in the
|
|
example looks like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
|
return "Go " + DirectorFooBarAbstractFoo(om.fb)
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The complete example, including the <tt>FooBarGoo</tt> class
|
|
implementation, can be found in <a href="#Go_director_foobargo_class">
|
|
the end of the guide</a>.</p>
|
|
<h4><a name="Go_director_subclass">25.4.9.6 Subclass via embedding</a></h4>
|
|
<p> <a href="#Go_director_ctor_dtor">As previously mentioned in this
|
|
guide</a> the default and director constructor functions return the
|
|
same interface type. To properly subclass a C++ class with a Go type
|
|
the director object instance returned by the <tt>NewDirectorClassName</tt>
|
|
constructor function should be embedded into a Go struct so that it
|
|
represents a distinct but compatible type in Go's type system. This Go
|
|
struct should be private and the constructor and destructor functions
|
|
should instead work with a public interface type so that the Go class
|
|
that subclasses a C++ class can be used as a compatible drop in.</p>
|
|
<p> The subclassing part of the <tt>FooBarGo</tt> class for an example
|
|
looks like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
type FooBarGo interface {
|
|
FooBarAbstract
|
|
deleteFooBarAbstract()
|
|
IsFooBarGo()
|
|
}
|
|
|
|
type fooBarGo struct {
|
|
FooBarAbstract
|
|
}
|
|
|
|
func (fbgs *fooBarGo) deleteFooBarAbstract() {
|
|
DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
|
|
}
|
|
|
|
func (fbgs *fooBarGo) IsFooBarGo() {}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om)
|
|
om.fb = fb
|
|
|
|
return &fooBarGo{FooBarAbstract: fb}
|
|
}
|
|
|
|
func DeleteFooBarGo(fbg FooBarGo) {
|
|
fbg.deleteFooBarAbstract()
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The complete example, including the <tt>FooBarGoo</tt> class
|
|
implementation, can be found in <a href="#Go_director_foobargo_class">
|
|
the end of the guide</a>. In this part of the example the private <tt>
|
|
fooBarGo</tt> struct embeds <tt>FooBarAbstract</tt> which lets the <tt>
|
|
fooBarGo</tt> Go type "inherit" all the methods of the <tt>
|
|
FooBarAbstract</tt> C++ class by means of embedding. The public <tt>
|
|
FooBarGo</tt> interface type includes the <tt>FooBarAbstract</tt>
|
|
interface and hence <tt>FooBarGo</tt> can be used as a drop in
|
|
replacement for <tt>FooBarAbstract</tt> while the reverse isn't
|
|
possible and would raise a compile time error. Furthermore the
|
|
constructor and destructor functions <tt>NewFooBarGo</tt> and <tt>
|
|
DeleteFooBarGo</tt> take care of all the director specifics and to the
|
|
user the class appears as any other SWIG wrapped C++ class.</p>
|
|
<h4><a name="Go_director_finalizer">25.4.9.7 Memory management with
|
|
runtime.SetFinalizer</a></h4>
|
|
<p> In general all guidelines for <a href="#Go_class_memory">C++ class
|
|
memory management</a> apply as well to director classes. One often
|
|
overlooked limitation with <tt>runtime.SetFinalizer</tt> is that a
|
|
finalizer doesn't run in case of a cycle and director classes typically
|
|
have a cycle. The cycle in the <tt>FooBarGo</tt> class is here:</p>
|
|
<div class="code">
|
|
<pre>
|
|
type overwrittenMethodsOnFooBarAbstract struct {
|
|
fb FooBarAbstract
|
|
}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om) // fb.v = om
|
|
om.fb = fb // Backlink causes cycle as fb.v = om!
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> In order to be able to use <tt>runtime.SetFinalizer</tt>
|
|
nevertheless the finalizer needs to be set on something that isn't in a
|
|
cycle and that references the director object instance. In the <tt>
|
|
FooBarGo</tt> class example the <tt>FooBarAbstract</tt> director
|
|
instance can be automatically deleted by setting the finalizer on <tt>
|
|
fooBarGo</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
type fooBarGo struct {
|
|
FooBarAbstract
|
|
}
|
|
|
|
type overwrittenMethodsOnFooBarAbstract struct {
|
|
fb FooBarAbstract
|
|
}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om)
|
|
om.fb = fb // Backlink causes cycle as fb.v = om!
|
|
|
|
fbgs := &fooBarGo{FooBarAbstract: fb}
|
|
runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
|
|
return fbgs
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Furthermore if <tt>runtime.SetFinalizer</tt> is in use either the <tt>
|
|
DeleteClassName</tt> destructor function needs to be removed or the <tt>
|
|
fooBarGo</tt> struct needs additional data to prevent double deletion.
|
|
Please read the <a href="#Go_class_memory">C++ class memory management</a>
|
|
subchapter before using <tt>runtime.SetFinalizer</tt> to know all of
|
|
its gotchas.</p>
|
|
<h4><a name="Go_director_foobargo_class">25.4.9.8 Complete FooBarGo
|
|
example class</a></h4>
|
|
<p> The complete and annotated <tt>FooBarGo</tt> class looks like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// FooBarGo is a superset of FooBarAbstract and hence FooBarGo can be used as a
|
|
// drop in replacement for FooBarAbstract but the reverse causes a compile time
|
|
// error.
|
|
type FooBarGo interface {
|
|
FooBarAbstract
|
|
deleteFooBarAbstract()
|
|
IsFooBarGo()
|
|
}
|
|
|
|
// Via embedding fooBarGo "inherits" all methods of FooBarAbstract.
|
|
type fooBarGo struct {
|
|
FooBarAbstract
|
|
}
|
|
|
|
func (fbgs *fooBarGo) deleteFooBarAbstract() {
|
|
DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
|
|
}
|
|
|
|
// The IsFooBarGo method ensures that FooBarGo is a superset of FooBarAbstract.
|
|
// This is also how the class hierarchy gets represented by the SWIG generated
|
|
// wrapper code. For an instance FooBarCpp has the IsFooBarAbstract and
|
|
// IsFooBarCpp methods.
|
|
func (fbgs *fooBarGo) IsFooBarGo() {}
|
|
|
|
// Go type that defines the DirectorInterface. It contains the Foo and Bar
|
|
// methods that overwrite the respective virtual C++ methods on FooBarAbstract.
|
|
type overwrittenMethodsOnFooBarAbstract struct {
|
|
// Backlink to FooBarAbstract so that the rest of the class can be used by
|
|
// the overridden methods.
|
|
fb FooBarAbstract
|
|
|
|
// If additional constructor arguments have been given they are typically
|
|
// stored here so that the overridden methods can use them.
|
|
}
|
|
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
|
// DirectorFooBarAbstractFoo calls the base method FooBarAbstract::Foo.
|
|
return "Go " + DirectorFooBarAbstractFoo(om.fb)
|
|
}
|
|
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
|
|
return "Go Bar"
|
|
}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
// Instantiate FooBarAbstract with selected methods overridden. The methods
|
|
// that will be overwritten are defined on
|
|
// overwrittenMethodsOnFooBarAbstract and have a compatible signature to the
|
|
// respective virtual C++ methods. Furthermore additional constructor
|
|
// arguments will be typically stored in the
|
|
// overwrittenMethodsOnFooBarAbstract struct.
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om)
|
|
om.fb = fb // Backlink causes cycle as fb.v = om!
|
|
|
|
fbgs := &fooBarGo{FooBarAbstract: fb}
|
|
// The memory of the FooBarAbstract director object instance can be
|
|
// automatically freed once the FooBarGo instance is garbage collected by
|
|
// uncommenting the following line. Please make sure to understand the
|
|
// runtime.SetFinalizer specific gotchas before doing this. Furthermore
|
|
// DeleteFooBarGo should be deleted if a finalizer is in use or the fooBarGo
|
|
// struct needs additional data to prevent double deletion.
|
|
// runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
|
|
return fbgs
|
|
}
|
|
|
|
// Recommended to be removed if runtime.SetFinalizer is in use.
|
|
func DeleteFooBarGo(fbg FooBarGo) {
|
|
fbg.deleteFooBarAbstract()
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Returned string by the <tt>FooBarGo.FooBar</tt> method is:</p>
|
|
<div class="code">
|
|
<pre>
|
|
Go Foo, Go Bar
|
|
</pre>
|
|
</div>
|
|
<p> For comparison the <tt>FooBarCpp</tt> class looks like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class FooBarCpp : public FooBarAbstract
|
|
{
|
|
protected:
|
|
virtual std::string Foo() {
|
|
return "C++ " + FooBarAbstract::Foo();
|
|
}
|
|
|
|
virtual std::string Bar() {
|
|
return "C++ Bar";
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> For comparison the returned string by the <tt>FooBarCpp::FooBar</tt>
|
|
method is:</p>
|
|
<div class="code">
|
|
<pre>
|
|
C++ Foo, C++ Bar
|
|
</pre>
|
|
</div>
|
|
<p> The complete source of this example can be found under <a href="https://github.com/swig/swig/tree/master/Examples/go/director">
|
|
SWIG/Examples/go/director/</a>.</p>
|
|
<h3><a name="Go_primitive_type_mappings">25.4.10 Default Go primitive
|
|
type mappings</a></h3>
|
|
<p> The following table lists the default type mapping from C/C++ to Go.
|
|
This table will tell you which Go type to expect for a function which
|
|
uses a given C/C++ type.</p>
|
|
<table BORDER summary="Go primitive type mappings">
|
|
<tr><td><b>C/C++ type</b></td><td><b>Go type</b></td></tr>
|
|
<tr><td>bool</td><td>bool</td></tr>
|
|
<tr><td>char</td><td>byte</td></tr>
|
|
<tr><td>signed char</td><td>int8</td></tr>
|
|
<tr><td>unsigned char</td><td>byte</td></tr>
|
|
<tr><td>short</td><td>int16</td></tr>
|
|
<tr><td>unsigned short</td><td>uint16</td></tr>
|
|
<tr><td>int</td><td>int</td></tr>
|
|
<tr><td>unsigned int</td><td>uint</td></tr>
|
|
<tr><td>long</td><td>int64</td></tr>
|
|
<tr><td>unsigned long</td><td>uint64</td></tr>
|
|
<tr><td>long long</td><td>int64</td></tr>
|
|
<tr><td>unsigned long long</td><td>uint64</td></tr>
|
|
<tr><td>float</td><td>float32</td></tr>
|
|
<tr><td>double</td><td>float64</td></tr>
|
|
<tr><td>char *
|
|
<br>char []</td><td>string</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> These type mappings are defined by the "gotype" typemap. You may
|
|
change that typemap, or add new values, to control how C/C++ types are
|
|
mapped into Go types.</p>
|
|
<h3><a name="Go_output_arguments">25.4.11 Output arguments</a></h3>
|
|
<p>Because of limitations in the way output arguments are processed in
|
|
swig, a function with output arguments will not have multiple return
|
|
values. Instead, you must pass a pointer into the C++ function to tell
|
|
it where to store the output value. In go, you supply a slice in the
|
|
place of the output argument.</p>
|
|
<p>For example, suppose you were trying to wrap the modf() function in
|
|
the C math library which splits x into integral and fractional parts
|
|
(and returns the integer part in one of its parameters):</p>
|
|
<div class="code">
|
|
<pre>
|
|
double modf(double x, double *ip);
|
|
</pre>
|
|
</div>
|
|
<p>You could wrap it with SWIG as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <typemaps.i>
|
|
double modf(double x, double *OUTPUT);
|
|
</pre>
|
|
</div>
|
|
<p>or you can use the <code>%apply</code> directive:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <typemaps.i>
|
|
%apply double *OUTPUT { double *ip };
|
|
double modf(double x, double *ip);
|
|
</pre>
|
|
</div>
|
|
<p>In Go you would use it like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
ptr := []float64{0.0}
|
|
fraction := modulename.Modf(5.0, ptr)
|
|
</pre>
|
|
</div>
|
|
<p>Since this is ugly, you may want to wrap the swig-generated API with
|
|
some <a href="#Go_adding_additional_code">additional functions written
|
|
in go</a> that hide the ugly details.</p>
|
|
<p>There are no <code>char *OUTPUT</code> typemaps. However you can
|
|
apply the <code>signed char *</code> typemaps instead:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <typemaps.i>
|
|
%apply signed char *OUTPUT {char *output};
|
|
void f(char *output);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Go_adding_additional_code">25.4.12 Adding additional go
|
|
code</a></h3>
|
|
<p>Often the APIs generated by swig are not very natural in go,
|
|
especially if there are output arguments. You can insert additional go
|
|
wrapping code to add new APIs with <code>%insert(go_wrapper)</code>,
|
|
like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <typemaps.i>
|
|
// Change name of what swig generates to Wrapped_modf. This function will
|
|
// have the following signature in go:
|
|
// func Wrapped_modf(float64, []float64) float64
|
|
%rename(wrapped_modf) modf(double x, double *ip);
|
|
|
|
%apply double *OUTPUT { double *ip };
|
|
double modf(double x, double *ip);
|
|
|
|
%insert(go_wrapper) %{
|
|
|
|
// The improved go interface to this function, which has two return values,
|
|
// in the more natural go idiom:
|
|
func Modf(x float64) (fracPart float64, intPart float64) {
|
|
ip := []float64{0.0}
|
|
fracPart = Wrapped_modf(x, ip)
|
|
intPart = ip[0]
|
|
return
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p>For classes, since swig generates an interface, you can add
|
|
additional methods by defining another interface that includes the
|
|
swig-generated interface. For example,</p>
|
|
<div class="code">
|
|
<pre>
|
|
%rename(Wrapped_MyClass) MyClass;
|
|
%rename(Wrapped_GetAValue) MyClass::GetAValue(int *x);
|
|
%apply int *OUTPUT { int *x };
|
|
|
|
class MyClass {
|
|
public:
|
|
MyClass();
|
|
int AFineMethod(const char *arg); // Swig's wrapping is fine for this one.
|
|
bool GetAValue(int *x);
|
|
};
|
|
|
|
%insert(go_wrapper) %{
|
|
|
|
type MyClass interface {
|
|
Wrapped_MyClass
|
|
GetAValue() (int, bool)
|
|
}
|
|
|
|
func (arg SwigcptrWrapped_MyClass) GetAValue() (int, bool) {
|
|
ip := []int{0}
|
|
ok := arg.Wrapped_GetAValue(ip)
|
|
return ip[0], ok
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p>Of course, if you have to rewrite most of the methods, instead of
|
|
just a few, then you might as well define your own struct that includes
|
|
the swig-wrapped object, instead of adding methods to the
|
|
swig-generated object.</p>
|
|
<p>If you need to import other go packages, you can do this with <code>
|
|
%go_import</code>. For example,</p>
|
|
<div class="code">
|
|
<pre>
|
|
%go_import("fmt", _ "unusedPackage", rp "renamed/package")
|
|
|
|
%insert(go_wrapper) %{
|
|
|
|
func foo() {
|
|
fmt.Println("Some string:", rp.GetString())
|
|
}
|
|
|
|
// Importing the same package twice is permitted,
|
|
// Go code will be generated with only the first instance of the import.
|
|
%go_import("fmt")
|
|
|
|
%insert(go_wrapper) %{
|
|
|
|
func bar() {
|
|
fmt.Println("Hello world!")
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Go_typemaps">25.4.13 Go typemaps</a></h3>
|
|
<p> You can use the <tt>%typemap</tt> directive to modify SWIG's default
|
|
wrapping behavior for specific C/C++ types. You need to be familiar
|
|
with the material in the general "<a href="#Typemaps">Typemaps</a>"
|
|
chapter. That chapter explains how to define a typemap. This section
|
|
describes some specific typemaps used for Go.</p>
|
|
<p> In general type conversion code may be written either in C/C++ or in
|
|
Go. The choice to make normally depends on where memory should be
|
|
allocated. To allocate memory controlled by the Go garbage collector,
|
|
write Go code. To allocate memory in the C/C++ heap, write C code.</p>
|
|
<table BORDER summary="Go Typemaps">
|
|
<tr><td><b>Typemap</b></td><td><b>Description</b></td></tr>
|
|
<tr><td>gotype</td><td> The Go type to use for a C++ type. This type
|
|
will appear in the generated Go wrapper function. If this is not
|
|
defined SWIG will use a default as <a href="#Go_primitive_type_mappings">
|
|
described above</a>.</td></tr>
|
|
<tr><td>imtype</td><td> An intermediate Go type used by the "goin",
|
|
"goout", "godirectorin", and "godirectorout" typemaps. If this typemap
|
|
is not defined for a C/C++ type, the gotype typemap will be used. This
|
|
is useful when gotype is best converted to C/C++ using Go code.</td></tr>
|
|
<tr><td>goin</td><td> Go code to convert from gotype to imtype when
|
|
calling a C/C++ function. SWIG will then internally convert imtype to a
|
|
C/C++ type and pass it down. If this is not defined, or is the empty
|
|
string, no conversion is done.</td></tr>
|
|
<tr><td>in</td><td> C/C++ code to convert the internally generated C/C++
|
|
type, based on imtype, into the C/C++ type that a function call
|
|
expects. If this is not defined the value will simply be cast to the
|
|
desired type.</td></tr>
|
|
<tr><td>out</td><td> C/C++ code to convert the C/C++ type that a
|
|
function call returns into the internally generated C/C++ type, based
|
|
on imtype, that will be returned to Go. If this is not defined the
|
|
value will simply be cast to the desired type.</td></tr>
|
|
<tr><td>goout</td><td> Go code to convert a value returned from a C/C++
|
|
function from imtype to gotype. If this is not defined, or is the empty
|
|
string, no conversion is done.</td></tr>
|
|
<tr><td>argout</td><td> C/C++ code to adjust an argument value when
|
|
returning from a function. This is called after the real C/C++ function
|
|
has run. This uses the internally generated C/C++ type, based on
|
|
imtype. This is only useful for a pointer type of some sort. If this is
|
|
not defined nothing will be done.</td></tr>
|
|
<tr><td>goargout</td><td> Go code to adjust an argument value when
|
|
returning from a function. This is called after the real C/C++ function
|
|
has run. The value will be in imtype. This is only useful for a pointer
|
|
type of some sort. If this is not defined, or is the empty string,
|
|
nothing will be done.</td></tr>
|
|
<tr><td>directorin</td><td> C/C++ code to convert the C/C++ type used to
|
|
call a director method into the internally generated C/C++ type, based
|
|
on imtype, that will be passed to Go. If this is not defined the value
|
|
will simply be cast to the desired type.</td></tr>
|
|
<tr><td>godirectorin</td><td> Go code to convert a value used to call a
|
|
director method from imtype to gotype. If this is not defined, or is
|
|
the empty string, no conversion is done.</td></tr>
|
|
<tr><td>godirectorout</td><td> Go code to convert a value returned from
|
|
a director method from gotype to imtype. If this is not defined, or is
|
|
the empty string, no conversion is done.</td></tr>
|
|
<tr><td>directorout</td><td> C/C++ code to convert a value returned from
|
|
a director method from the internally generated C/C++ type, based on
|
|
imtype, into the type that the method should return If this is not
|
|
defined the value will simply be cast to the desired type.</td></tr>
|
|
</table>
|
|
<HR NOSHADE>
|
|
<h1><a name="Guile">26 SWIG and Guile</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Guile_nn1">Supported Guile Versions</a></li>
|
|
<li><a href="#Guile_nn2">Meaning of "Module"</a></li>
|
|
<li><a href="#Guile_nn3">Old 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_nn14">Smobs</a></li>
|
|
<li><a href="#Guile_nn15">Garbage Collection</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Guile_nn16">Native Guile pointers</a></li>
|
|
<li><a href="#Guile_nn17">Exception Handling</a></li>
|
|
<li><a href="#Guile_nn18">Procedure documentation</a></li>
|
|
<li><a href="#Guile_nn19">Procedures with setters</a></li>
|
|
<li><a href="#Guile_nn20">GOOPS Proxy Classes</a>
|
|
<ul>
|
|
<li><a href="#Guile_nn21">Naming Issues</a></li>
|
|
<li><a href="#Guile_nn22">Linking</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> This section details guile-specific support in SWIG.</p>
|
|
<h2><a name="Guile_nn1">26.1 Supported Guile Versions</a></h2>
|
|
<p> SWIG is known to work with Guile versions 2.0.x, 2.2.x and 3.0.x
|
|
(these are all tested via CI). SWIG probably still works with Guile
|
|
1.8.x but we're no longer able to regularly test this either in CI or
|
|
by hand. Support for Guile 1.6.x has been dropped (SWIG 2.0.9 was the
|
|
last version of SWIG to support it).</p>
|
|
<p> Note that starting with guile 2.0, the guile sources can be compiled
|
|
for improved performance. This is currently not tested with swig so
|
|
your mileage may vary. To be safe set environment variable <tt>
|
|
GUILE_AUTO_COMPILE</tt> to 0 when using swig generated guile code.</p>
|
|
<h2><a name="Guile_nn2">26.2 Meaning of "Module"</a></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">26.3 Old GH Guile API</a></h2>
|
|
<p>Guile 1.8 and older could be interfaced using two different api's,
|
|
the SCM or the GH API. The GH interface to guile is deprecated. Read
|
|
more about why in the <a href="https://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/GH.html#GH">
|
|
Guile manual</a>.</p>
|
|
<p>Support for the guile GH wrapper code generation has been dropped
|
|
from SWIG. The last version of SWIG that can still generate guile GH
|
|
wrapper code is 2.0.9. Please use that version if you really need the
|
|
GH wrapper code.</p>
|
|
<h2><a name="Guile_nn4">26.4 Linkage</a></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">26.4.1 Simple Linkage</a></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 "./libexample.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 "./libexample.so" "SWIG_init")
|
|
</pre>
|
|
</div>
|
|
<p> A more portable approach would be to drop the shared library
|
|
extension:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
(load-extension "./libexample" "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 "./libexample.so" "SWIG_init") %}
|
|
</pre>
|
|
</div>
|
|
<p> (The <code>%scheme</code> directive allows inserting 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">26.4.2 Passive Linkage</a></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">26.4.3 Native Guile Module Linkage</a></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.</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 "./libfoo"))
|
|
;; 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 "./libfoo.so" "scm_init_my_modules_foo_module")
|
|
</pre>
|
|
</div></li>
|
|
</ul>
|
|
<h3><a name="Guile_nn8">26.4.4 Old Auto-Loading Guile Module Linkage</a></h3>
|
|
<p>Guile used to support an autoloading facility for object-code
|
|
modules, but this support was deprecated and removed in Guile version
|
|
1.4.1. SWIG supported this via option <code>-Linkage ltdlmod</code>,
|
|
but this support is no longer useful and was removed in SWIG 4.2.0.</p>
|
|
<h3><a name="Guile_nn9">26.4.5 Hobbit4D Linkage</a></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">26.5 Underscore Folding</a></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 <a href="#SWIG_rename_ignore">SWIG directive <code>
|
|
%rename</code></a> to specify the Guile names of the wrapped functions
|
|
and variables.</p>
|
|
<h2><a name="Guile_nn11">26.6 Typemaps</a></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="#Customization_features">
|
|
Features and the %feature directive</a> for info on how to apply the
|
|
%feature.</p>
|
|
<h2><a name="Guile_nn12">26.7 Representation of pointers as smobs</a></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="#Typemaps_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_nn14">26.7.1 Smobs</a></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>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. If a generated GOOPS module has been loaded,
|
|
smobs will be wrapped by the corresponding GOOPS class.</p>
|
|
<h3><a name="Guile_nn15">26.7.2 Garbage Collection</a></h3>
|
|
<p>Garbage collection is a feature of Guile since version 1.6. As SWIG
|
|
now requires Guile > 1.8, it is automatically included. 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="#Customization_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">26.8 Native Guile pointers</a></h2>
|
|
<p> In addition to SWIG smob pointers, <a href="https://www.gnu.org/software/guile/manual/html_node/Foreign-Pointers.html">
|
|
Guile's native pointer type</a> are accepted as arguments to wrapped
|
|
SWIG functions. This can be useful for passing <a href="https://www.gnu.org/software/guile/manual/html_node/Void-Pointers-and-Byte-Access.html#">
|
|
pointers to bytevector data</a> to wrapped functions.</p>
|
|
<h2><a name="Guile_nn17">26.9 Exception Handling</a></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");
|
|
MAP(SWIG_NullReferenceError, "swig-null-reference-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_nn18">26.10 Procedure documentation</a></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>.</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_nn19">26.11 Procedures with setters</a></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_nn20">26.12 GOOPS Proxy Classes</a></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>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_nn21">26.12.1 Naming Issues</a></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>
|
|
<h3><a name="Guile_nn22">26.12.2 Linking</a></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 shared library.<div class="code">
|
|
<pre>
|
|
%goops %{ (load-extension "./libfoo.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 "./libfoo.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 shared 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 "./libfoo.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 "./libfoo.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 "./libfoo.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">27 SWIG and Java</a></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="#Java_running_swig">Running SWIG</a></li>
|
|
<li><a href="#Java_commandline">Additional Commandline Options</a></li>
|
|
<li><a href="#Java_getting_right_headers">Getting the right header files</a>
|
|
</li>
|
|
<li><a href="#Java_compiling_dynamic">Compiling a dynamic module</a></li>
|
|
<li><a href="#Java_using_module">Using your module</a></li>
|
|
<li><a href="#Java_dynamic_linking_problems">Dynamic linking problems</a>
|
|
</li>
|
|
<li><a href="#Java_compilation_problems_cpp">Compilation problems and
|
|
compiling with C++</a></li>
|
|
<li><a href="#Java_building_windows">Building on Windows</a>
|
|
<ul>
|
|
<li><a href="#Java_visual_studio">Running SWIG from Visual Studio</a></li>
|
|
<li><a href="#Java_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="#Java_module_packages_classes">Modules, packages and
|
|
generated Java classes</a></li>
|
|
<li><a href="#Java_functions">Functions</a></li>
|
|
<li><a href="#Java_global_variables">Global variables</a></li>
|
|
<li><a href="#Java_constants">Constants</a></li>
|
|
<li><a href="#Java_enumerations">Enumerations</a>
|
|
<ul>
|
|
<li><a href="#Java_anonymous_enums">Anonymous enums</a></li>
|
|
<li><a href="#Java_typesafe_enums">Typesafe enums</a></li>
|
|
<li><a href="#Java_proper_enums">Proper Java enums</a></li>
|
|
<li><a href="#Java_typeunsafe_enums">Type unsafe enums</a></li>
|
|
<li><a href="#Java_simple_enums">Simple enums</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_pointers">Pointers</a></li>
|
|
<li><a href="#Java_structures">Structures</a></li>
|
|
<li><a href="#Java_classes">C++ classes</a></li>
|
|
<li><a href="#Java_inheritance">C++ inheritance</a></li>
|
|
<li><a href="#Java_pointers_refs_arrays">Pointers, references, arrays
|
|
and pass by value</a>
|
|
<ul>
|
|
<li><a href="#Java_null_pointers">Null pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_overloaded_functions">C++ overloaded functions</a></li>
|
|
<li><a href="#Java_default_arguments">C++ default arguments</a></li>
|
|
<li><a href="#Java_namespaces">C++ namespaces</a></li>
|
|
<li><a href="#Java_templates">C++ templates</a></li>
|
|
<li><a href="#Java_smart_pointers">C++ Smart Pointers</a>
|
|
<ul>
|
|
<li><a href="#Java_smart_pointers_shared_ptr">The shared_ptr Smart
|
|
Pointer</a></li>
|
|
<li><a href="#Java_smart_pointers_generic">Generic Smart Pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_further_details">Further details on the generated
|
|
Java classes</a>
|
|
<ul>
|
|
<li><a href="#Java_imclass">The intermediary JNI class</a>
|
|
<ul>
|
|
<li><a href="#Java_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="#Java_module_class_pragmas">The Java module class pragmas</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_constants_interface">The Java constants interface</a>
|
|
<ul>
|
|
<li><a href="#Java_constants_interface_pragmas">The Java constants
|
|
interface pragmas</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_proxy_classes">Java proxy classes</a>
|
|
<ul>
|
|
<li><a href="#Java_memory_management">Memory management</a></li>
|
|
<li><a href="#Java_inheritance_mirroring">Inheritance</a></li>
|
|
<li><a href="#Java_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="#Java_type_wrapper_classes">Type wrapper classes</a></li>
|
|
<li><a href="#Java_enum_classes">Enum classes</a>
|
|
<ul>
|
|
<li><a href="#Java_typesafe_enums_classes">Typesafe enum classes</a></li>
|
|
<li><a href="#Java_proper_enums_classes">Proper Java enum classes</a></li>
|
|
<li><a href="#Java_typeunsafe_enums_classes">Type unsafe enum classes</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_interfaces">Interfaces</a></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>
|
|
<li><a href="#Java_directors_performance">Director performance tuning</a>
|
|
</li>
|
|
<li><a href="#Java_exceptions_from_directors">Java exceptions from
|
|
directors</a>
|
|
<ul>
|
|
<li><a href="#Java_customizing_director_exceptions">Customizing director
|
|
exceptions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_protected_virtual_methods">Accessing virtual
|
|
protected methods</a></li>
|
|
<li><a href="#Java_allprotected">Accessing non-virtual protected members</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_common_customization">Common customization features</a>
|
|
<ul>
|
|
<li><a href="#Java_helper_functions">C/C++ helper functions</a></li>
|
|
<li><a href="#Java_class_extension">Class extension with %extend</a></li>
|
|
<li><a href="#Java_proxycode">Class extension with %proxycode</a></li>
|
|
<li><a href="#Java_exception_handling">Exception handling with
|
|
%exception and %javaexception</a></li>
|
|
<li><a href="#Java_method_access">Method access with
|
|
%javamethodmodifiers</a></li>
|
|
<li><a href="#Java_begin">Java begin</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_tips_techniques">Tips and techniques</a>
|
|
<ul>
|
|
<li><a href="#Java_input_output_parameters">Input and output parameters
|
|
using primitive pointers and references</a></li>
|
|
<li><a href="#Java_simple_pointers">Simple pointers</a></li>
|
|
<li><a href="#Java_c_arrays">Wrapping C arrays with Java arrays</a></li>
|
|
<li><a href="#Java_unbounded_c_arrays">Unbounded C Arrays</a></li>
|
|
<li><a href="#Java_string_length">Passing a string with length</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="#Java_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="#Java_jvm64">Sixty four bit JVMs</a></li>
|
|
<li><a href="#Java_what_is_typemap">What is a typemap?</a></li>
|
|
<li><a href="#Java_typemaps_c_to_java_types">Typemaps for mapping C/C++
|
|
types to Java types</a></li>
|
|
<li><a href="#Java_typemap_attributes">Java typemap attributes</a></li>
|
|
<li><a href="#Java_special_variables">Java special variables</a></li>
|
|
<li><a href="#Java_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="#Java_typemap_examples">Typemap Examples</a>
|
|
<ul>
|
|
<li><a href="#Java_simpler_enum_classes">Simpler Java enums for enums
|
|
without initializers</a></li>
|
|
<li><a href="#Java_exception_typemap">Handling C++ exception
|
|
specifications as Java exceptions</a></li>
|
|
<li><a href="#Java_nan_exception_typemap">NaN Exception - exception
|
|
handling for a particular type</a></li>
|
|
<li><a href="#Java_converting_java_string_arrays">Converting Java String
|
|
arrays to char **</a></li>
|
|
<li><a href="#Java_expanding_java_object">Expanding a Java object to
|
|
multiple arguments</a></li>
|
|
<li><a href="#Java_using_typemaps_return_arguments">Using typemaps to
|
|
return arguments</a></li>
|
|
<li><a href="#Java_adding_downcasts">Adding Java downcasts to
|
|
polymorphic return types</a></li>
|
|
<li><a href="#Java_adding_equals_method">Adding an equals method to the
|
|
Java classes</a></li>
|
|
<li><a href="#Java_void_pointers">Void pointers and a common Java base
|
|
class</a></li>
|
|
<li><a href="#Java_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="#Java_odds_ends">Odds and ends</a>
|
|
<ul>
|
|
<li><a href="#Java_javadoc_comments">JavaDoc comments</a></li>
|
|
<li><a href="#Java_functional_interface">Functional interface without
|
|
proxy classes</a></li>
|
|
<li><a href="#Java_using_own_jni_functions">Using your own JNI functions</a>
|
|
</li>
|
|
<li><a href="#Java_performance">Performance concerns and hints</a></li>
|
|
<li><a href="#Java_debugging">Debugging</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Java_examples">Java 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">27.1 Overview</a></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 via the director
|
|
feature.</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">27.2 Preliminaries</a></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>
|
|
<p> Android uses Java JNI and also works with SWIG. Please read the <a href="#Android">
|
|
Android chapter</a> in conjunction with this one if you are targeting
|
|
Android.</p>
|
|
<h3><a name="Java_running_swig">27.2.1 Running SWIG</a></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="#SWIG_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="#Java_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">27.2.2 Additional Commandline Options</a></h3>
|
|
<p> The following table lists 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="Java_getting_right_headers">27.2.3 Getting the right header
|
|
files</a></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="Java_compiling_dynamic">27.2.4 Compiling a dynamic module</a>
|
|
</h3>
|
|
<p> The JNI code exists in a dynamic module or shared library (DLL on
|
|
Windows) and gets loaded by the JVM. Assuming you have code you need to
|
|
link to in a file called <tt>example.c</tt>, in order 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 -fPIC -c example_wrap.c -I/usr/java/include -I/usr/java/include/solaris
|
|
$ gcc -fPIC -c example.c
|
|
$ ld -G example_wrap.o example.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="https://github.com/swig/swig/wiki">
|
|
SWIG Wiki</a> for additional information.</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="#Java_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="#Java_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="Java_using_module">27.2.5 Using your module</a></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="Java_dynamic_linking_problems">27.2.6 Dynamic linking
|
|
problems</a></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
|
|
option 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="https://github.com/swig/swig/wiki">
|
|
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="Java_compilation_problems_cpp">27.2.7 Compilation problems
|
|
and compiling with C++</a></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="Java_building_windows">27.2.8 Building on Windows</a></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="Java_visual_studio">27.2.8.1 Running SWIG from Visual
|
|
Studio</a></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="#Java_dynamic_linking_problems">Dynamic linking
|
|
problems</a>.</p>
|
|
<h4><a name="Java_nmake">27.2.8.2 Using NMAKE</a></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 it's 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
|
|
option for swig and replacing .c with .cxx.</p>
|
|
<h2><a name="Java_basic_tour">27.3 A tour of basic C/C++ wrapping</a></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="Java_module_packages_classes">27.3.1 Modules, packages and
|
|
generated Java classes</a></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>
|
|
<p> SWIG won't create the directory, so make sure it exists beforehand.</p>
|
|
<h3><a name="Java_functions">27.3.2 Functions</a></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="Java_global_variables">27.3.3 Global variables</a></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="Java_constants">27.3.4 Constants</a></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="#Customization_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="Java_enumerations">27.3.5 Enumerations</a></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="Java_anonymous_enums">27.3.5.1 Anonymous enums</a></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="Java_typesafe_enums">27.3.5.2 Typesafe enums</a></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="#Java_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 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="https://www.javaworld.com/article/2076970/create-enumerated-constants-in-java.html">
|
|
Create enumerated constants in Java</a> JavaWorld article, <a href="https://www.javaworld.com/article/2077499/java-tip-133--more-on-typesafe-enums.html">
|
|
Java Tip 133: More on typesafe enums</a> and <a href="https://www.javaworld.com/article/2077487/java-tip-122--beware-of-java-typesafe-enumerations.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="Java_proper_enums">27.3.5.3 Proper Java enums</a></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="#Java_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="#Java_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="#Java_simpler_enum_classes">
|
|
Simpler Java enums for enums without initializers</a> section.</p>
|
|
<h4><a name="Java_typeunsafe_enums">27.3.5.4 Type unsafe enums</a></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="#Java_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="Java_simple_enums">27.3.5.5 Simple enums</a></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="#Java_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="Java_pointers">27.3.6 Pointers</a></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="Java_structures">27.3.7 Structures</a></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="#Java_c_arrays">
|
|
Wrapping C arrays with Java arrays</a> and <a href="#Java_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="Java_classes">27.3.8 C++ classes</a></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="Java_inheritance">27.3.9 C++ inheritance</a></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>
|
|
<p> Private and protected methods are not wrapped as they are
|
|
inaccessible outside of the class. Protected methods can be made
|
|
accessible though via the directors feature, see the <a href="#Java_protected_virtual_methods">
|
|
Accessing virtual protected methods</a> in the directors section.</p>
|
|
<h3><a name="Java_pointers_refs_arrays">27.3.10 Pointers, references,
|
|
arrays and pass by value</a></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="Java_null_pointers">27.3.10.1 Null pointers</a></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="Java_overloaded_functions">27.3.11 C++ overloaded functions</a>
|
|
</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">27.3.12 C++ default arguments</a></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="Java_namespaces">27.3.13 C++ namespaces</a></h3>
|
|
<p> SWIG is aware of named C++ namespaces and they can be mapped to Java
|
|
packages, however, the default wrapping flattens the namespaces,
|
|
effectively ignoring them. So by default, the 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>
|
|
<p> The default behaviour described above can be improved via the <a href="#SWIGPlus_nspace">
|
|
nspace feature</a>. Note that it only works for classes, structs, unions
|
|
and enums declared within a named C++ namespace. When the nspace
|
|
feature is used (either the <tt>nspace</tt> feature flag or <tt>
|
|
%nspacemove</tt>), the C++ namespaces are converted into Java packages
|
|
of the same name. Proxy classes are thus declared within a package and
|
|
this proxy makes numerous calls to the JNI intermediary class which is
|
|
declared in the unnamed package by default. As Java does not support
|
|
types declared in a named package accessing types declared in an
|
|
unnamed package, the <tt>-package</tt> commandline option described
|
|
earlier generally should be used to provide a parent package. So if
|
|
SWIG is run using the <tt>-package com.myco</tt> option, a wrapped
|
|
class, <tt>MyWorld::Material::Color</tt>, can then be accessed as <tt>
|
|
com.myco.MyWorld.Material.Color</tt>. If you don't specify a package,
|
|
you will get the following warning:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:16: Warning 826: The nspace feature is used on 'MyWorld::Material::Color' without -package. The generated code
|
|
may not compile as Java does not support types declared in a named package accessing types declared in an unnamed package.
|
|
</pre>
|
|
</div>
|
|
<p> If it is undesirable to have a single top level package, the nspace
|
|
feature may be used without the <tt>-package</tt> commandline option
|
|
(and the resulting warning ignored) if all of the types exposed using
|
|
SWIG are placed in a package using the nspace feature and the
|
|
'jniclasspackage' pragma is used to specify a package for the JNI
|
|
intermediary class.</p>
|
|
<p> If the resulting use of the nspace feature and hence packages
|
|
results in a proxy class in one package deriving or using a proxy class
|
|
from another package, you will need to open up the visibility for the
|
|
pointer constructor and <tt>getCPtr</tt> method from the default
|
|
'protected' to 'public' with the <tt>SWIG_JAVABODY_PROXY</tt> macro.
|
|
See <a href="#Java_code_typemaps">Java code typemaps</a>.</p>
|
|
<h3><a name="Java_templates">27.3.14 C++ templates</a></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="Java_smart_pointers">27.3.15 C++ Smart Pointers</a></h3>
|
|
<h4><a name="Java_smart_pointers_shared_ptr">27.3.15.1 The shared_ptr
|
|
Smart Pointer</a></h4>
|
|
<p> The C++11 standard provides <tt>std::shared_ptr</tt> which was
|
|
derived from the Boost implementation, <tt>boost::shared_ptr</tt>. Both
|
|
of these are available for Java in the SWIG library and usage is
|
|
outlined in the <a href="#Library_std_shared_ptr">shared_ptr smart
|
|
pointer</a> library section.</p>
|
|
<h4><a name="Java_smart_pointers_generic">27.3.15.2 Generic Smart
|
|
Pointers</a></h4>
|
|
<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="Java_further_details">27.4 Further details on the generated
|
|
Java classes</a></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="Java_imclass">27.4.1 The intermediary JNI class</a></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="#Java_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="Java_imclass_pragmas">27.4.1.1 The intermediary JNI class
|
|
pragmas</a></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>jniclasspackage</td><td>Package in which to place 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 just the default package-private access.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%pragma(java) jniclassclassmodifiers="class"
|
|
</pre>
|
|
</div>
|
|
<p> All the methods in the intermediary JNI class will then not be
|
|
callable outside of the package as the method modifiers have been
|
|
changed from public access to default access. This is useful if you
|
|
want to prevent users calling these low level functions.</p>
|
|
<h3><a name="Java_module_class">27.4.2 The Java module class</a></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="Java_module_class_pragmas">27.4.2.1 The Java module class
|
|
pragmas</a></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="#Java_imclass_pragmas">The intermediary JNI class
|
|
pragmas</a> section for further details on using pragmas.</p>
|
|
<h3><a name="Java_constants_interface">27.4.3 The Java constants
|
|
interface</a></h3>
|
|
<p> C/C++ constants are generated as final static members in a constants
|
|
interface as mentioned in the <a href="#Java_constants">Constants</a>
|
|
section, such as the example in this section:</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> C/C++ enums can also be generated into the same constants interface
|
|
as described in the <a href="#Java_enumerations">Enumerations</a>
|
|
section.</p>
|
|
<h4><a name="Java_constants_interface_pragmas">27.4.3.1 The Java
|
|
constants interface pragmas</a></h4>
|
|
<p> Scope for tailoring the generated interface is limited to one
|
|
pragma, in the same manner as the intermediary JNI class pragmas and
|
|
module class pragmas. The pragma details are:</p>
|
|
<table BORDER summary="Java constants interface pragmas">
|
|
<tr VALIGN="TOP"><td><b>Pragma</b></td><td><b>Description</b></td></tr>
|
|
<tr><td>constantsmodifiers</td><td>Class modifiers and class type for
|
|
the constants interface, defaults to <tt>public interface</tt></td></tr>
|
|
</table>
|
|
<p> The pragma code appears in the generated constants interface like
|
|
this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
[ constantsmodifiers pragma ] constantsname {
|
|
... SWIG generated final static variables ...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> where <tt>constantsname</tt> is a name created by concatenating the
|
|
module name and <tt>Constants</tt>, for example, <tt>exampleConstants</tt>
|
|
for a module named <tt>example</tt>.</p>
|
|
<p> The only real use for this pragma is to change the visibility from
|
|
public to default with:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%pragma(java) constantsmodifiers="interface"
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Java_proxy_classes">27.4.4 Java proxy classes</a></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/docs/books/jni/html/stubs.html">
|
|
peer classes</a>. The default proxy class for our previous example looks
|
|
like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public class Foo {
|
|
private transient long swigCPtr;
|
|
protected transient 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="Java_memory_management">27.4.4.1 Memory management</a></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="Java_inheritance_mirroring">27.4.4.2 Inheritance</a></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 transient long swigCPtr;
|
|
protected transient 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 transient 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="Java_proxy_classes_gc">27.4.4.3 Proxy classes and garbage
|
|
collection</a></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="https://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="https://www.oracle.com/technetwork/java/index.html">
|
|
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
|
|
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">27.4.4.4 The premature garbage collection
|
|
prevention parameter for proxy class marshalling</a></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">27.4.4.5 Single threaded
|
|
applications and thread safety</a></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 transient long swigCPtr;
|
|
protected transient 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="Java_type_wrapper_classes">27.4.5 Type wrapper classes</a></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 transient 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="Java_enum_classes">27.4.6 Enum classes</a></h3>
|
|
<p> SWIG can generate three types of enum classes. The <a href="#Java_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="Java_typesafe_enums_classes">27.4.6.1 Typesafe enum classes</a>
|
|
</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="Java_proper_enums_classes">27.4.6.2 Proper Java enum
|
|
classes</a></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="#Java_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="Java_typeunsafe_enums_classes">27.4.6.3 Type unsafe enum
|
|
classes</a></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>
|
|
<h3><a name="Java_interfaces">27.4.7 Interfaces</a></h3>
|
|
<p> By default SWIG wraps all C++ classes as Java classes. As Java only
|
|
supports derivation from a single base class, SWIG has to ignore all
|
|
bases except the first when a C++ class inherits from more than one
|
|
base class. However, there is a family of SWIG macros that change the
|
|
default wrapping and allows a C++ class to be wrapped as a Java
|
|
interface instead of a Java class. These macros provide a way to
|
|
support some sort of multiple inheritance as there is no limit to the
|
|
number of interfaces that a Java class can inherit from.</p>
|
|
<p> When a C++ class is wrapped as a Java interface, a Java proxy class
|
|
is still needed. The <tt>swiginterface.i</tt> library file provides
|
|
three macros for marking a C++ class to be wrapped as a Java interface.
|
|
There is more than one macro in order to provide a choice for choosing
|
|
the Java interface and Java proxy names.</p>
|
|
<table BORDER summary="Java interface macros">
|
|
<tr VALIGN="TOP"><td><b>Interface Macro Name</b></td><td><b>Description</b>
|
|
</td></tr>
|
|
<tr><td><tt>%interface(CTYPE)</tt></td><td>For C++ class <tt>CTYPE</tt>,
|
|
proxy class name is unchanged without any suffix added, interface name
|
|
has <tt>SwigInterface</tt> added as a suffix.</td></tr>
|
|
<tr><td><tt>%interface_impl(CTYPE)</tt></td><td>For C++ class <tt>CTYPE</tt>
|
|
, proxy class name has <tt>SwigImpl</tt> added as a suffix, interface
|
|
name has no added suffix.</td></tr>
|
|
<tr><td><tt>%interface_custom("PROXY", "INTERFACE", CTYPE)</tt></td><td>
|
|
For C++ class <tt>CTYPE</tt>, proxy class name is given by the string <tt>
|
|
PROXY</tt>, interface name is given by the string <tt>INTERFACE</tt>.
|
|
The <tt>PROXY</tt> and <tt>INTERFACE</tt> names can use the <a href="#SWIG_advanced_renaming">
|
|
string formatting functions</a> used in <tt>%rename</tt>.</td></tr>
|
|
<tr><td><tt>%interface_additional("PROXY", "INTERFACE", "ADDITIONAL",
|
|
CTYPE)</tt></td><td>For C++ class <tt>CTYPE</tt>, proxy class name is
|
|
given by the string <tt>PROXY</tt>, interface name is given by the
|
|
string <tt>INTERFACE</tt>. The <tt>PROXY</tt> and <tt>INTERFACE</tt>
|
|
names can use the <a href="#SWIG_advanced_renaming">string formatting
|
|
functions</a> used in <tt>%rename</tt>. <tt>ADDITIONAL</tt> should
|
|
contain a comma separated list of interfaces for the interface class to
|
|
additionally extend. This is for adding interfaces not parsed by SWIG
|
|
and is useful for adding in pure Java interfaces</td></tr>
|
|
</table>
|
|
<p> The table below has a few examples showing the resulting proxy and
|
|
interface names for a C++ class called <tt>Base</tt>.</p>
|
|
<table BORDER summary="Java interface macro examples">
|
|
<tr VALIGN="TOP"><td><b>Example Usage</b></td><td><b>Proxy Class Name</b>
|
|
</td><td><b>Interface Class Name</b></td></tr>
|
|
<tr><td><tt>%interface(Base)</tt></td><td><tt>Base</tt></td><td><tt>
|
|
BaseSwigInterface</tt></td></tr>
|
|
<tr><td><tt>%interface_impl(Base)</tt></td><td><tt>BaseSwigImpl</tt></td><td>
|
|
<tt>Base</tt></td></tr>
|
|
<tr><td><tt>%interface_custom("BaseProxy", "IBase", Base)</tt></td><td><tt>
|
|
BaseProxy</tt></td><td><tt>IBase</tt></td></tr>
|
|
<tr><td><tt>%interface_custom("%sProxy", "IBase", Base)</tt></td><td><tt>
|
|
BaseProxy</tt></td><td><tt>IBase</tt></td></tr>
|
|
<tr><td><tt>%interface_custom("%sProxy", "%sInterface", Base)</tt></td><td>
|
|
<tt>BaseProxy</tt></td><td><tt>BaseProxyInterface</tt></td></tr>
|
|
<tr><td><tt>%interface_custom("%sProxy", "%(rstrip:[Proxy])sInterface",
|
|
Base)</tt></td><td><tt>BaseProxy</tt></td><td><tt>BaseInterface</tt></td>
|
|
</tr>
|
|
</table>
|
|
<p> The 2nd last example shows the names used in the string formatting
|
|
functions. The input for <tt>PROXY</tt> that <tt>"%s"</tt> expands to
|
|
is the proxy name, that is, Base. The input for <tt>INTERFACE</tt> that
|
|
<tt>"%s"</tt> expands to is the proxy name, that is, <tt>BaseProxy</tt>
|
|
.</p>
|
|
<p> The last example shows <tt>rstrip</tt> and in this case strips the <tt>
|
|
Proxy</tt> suffix and then adds on <tt>Interface</tt>.</p>
|
|
<p> Consider the following C++ code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
namespace Space {
|
|
struct Base1 {
|
|
virtual void Method1();
|
|
virtual Base1();
|
|
};
|
|
struct Base2 {
|
|
virtual void Method2();
|
|
virtual Base2();
|
|
};
|
|
struct Derived : Base1, Base2 {
|
|
};
|
|
void UseBases(const Base1 &b1, const Base2 &b2);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> By default all classes are wrapped and are available in Java, but, <tt>
|
|
Derived</tt> has all bases ignored except the first. SWIG generates a
|
|
warning for the above code:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:12: Warning 813: Warning for Derived, base Base2 ignored.
|
|
Multiple inheritance is not supported in Java.
|
|
</pre>
|
|
</div>
|
|
<p> If we decide to wrap the two base classes as interfaces and add the
|
|
following before SWIG parses the above example code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <swiginterface.i>
|
|
%interface_impl(Space::Base1);
|
|
%interface_impl(Space::Base2);
|
|
</pre>
|
|
</div>
|
|
<p> then two interface files are generated, Base1.java and Base2.java in
|
|
addition to proxy class files, Base1SwigImpl.java and
|
|
Base2SwigImpl.java. The contents of interface file Base1.java for <tt>
|
|
Base1</tt> is shown below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public interface Base1 {
|
|
long Base1_GetInterfaceCPtr();
|
|
void Method1();
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The proxy class in Base1SwigImpl.java for Base1 is as it would have
|
|
been if <tt>%interface</tt> was not used, except the name has changed
|
|
to <tt>Base1SwigImpl</tt> and it implements the appropriate base:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public class Base1SwigImpl implements Base1 {
|
|
...
|
|
public long Base1_GetInterfaceCPtr() {
|
|
return exampleJNI.Base1SwigImpl_Base1_GetInterfaceCPtr(swigCPtr);
|
|
}
|
|
|
|
public void Method1() {
|
|
exampleJNI.Base1SwigImpl_Method1(swigCPtr, this);
|
|
}
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> In fact any class using <tt>Base</tt> as an immediate base class
|
|
will now implement the interface instead of deriving from it (or
|
|
ignoring the base in the case of multiple base classes). Hence the <tt>
|
|
Derived</tt> proxy class will now implement both bases:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public class Derived implements Base1, Base2 {
|
|
...
|
|
public long Base1_GetInterfaceCPtr() {
|
|
return exampleJNI.Derived_Base1_GetInterfaceCPtr(swigCPtr);
|
|
}
|
|
|
|
public long Base2_GetInterfaceCPtr() {
|
|
return exampleJNI.Derived_Base2_GetInterfaceCPtr(swigCPtr);
|
|
}
|
|
|
|
public void Method1() {
|
|
exampleJNI.Derived_Method1(swigCPtr, this);
|
|
}
|
|
|
|
public void Method2() {
|
|
exampleJNI.Derived_Method2(swigCPtr, this);
|
|
}
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The proxy class has methods added to it, from the implemented bases,
|
|
so that the underlying C++ implementation can be called. In the example
|
|
above, <tt>Method1</tt> and <tt>Method2</tt> have been added from the
|
|
implemented bases. If a method is ignored in the base, such as via <tt>
|
|
%ignore</tt>, then that method will be excluded from the interface and
|
|
there will not be an additional method added to the proxy class
|
|
implementing that interface.</p>
|
|
<p> The Java interface only ever contains virtual and non-virtual
|
|
instance methods from the wrapped C++ class. Any static methods, enums
|
|
or variables in the wrapped C++ class are not supported and are not
|
|
added to the interface. They are of course still available in the Java
|
|
proxy class.</p>
|
|
<p> Wherever a class marked as an interface is used, such as the <tt>
|
|
UseBases</tt> method in the example, the interface name is used as the
|
|
type in the Java layer:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public static void UseBases(Base1 b1, Base2 b2) {
|
|
exampleJNI.UseBases(b1.Base1_GetInterfaceCPtr(), b1, b2.Base2_GetInterfaceCPtr(), b2);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Note that each Java interface has a method added to obtain the
|
|
correct C++ pointer for passing to the native function - <tt>
|
|
Base1_GetInterfaceCPtr</tt> for <tt>Base1</tt>. This method is similar
|
|
to the <tt>getCPtr</tt> method in the proxy classes. In fact, as shown
|
|
above in the <tt>Derived</tt> class, the proxy classes implement this
|
|
generated interface by calling a native method (<tt>
|
|
Derived_Base1_GetInterfaceCPtr</tt>) which calls an appropriate C++ cast
|
|
of the pointer up the inheritance chain.</p>
|
|
<p> The <tt>%interface_additional</tt> macro is useful for adding
|
|
additional interfaces to the Java interface class. Consider a simple
|
|
class hierarchy, where <tt>Whizz</tt> inherits from <tt>Bang</tt> and
|
|
we want these two classes to be wrapped as Java interfaces and the <tt>
|
|
Whizz</tt> interface to additionally extend from the pure Java interface
|
|
<tt>java.util.EventListener</tt>.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%interface_custom("Bang", "IBang", Space::Bang);
|
|
%interface_additional("Whizz", "IWhizz", "java.util.EventListener", Space::Whizz)
|
|
|
|
namespace Space {
|
|
struct Bang {
|
|
virtual void bang() = 0;
|
|
};
|
|
struct Whizz : Bang {
|
|
virtual void whizz() = 0;
|
|
};
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The classes and interfaces generated are shown below, noting that <tt>
|
|
IWhizz</tt> extends the additional interface <tt>java.util.EventListener</tt>
|
|
:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public interface IBang { ... }
|
|
|
|
public interface IWhizz extends java.util.EventListener, IBang { ... }
|
|
|
|
public class Bang implements IBang { ... }
|
|
|
|
public class Whizz implements IWhizz, IBang { ... }
|
|
</pre>
|
|
</div>
|
|
<p> Note the subtle difference to the <tt>javainterfaces</tt> typemap
|
|
discussed elsewhere. The typemap applies to the generated Java proxy
|
|
class only, not the Java interface. A slight change to our example
|
|
above as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%interface_custom("Bang", "IBang", Space::Bang);
|
|
%interface_custom("Whizz", "IWhizz", Space::Whizz)
|
|
%typemap(javainterfaces) Space::Whizz "java.util.EventListener"
|
|
|
|
namespace Space {
|
|
... as shown above ...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> will then the generate different code for the proxy class <tt>Whizz</tt>
|
|
and the interface <tt>IWhizz</tt> as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public interface IBang { ... }
|
|
|
|
public interface IWhizz extends IBang { ... }
|
|
|
|
public class Bang implements IBang { ... }
|
|
|
|
public class Whizz implements IWhizz, IBang, java.util.EventListener { ... }
|
|
|
|
</pre>
|
|
</div>
|
|
<p> Finally, a note on the implementation of the interface macros. The
|
|
interface macros are implemented using the <tt>interface</tt> feature
|
|
and typemaps. A couple of examples:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%define %interface(CTYPE...)
|
|
%feature("interface", name="%sSwigInterface") CTYPE;
|
|
INTERFACE_TYPEMAPS(CTYPE)
|
|
%enddef
|
|
|
|
%define %interface_additional(PROXY, INTERFACE, ADDITIONAL, CTYPE...)
|
|
%rename(PROXY) CTYPE;
|
|
%feature("interface", name=INTERFACE, additional=ADDITIONAL) CTYPE;
|
|
INTERFACE_TYPEMAPS(CTYPE)
|
|
%enddef
|
|
</pre>
|
|
</div>
|
|
<p> The feature accepts two attributes named <tt>name</tt> and <tt>
|
|
additional</tt>. The <tt>name</tt> attribute should contain the name of
|
|
the Java interface. The <tt>additional</tt> attribute should contain
|
|
additional interfaces for the interface class, not parsed by SWIG. The <tt>
|
|
INTERFACE_TYPEMAPS</tt> macro implements the typemaps and can be viewed
|
|
in the <tt>swiginterface.i</tt> file and contains the usual Java
|
|
typemaps for generating code plus the <tt>javainterfacecode</tt>
|
|
typemap which is only used when a class is marked with the <tt>
|
|
interface</tt> feature. See <a href="#Java_code_typemaps">Java code
|
|
typemaps</a> for details.</p>
|
|
<p><b> Compatibility note:</b> The <tt>additional</tt> attribute and <tt>
|
|
%interface_additional</tt> macro was added in SWIG-4.3.0.</p>
|
|
<h2><a name="Java_directors">27.5 Cross language polymorphism using
|
|
directors</a></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">27.5.1 Enabling directors</a></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 the virtual methods in class Foo
|
|
%feature("director") Foo;
|
|
</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 the 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">27.5.2 Director classes</a></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). Virtual methods that have a final specifier
|
|
are unsurprisingly excluded. Thus the 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">27.5.3 Overhead and code bloat</a></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">27.5.4 Simple directors example</a></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 intermediary class marshal and convert arguments
|
|
between C++ and Java when needed.</p>
|
|
<div class="code">
|
|
<pre>
|
|
class DirectorDerived extends DirectorBase {
|
|
@Override
|
|
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">27.5.5 Director threading issues</a>
|
|
</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>
|
|
<h3><a name="Java_directors_performance">27.5.6 Director performance
|
|
tuning</a></h3>
|
|
<p> When a new instance of a director (or subclass) is created in Java,
|
|
the C++ side of the director performs a runtime check per director
|
|
method to determine if that particular method is overridden in Java or
|
|
if it should invoke the C++ base implementation directly. Although this
|
|
makes initialization slightly more expensive, it is generally a good
|
|
overall tradeoff.</p>
|
|
<p> However, if all director methods are expected to usually be
|
|
overridden by Java subclasses, then initialization can be made faster
|
|
by avoiding these checks via the <tt>assumeoverride</tt> attribute. For
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director", assumeoverride=1) Foo;
|
|
</pre>
|
|
</div>
|
|
<p> The disadvantage is that invocation of director methods from C++
|
|
when Java doesn't actually override the method will require an
|
|
additional call up into Java and back to C++. As such, this option is
|
|
only useful when overrides are extremely common and instantiation is
|
|
frequent enough that its performance is critical.</p>
|
|
<h3><a name="Java_exceptions_from_directors">27.5.7 Java exceptions from
|
|
directors</a></h3>
|
|
<p> With directors routing method calls to Java, and proxies routing
|
|
them to C++, the handling of exceptions is an important concern. The
|
|
default behavior for Java exceptions thrown in a director method
|
|
overridden in Java is to store the thrown Java exception into a SWIG
|
|
defined <code>Swig::DirectorException</code> C++ class exception in the
|
|
C++ layer and then throw this C++ exception.</p>
|
|
<p> Of course, should this exception be thrown, your C++ code must catch
|
|
it and handle it before returning back to Java. The default generated
|
|
code<b> does not</b> attempt to handle the C++ exception, but there is
|
|
a simple way to make this all work by catching the C++ exception and
|
|
extracting the original Java exception by using <tt>%catches</tt> for <tt>
|
|
Swig::DirectorException</tt>. Consider the example shown earlier with a
|
|
modification to the <tt>upcall_method</tt> Java method to throw a Java
|
|
exception:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class DirectorDerived extends DirectorBase {
|
|
@Override
|
|
public void upcall_method() {
|
|
System.out.println("DirectorDerived.upcall_method() invoked.");
|
|
throw new RuntimeException("There was a problem!");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Now, by default, the JVM will abort when <tt>
|
|
example.callup(director)</tt> is called as the C++ <tt>
|
|
Swig::DirectorException</tt> (storing the Java exception) is thrown and
|
|
not handled by the <tt>callup</tt> method. Needless to say this is not
|
|
very user friendly and so the recommendation is to add the following
|
|
simple <tt>%catches</tt> directive before SWIG parses the <tt>callup</tt>
|
|
function:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%catches(Swig::DirectorException) callup;
|
|
</pre>
|
|
</div>
|
|
<p> Or target all wrapped methods using:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%catches(Swig::DirectorException);
|
|
</pre>
|
|
</div>
|
|
<p> This tells SWIG to generate a C++ catch handler using some code from
|
|
the <a href="#Typemaps_throws_typemap">throws typemap</a> for <tt>
|
|
Swig::DirectorException</tt> that SWIG supplies by default, see <a href="#SWIGPlus_catches">
|
|
Exception handling with %catches</a>. This typemap code is written to
|
|
simply catch the C++ <tt>Swig::DirectorException</tt> class and
|
|
immediately return to Java throwing the original Java exception that it
|
|
has stored. The net result is a stack trace containing the original
|
|
Java exception including the location that the exception was thrown
|
|
from.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
DirectorDerived.upcall_method() invoked.
|
|
Exception in thread "main" java.lang.RuntimeException: There was a problem!
|
|
at DirectorDerived.upcall_method(runme.java:4)
|
|
at exampleJNI.SwigDirector_DirectorBase_upcall_method(exampleJNI.java:20)
|
|
at exampleJNI.callup(Native Method)
|
|
at example.callup(example.java:12)
|
|
at runme.main(runme.java:21)
|
|
</pre>
|
|
</div>
|
|
<p> More on the <tt>Swig::DirectorException</tt> class can be found in
|
|
the next section which details how to customize the handling of
|
|
director exceptions.</p>
|
|
<h4><a name="Java_customizing_director_exceptions">27.5.7.1 Customizing
|
|
director exceptions</a></h4>
|
|
<p> This section is for advanced customization of director exceptions.
|
|
The recommendation for most users is to use the simple <tt>%catches</tt>
|
|
directive described above as it should be sufficient for most users
|
|
needs.</p>
|
|
<p> The conversion of Java exceptions into C++ exceptions can be
|
|
customized in two different ways using the <code>director:except</code>
|
|
<a href="#Customization_features">feature</a>. In the first approach, a
|
|
code block is attached to each director method to handle the mapping of
|
|
Java exceptions into C++ exceptions. The code block is generated just
|
|
after the call up from the C++ director method into the overloaded
|
|
method in Java. Its primary function is to check if a Java exception
|
|
has been thrown and then handle it in C++. The example below converts a
|
|
<tt>java.lang.IndexOutOfBoundsException</tt> into a C++ <tt>
|
|
std::out_of_range</tt> exception and converts a user's Java <tt>
|
|
MyJavaException</tt> into a C++ <tt>MyCppException</tt> exception. If
|
|
the Java exception doesn't match either of these, a fallback <tt>
|
|
std::runtime_error</tt> C++ exception is thrown.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director:except") MyClass::dirmethod(int x) {
|
|
jthrowable $error = jenv->ExceptionOccurred();
|
|
if ($error) {
|
|
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
|
|
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
|
|
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyJavaException"))
|
|
throw MyCppException(Swig::JavaExceptionMessage(jenv, $error).message());
|
|
throw std::runtime_error("Unexpected exception thrown in MyClass::dirmethod");
|
|
}
|
|
}
|
|
|
|
class MyClass {
|
|
public:
|
|
/** Throws either a std::out_of_range or MyCppException on error */
|
|
virtual void dirmethod(int x);
|
|
virtual ~MyClass();
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> A few special variables are expanded within the <tt>director:except</tt>
|
|
feature.</p>
|
|
<ul>
|
|
<li> The special variable <tt>$error</tt> is expanded into a unique
|
|
variable name (swigerror) and should be used for the assignment of the
|
|
jthrowable exception that occurred.</li>
|
|
<li> The special variable <tt>$packagepath</tt> is replaced by the outer
|
|
package provided for SWIG generation by the -package option.</li>
|
|
<li> The special variable <tt>$directorthrowshandlers</tt> is not shown
|
|
above, but is replaced by applicable "directorthrows" typemap contents
|
|
(covered later in this section).</li>
|
|
<li> The special variable <tt>$null</tt> is not shown above, but is
|
|
replaced by a suitable default constructed object for returning from
|
|
the director method (or nothing if the director method has a void
|
|
return).</li>
|
|
</ul>
|
|
<p> Utility functions/classes in director.swg are provided to aid the
|
|
exception conversion as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
namespace Swig {
|
|
|
|
// Helper method to determine if a Java throwable matches a particular Java class type
|
|
// Note side effect of clearing any pending exceptions
|
|
bool ExceptionMatches(JNIEnv *jenv, jthrowable throwable, const char *classname);
|
|
|
|
// Helper class to extract the exception message from a Java throwable
|
|
class JavaExceptionMessage {
|
|
public:
|
|
JavaExceptionMessage(JNIEnv *jenv, jthrowable throwable);
|
|
|
|
// Return a C string of the exception message in the jthrowable passed in the constructor
|
|
// If no message is available, null_string is return instead
|
|
const char *message(const char *null_string =
|
|
"Could not get exception message in JavaExceptionMessage") const;
|
|
};
|
|
|
|
// C++ Exception class for handling Java exceptions thrown during a director method Java upcall
|
|
class DirectorException : public std::exception {
|
|
public:
|
|
|
|
// Construct exception from a Java throwable
|
|
DirectorException(JNIEnv *jenv, jthrowable throwable);
|
|
|
|
// More general constructor for handling as a java.lang.RuntimeException
|
|
DirectorException(const char *msg);
|
|
|
|
// Return exception message extracted from the Java throwable
|
|
const char *what() const throw();
|
|
|
|
// Reconstruct and raise/throw the Java Exception that caused the DirectorException
|
|
// Note that any error in the JNI exception handling results in a Java RuntimeException
|
|
void throwException(JNIEnv *jenv) const;
|
|
|
|
// Create and throw the DirectorException
|
|
static void raise(JNIEnv *jenv, jthrowable throwable) {
|
|
throw DirectorException(jenv, throwable);
|
|
}
|
|
};
|
|
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The utility function <code>Swig::ExceptionMatches</code> and class <code>
|
|
Swig::JavaExceptionMessage</code> are provided to simplify writing code
|
|
for wrappers that use the <code>director:except</code> feature. The
|
|
function <code>Swig::ExceptionMatches</code> matches the type of the <code>
|
|
jthrowable</code> thrown against a<b> fully qualified</b> JNI style
|
|
class name, such as <code>"java/lang/IOError"</code>. If the throwable
|
|
class is the same type, or derives from the given type, <code>
|
|
Swig::ExceptionMatches</code> will return true. Care must be taken to
|
|
provide the correct fully qualified name, since for wrapped exceptions
|
|
the generated proxy class will have an additional package
|
|
qualification, depending on the '-package' argument and use of the <a href="#Java_namespaces">
|
|
nspace feature</a>. The utility class <code>Swig::JavaExceptionMessage</code>
|
|
is a holder providing access to the message from the thrown Java
|
|
exception. The <code>message()</code> method returns the exception
|
|
message as a <code>const char *</code>, which is only valid during the
|
|
lifetime of the holder. Any code using this message needs to copy it,
|
|
for example into a std::string or a newly constructed C++ exception.</p>
|
|
<p> Using the first approach above to write handlers for a large number
|
|
of methods will require repetitive duplication of the <code>
|
|
director:except</code> feature code for each director method. To
|
|
mitigate this, a second approach is provided via typemaps in a fashion
|
|
analogous to the <a href="#Typemaps_throws_typemap">"throws" typemap</a>
|
|
. The "throws" typemap provides a way to map all the C++ exceptions
|
|
listed in a method's defined exceptions (either from a C++<em>
|
|
exception specification</em> or a <code>%catches</code> feature) into
|
|
Java exceptions. The "directorthrows" typemap provides the inverse
|
|
mapping and should contain code to convert a suitably matching Java
|
|
exception into a C++ exception. Only use this typemap if you wish to
|
|
write custom conversions of Java exceptions into C++ exceptions and
|
|
apply them to many different methods. The default handling which uses
|
|
the <code>Swig::DirectorException</code> class should otherwise meet
|
|
your needs.</p>
|
|
<p> The example below converts a Java <code>
|
|
java.lang.IndexOutOfBoundsException</code> exception to the typemap's
|
|
type, that is a <code>std::out_of_range</code> C++ exception:<div class="code">
|
|
<pre>
|
|
%typemap(directorthrows) std::out_of_range %{
|
|
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException")) {
|
|
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
|
|
}
|
|
%}
|
|
</pre>
|
|
</div></p>
|
|
<p> The "directorthrows" typemap is then used in conjunction with the <code>
|
|
director:except</code> feature if the <code>$directorthrowshandlers</code>
|
|
special variable is used in the code block. Consider the following,
|
|
which also happens to be the default:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director:except") %{
|
|
jthrowable $error = jenv->ExceptionOccurred();
|
|
if ($error) {
|
|
$directorthrowshandlers
|
|
Swig::DirectorException::raise(jenv, $error);
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> where <tt>Swig::DirectorException::raise</tt> is the helper method
|
|
to throw a C++ <tt>Swig::DirectorException</tt>, see above. The code
|
|
generated from the <code>director:except</code> feature has the <code>
|
|
$directorthrowshandlers</code> special variable replaced with the code
|
|
in the relevant "directorthrows" typemaps, for each and every exception
|
|
defined for the method. The relevant exceptions can be defined either
|
|
with a C++ exception specification or <code>%catches</code> as
|
|
described for the <a href="#Typemaps_throws_typemap">"throws" typemap</a>
|
|
.</p>
|
|
<p> Let's try and put all this together by considering the following
|
|
director method:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct X {
|
|
virtual void doSomething(int index) throw (std::out_of_range);
|
|
...
|
|
};
|
|
|
|
OR
|
|
|
|
%catches(std::out_of_range) X::doSomething;
|
|
struct X {
|
|
virtual void doSomething(int index);
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> When combined with the default <code>director:except</code> feature
|
|
and the "directorthrows" typemap above, the resulting code generated in
|
|
the director method after calling up to Java will be:</p>
|
|
<div class="code">
|
|
<pre>
|
|
jthrowable swigerror = jenv->ExceptionOccurred();
|
|
if (swigerror) {
|
|
if (Swig::ExceptionMatches(jenv, swigerror, "java/lang/IndexOutOfBoundsException")) {
|
|
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
|
|
}
|
|
Swig::DirectorException::raise(jenv, swigerror);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p><em> Note: Beware of using exception specifications as the SWIG
|
|
director methods will be generated with the same exception
|
|
specifications and if the director method throws an exception that is
|
|
not specified in the exception specifications list it is likely to
|
|
terminate your program. See the C++ standard for more details. Using
|
|
the %catches feature instead to define the handled exceptions does not
|
|
suffer this potential fate.</em></p>
|
|
<p>Because the default code generation maps any unhandled Java
|
|
exceptions to <code>Swig::DirectorException</code>, any director
|
|
methods that have exception specifications may cause program
|
|
termination as this exception class won't be in the exception
|
|
specifications list. You can avoid throwing <tt>Swig::DirectorException</tt>
|
|
by changing the default handling for all methods by adding a <tt>
|
|
director:except</tt> feature without any method name. For example, you
|
|
can just ignore them:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director:except") %{
|
|
jthrowable $error = jenv->ExceptionOccurred();
|
|
if ($error) {
|
|
$directorthrowshandlers
|
|
jenv->ExceptionClear();
|
|
return $null; // exception is ignored
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p>Alternatively an exception compatible with the existing director
|
|
method exception specifications can be thrown. Assuming that all
|
|
methods allow std::runtime_error to be thrown, the <code>return $null</code>
|
|
line above could be changed to:</p>
|
|
<div class="code">
|
|
<pre>
|
|
throw std::runtime_error(Swig::JavaExceptionMessage(jenv, $error).message());
|
|
</pre>
|
|
</div>
|
|
<p>In more complex situations, a separate <code>director:except</code>
|
|
feature may need to be attached to specific methods by providing a
|
|
method name to the <tt>director:except</tt> feature.</p>
|
|
<p>This is all no doubt quite hard to follow without seeing a full
|
|
example and some code. Below is a complete example demonstrating the
|
|
use of most of the exception customizations one can use, that is,
|
|
"directorthrows" and "throws" typemaps, %exception and %catches. See
|
|
the <a href="#Java_exception_handling">Exception handling with
|
|
%exception and %javaexception</a> section for more on converting C++
|
|
exceptions to Java exceptions. The example also has a user defined C++
|
|
exception class called <tt>MyNS::MyException</tt> and this is wrapped
|
|
as a Java exception. The director class being wrapped is <tt>MyClass</tt>
|
|
and the director method is called <tt>MyClass::dirmethod</tt>. A number
|
|
of <tt>std::cout</tt> calls have been added to help understand code
|
|
flow. You can copy the code below into an interface file and run SWIG
|
|
on it and examine the generated code.<div class="code">
|
|
<pre>
|
|
%module(directors="1") example
|
|
|
|
%{
|
|
#include <stdexcept>
|
|
#include <iostream>
|
|
%}
|
|
|
|
// Generic catch handler for all wrapped methods
|
|
%exception %{
|
|
try {
|
|
$action
|
|
} catch (const std::exception &e) {
|
|
std::cout << "Generic std::exception catch handler" << std::endl;
|
|
jclass clazz = jenv->FindClass("java/lang/RuntimeException");
|
|
jenv->ThrowNew(clazz, e.what());
|
|
return $null;
|
|
}
|
|
%}
|
|
|
|
// Expose C++ exception as a Java Exception by changing the Java base class and providing a getMessage()
|
|
%typemap(javabase) MyNS::MyException "java.lang.RuntimeException"
|
|
%rename(getMessage) MyNS::MyException::whatsup;
|
|
|
|
%inline %{
|
|
namespace MyNS {
|
|
class MyException {
|
|
std::string msg;
|
|
public:
|
|
MyException(const char *msg) : msg(msg) {}
|
|
const char * whatsup() const { return msg.c_str(); }
|
|
};
|
|
}
|
|
%}
|
|
|
|
%typemap(directorthrows) MyNS::MyException %{
|
|
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyException")) {
|
|
std::cout << "$1_type exception matched (directorthrows typemap)" << std::endl;
|
|
throw $1_type(Swig::JavaExceptionMessage(jenv, $error).message());
|
|
}
|
|
%}
|
|
|
|
%typemap(throws) MyNS::MyException %{
|
|
std::cout << "$1_type caught (throws typemap)" << std::endl;
|
|
jclass excep = jenv->FindClass("MyException");
|
|
if (excep) {
|
|
std::cout << "$1_type class found (throws typemap)" << std::endl;
|
|
jenv->ThrowNew(excep, $1.whatsup());
|
|
}
|
|
return $null;
|
|
%}
|
|
|
|
// These are the exceptions that the director method MyClass::dirmethod will have catch handlers for.
|
|
// Note that this is also a virtual method / director method and the C++ exceptions listed can be
|
|
// thrown after converting them from Java exceptions.
|
|
%catches(MyNS::MyException, Swig::DirectorException) MyClass::dirmethod;
|
|
|
|
// These are the exceptions that call_dirmethod C++ wrapper will have catch handlers for.
|
|
// Note that this is not a virtual method, hence not a director method.
|
|
%catches(MyNS::MyException, Swig::DirectorException) call_dirmethod;
|
|
|
|
%feature("director") MyClass;
|
|
|
|
%feature("director:except") MyClass::dirmethod(int x) {
|
|
jthrowable $error = jenv->ExceptionOccurred();
|
|
if ($error) {
|
|
std::cout << "Upcall finished, an exception was thrown in Java" << std::endl;
|
|
$directorthrowshandlers
|
|
std::cout << "Upcall finished, no exception conversion, throwing DirectorException" << std::endl;
|
|
Swig::DirectorException::raise(jenv, $error);
|
|
}
|
|
}
|
|
|
|
%inline %{
|
|
class MyClass {
|
|
public:
|
|
/** Throws either a std::out_of_range or MyException on error */
|
|
virtual void dirmethod(int x) {
|
|
if (x <= 0)
|
|
throw std::out_of_range("MyClass::dirmethod index is out of range");
|
|
else if (x == 1)
|
|
throw MyNS::MyException("MyClass::dirmethod some problem!");
|
|
}
|
|
virtual ~MyClass() {}
|
|
static void call_dirmethod(MyClass& c, int x) {
|
|
return c.dirmethod(x);
|
|
}
|
|
};
|
|
%}
|
|
</pre>
|
|
</div></p>
|
|
<p> The generated code for the <tt>call_dirmethod</tt> wrapper contains
|
|
the various exception handlers. The outer exception handler is from the
|
|
<tt>%exception</tt> directive and the others are from the "throws"
|
|
typemaps.</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIGEXPORT void JNICALL Java_exampleJNI_MyClass_1call_1dirmethod(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) {
|
|
...
|
|
try {
|
|
try {
|
|
MyClass::call_dirmethod(*arg1,arg2);
|
|
} catch(MyNS::MyException &_e) {
|
|
std::cout << "MyNS::MyException caught (throws typemap)" << std::endl;
|
|
jclass excep = jenv->FindClass("MyException");
|
|
if (excep) {
|
|
std::cout << "MyNS::MyException class found (throws typemap)" << std::endl;
|
|
jenv->ThrowNew(excep, (&_e)->whatsup());
|
|
}
|
|
return ;
|
|
|
|
} catch(Swig::DirectorException &_e) {
|
|
(&_e)->throwException(jenv);
|
|
return ;
|
|
}
|
|
} catch (const std::exception &e) {
|
|
std::cout << "Generic std::exception catch handler" << std::endl;
|
|
jclass clazz = jenv->FindClass("java/lang/RuntimeException");
|
|
jenv->ThrowNew(clazz, e.what());
|
|
return ;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The director method calling up to Java contains the exception
|
|
handling code from the "directorthrows" typemaps and <tt>
|
|
director:except</tt> feature.</p>
|
|
<div class="code">
|
|
<pre>
|
|
void SwigDirector_MyClass::dirmethod(int x) {
|
|
... [call up to Java using CallStaticVoidMethod]
|
|
jthrowable swigerror = jenv->ExceptionOccurred();
|
|
if (swigerror) {
|
|
std::cout << "Upcall finished, an exception was thrown in Java" << std::endl;
|
|
|
|
if (Swig::ExceptionMatches(jenv, swigerror, "MyException")) {
|
|
std::cout << "MyNS::MyException exception matched (directorthrows typemap)" << std::endl;
|
|
throw MyNS::MyException(Swig::JavaExceptionMessage(jenv, swigerror).message());
|
|
}
|
|
|
|
std::cout << "Upcall finished, no exception conversion, throwing DirectorException" << std::endl;
|
|
Swig::DirectorException::raise(jenv, swigerror);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Let's use the following Java class to override the director method.</p>
|
|
<div class="code">
|
|
<pre>
|
|
class DerivedClass extends MyClass {
|
|
@Override
|
|
public void dirmethod(int x) {
|
|
if (x < 0)
|
|
throw new IndexOutOfBoundsException("Index is negative");
|
|
else if (x == 0)
|
|
throw new MyException("MyException: bad dirmethod");
|
|
}
|
|
}
|
|
public class runme {
|
|
public static void main(String argv[]) {
|
|
System.loadLibrary("example");
|
|
... code snippets shown below ...
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Consider the output using the Java code in the four slightly
|
|
different scenarios below.</p>
|
|
<p> 1. Non-director C++ class is used, thus, no upcall to a Java
|
|
director method is made. A <tt>std::out_of_range</tt> exception is
|
|
thrown, which is derived from <tt>std::exception</tt>, and hence caught
|
|
by the generic exception handler in the <tt>call_dirmethod</tt>
|
|
wrapper. The Java code snippet and resulting output is:</p>
|
|
<div class="code">
|
|
<pre>
|
|
MyClass.call_dirmethod(new MyClass(), 0);
|
|
</pre>
|
|
</div><div class="shell">
|
|
<pre>
|
|
Generic std::exception catch handler
|
|
Exception in thread "main" java.lang.RuntimeException: MyClass::dirmethod index is out of range
|
|
at exampleJNI.MyClass_call_dirmethod(Native Method)
|
|
at MyClass.call_dirmethod(MyClass.java:57)
|
|
at runme.main(runme.java:14)
|
|
</pre>
|
|
</div>
|
|
<p> 2. Non-director C++ class again but this time the <tt>
|
|
MyNS::MyException</tt> class is thrown and caught:</p>
|
|
<div class="code">
|
|
<pre>
|
|
MyClass.call_dirmethod(new MyClass(), 1);
|
|
</pre>
|
|
</div><div class="shell">
|
|
<pre>
|
|
MyNS::MyException caught (throws typemap)
|
|
MyNS::MyException class found (throws typemap)
|
|
Exception in thread "main" MyException: MyClass::dirmethod some problem!
|
|
at exampleJNI.MyClass_call_dirmethod(Native Method)
|
|
at MyClass.call_dirmethod(MyClass.java:57)
|
|
at runme.main(runme.java:15)
|
|
</pre>
|
|
</div>
|
|
<p> 3. The <tt>DerivedClass</tt> director class is used so the upcall to
|
|
Java occurs, but it throws a Java <tt>MyException</tt>, which gets
|
|
converted into a C++ <tt>MyNS::MyException</tt>, then caught and
|
|
converted back into a Java <tt>MyException</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
MyClass.call_dirmethod(new DerivedClass(), 0);
|
|
</pre>
|
|
</div><div class="shell">
|
|
<pre>
|
|
Upcall finished, an exception was thrown in Java
|
|
MyNS::MyException exception matched (directorthrows typemap)
|
|
MyNS::MyException caught (throws typemap)
|
|
MyNS::MyException class found (throws typemap)
|
|
Exception in thread "main" MyException: MyException: bad dirmethod
|
|
at exampleJNI.MyClass_call_dirmethod(Native Method)
|
|
at MyClass.call_dirmethod(MyClass.java:57)
|
|
at runme.main(runme.java:16)
|
|
</pre>
|
|
</div>
|
|
<p> 4. The director class is used again, but this time the director
|
|
method throws a Java <tt>IndexOutOfBoundsException</tt> exception which
|
|
is converted into a C++ <tt>Swig::DirectorException</tt>, thrown and
|
|
caught again. This time the original Java exception is extracted from
|
|
the <tt>Swig::DirectorException</tt> and rethrown. Note that this
|
|
approach keeps the stack trace information of the original exception,
|
|
so it has the exact location of where the <tt>IndexOutOfBoundsException</tt>
|
|
exception was thrown. This is arguably an improvement over the approach
|
|
above that converts from a Java excepton to C++ exception and then back
|
|
to a new Java exception, losing the location of the original exception.</p>
|
|
<div class="code">
|
|
<pre>
|
|
MyClass.call_dirmethod(new DerivedClass(), -1);
|
|
</pre>
|
|
</div><div class="shell">
|
|
<pre>
|
|
Upcall finished, an exception was thrown in Java
|
|
Upcall finished, no exception conversion, throwing DirectorException
|
|
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index is negative
|
|
at DerivedClass.dirmethod(runme.java:5)
|
|
at exampleJNI.SwigDirector_MyClass_dirmethod(exampleJNI.java:23)
|
|
at exampleJNI.MyClass_call_dirmethod(Native Method)
|
|
at MyClass.call_dirmethod(MyClass.java:57)
|
|
at runme.main(runme.java:17)
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Java_protected_virtual_methods">27.5.8 Accessing virtual
|
|
protected methods</a></h3>
|
|
<p> By default, without enabling the director feature, protected methods
|
|
are not wrapped and so cannot be accessed from Java. When using
|
|
directors, the protected virtual methods are 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> Unfortunately the rules for classes in an inheritance chain when
|
|
changing the access specifiers in C++ are different to Java access
|
|
modifiers. They are similar, but, unlike in C+++, one cannot assign
|
|
weaker access modifiers in Java. Consider the following inheritance
|
|
chain and using directors to turn on wrapping protected methods:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director") BaseClass;
|
|
%feature("director") DerivedClass;
|
|
|
|
%inline %{
|
|
class BaseClass {
|
|
public:
|
|
virtual ~BaseClass();
|
|
virtual void baseMethod1();
|
|
virtual void baseMethod2();
|
|
protected:
|
|
virtual void baseMethod3();
|
|
virtual void baseMethod4();
|
|
};
|
|
|
|
class DerivedClass : public BaseClass {
|
|
public:
|
|
virtual ~DerivedClass();
|
|
virtual void baseMethod1();
|
|
protected:
|
|
virtual void baseMethod2();
|
|
virtual void baseMethod3();
|
|
public:
|
|
virtual void baseMethod4();
|
|
};
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> SWIG will generate Java access modifiers that are a one-to-one
|
|
mapping of the C++ access specifiers. So if a method is <tt>public</tt>
|
|
in C++ it will also be <tt>public</tt> in Java, and similarly <tt>
|
|
protected</tt> in C++ becomes <tt>protected</tt> in Java. This is fine
|
|
for all of the methods in the above example, except for the <tt>
|
|
DerivedClass.baseMethod2</tt>. The Java compiler issues an error:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
DerivedClass.java:69: error: baseMethod2() in DerivedClass cannot override baseMethod2() in BaseClass
|
|
protected void baseMethod2() {
|
|
^
|
|
attempting to assign weaker access privileges; was public
|
|
</pre>
|
|
</div>
|
|
<p> This requires fixing with one of two solutions:</p>
|
|
<ol>
|
|
<li>
|
|
<p>Change the access modifier to public for the derived class by adding
|
|
the following before SWIG parses the <tt>DerivedClass:</tt></p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("java:methodmodifiers") DerivedClass::baseMethod2 "public"
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>Simply ignore the method in the derived class altogether as it cannot
|
|
be used as a <tt>protected</tt> method in Java as the C++ design
|
|
intended:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%ignore DerivedClass::baseMethod2;
|
|
</pre>
|
|
</div></li>
|
|
</ol>
|
|
<h3><a name="Java_allprotected">27.5.9 Accessing non-virtual protected
|
|
members</a></h3>
|
|
<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="Java_common_customization">27.6 Common customization
|
|
features</a></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="Java_helper_functions">27.6.1 C/C++ helper functions</a></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="Java_class_extension">27.6.2 Class extension with %extend</a>
|
|
</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="Java_proxycode">27.6.3 Class extension with %proxycode</a></h3>
|
|
<p> The previous section described how to extend a wrapped class with C
|
|
or C++ code. This section describes how to extend a wrapped class with
|
|
Java code instead of C/C++ code. The <tt>%proxycode</tt> directive is
|
|
used and is just a macro for <tt>%insert("proxycode")</tt>. The <a href="#SWIG_nn42">
|
|
Code insertion block</a> section describes the <tt>%insert</tt>
|
|
directive. The section of code for insertion is "proxycode", that is,
|
|
the Java proxy class. This directive must hence only be used within the
|
|
scope of a class, otherwise it is silently ignored. There are two
|
|
common ways to get the scope correct.</p>
|
|
<p> The first is to use <tt>%proxycode</tt> inside a class that SWIG
|
|
parses, for example a <tt>toString()</tt> method can be added to a C++
|
|
class using pure Java code. A C++ header file can mix C++ and Java code
|
|
inside the C++ class as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// flag.h header file
|
|
class Flag {
|
|
bool flag;
|
|
public:
|
|
Flag(bool flag) : flag(flag) {}
|
|
bool FetchFlag() { return flag; }
|
|
#if defined(SWIG)
|
|
%proxycode %{
|
|
public String toString() {
|
|
boolean flag = FetchFlag();
|
|
return Boolean.toString(flag);
|
|
}
|
|
%}
|
|
#endif
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> and wrapped using:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
#include "flag.h"
|
|
%}
|
|
%include "flag.h"
|
|
</pre>
|
|
</div>
|
|
<p> The second is to use <tt>%proxycode</tt> within <tt>%extend</tt> as
|
|
everything within a <tt>%extend</tt> block is effectively within the
|
|
scope of the class, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// flag.h header file
|
|
class Flag {
|
|
bool flag;
|
|
public:
|
|
Flag(bool flag) : flag(flag) {}
|
|
bool FetchFlag() { return flag; }
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> and wrapped using:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
#include "flag.h"
|
|
%}
|
|
%include "flag.h"
|
|
|
|
%extend Flag {
|
|
#if defined(SWIG)
|
|
%proxycode %{
|
|
public String toString() {
|
|
boolean flag = FetchFlag();
|
|
return Boolean.toString(flag);
|
|
}
|
|
%}
|
|
#endif
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> There is some very limited support of typemaps within a <tt>
|
|
%proxycode</tt> block. A useful trick is to obtain the Java type for a
|
|
given C/C++ type using the <a href="#Typemaps_special_macro_typemap">
|
|
$typemap</a> special macro. The following C++ template demonstrates
|
|
this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%inline %{
|
|
template<typename T> struct Value {
|
|
T value;
|
|
Value(const T& val) : value(val) {}
|
|
};
|
|
%}
|
|
|
|
%extend Value {
|
|
%proxycode %{
|
|
public String toString() {
|
|
// Note template type expansion is supported, so T is expanded to 'unsigned int' in this example
|
|
// and $typemap(jstype, unsigned int) in turn is expanded to 'long'
|
|
$typemap(jstype, T) val = getValue();
|
|
return "$javaclassname value: " + val + " Java type: $typemap(jstype, T) JNI type: $typemap(jni, T)";
|
|
}
|
|
%}
|
|
}
|
|
%template(ValueUnsignedInt) Value<unsigned int>;
|
|
</pre>
|
|
</div>
|
|
<p> The generated Java contains the expanded special variable and macro
|
|
resulting in Java proxy code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public class ValueUnsignedInt {
|
|
...
|
|
public String toString() {
|
|
long val = getValue();
|
|
return "ValueUnsignedInt value: " + val + " Java type: long JNI type: jlong";
|
|
}
|
|
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Java_exception_handling">27.6.4 Exception handling with
|
|
%exception and %javaexception</a></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="#Customization_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="#Java_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="#Java_typemaps_for_c_and_cpp">
|
|
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="#Java_exception_typemap">Handling
|
|
C++ exception specifications as Java exceptions</a> provides further
|
|
exception handling capabilities.</p>
|
|
<h3><a name="Java_method_access">27.6.5 Method access with
|
|
%javamethodmodifiers</a></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>
|
|
<h3><a name="Java_begin">27.6.6 Java begin</a></h3>
|
|
<p> It is possible to add a common comment at the start of every
|
|
generated Java file. The <tt>%module</tt> directive supports the <tt>
|
|
javabegin</tt> option for this. The provided text is generated at the
|
|
very beginning of each generated .java file. As it is generated before
|
|
the package statement, is only really useful for adding in a common
|
|
comment into all generated .java files. For example, copyright text for
|
|
each file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(javabegin="/* Common comment. Copyright (C) 2000 Mr Nobody. */\n") nobodymodule
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Java_tips_techniques">27.7 Tips and techniques</a></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="Java_input_output_parameters">27.7.1 Input and output
|
|
parameters using primitive pointers and references</a></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="Java_simple_pointers">27.7.2 Simple pointers</a></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="Java_c_arrays">27.7.3 Wrapping C arrays with Java arrays</a>
|
|
</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="Java_unbounded_c_arrays">27.7.4 Unbounded C Arrays</a></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(size_t nelements);
|
|
void delete_intArray(int *x);
|
|
int intArray_getitem(int *x, size_t index);
|
|
void intArray_setitem(int *x, size_t 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_string_length">27.7.5 Passing a string with length</a></h3>
|
|
<p> SWIG provides multi-argument typemap available as mentioned in <a href="#Library_nn10">
|
|
Passing a string with length</a>. The following simple example
|
|
demonstrates passing a string to the wrapped function.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%apply (char *STRING, size_t LENGTH) { (const char data[], size_t len) }
|
|
%inline %{
|
|
void binaryChar1(const char data[], size_t len) {
|
|
printf("len: %d data: ", len);
|
|
for (size_t i=0; i<len; ++i)
|
|
printf("%x ", data[i]);
|
|
printf("\n");
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> Calling from Java requires a string to be passed in as the
|
|
multi-argument typemap being applied reduces the number of arguments in
|
|
the target language to one, from the original two:</p>
|
|
<div class="code">
|
|
<pre>
|
|
String str = "hi\0jk";
|
|
example.binaryChar1(str);
|
|
</pre>
|
|
</div>
|
|
<p> resulting in the output</p>
|
|
<div class="code">
|
|
<pre>
|
|
$ java runme
|
|
len: 5 data: 68 69 0 6a 6b
|
|
</pre>
|
|
</div>
|
|
<p> The typemap uses Java <tt>String::getBytes()</tt> to convert the
|
|
string to the default system encoding. If you wish to use another
|
|
encoding, you can modify the typemap. For example to convert the string
|
|
to UTF-8 use:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(javain, throws="java.io.IllegalCharsetNameException")
|
|
<br>
|
|
(const char *STRING, size_t LENGTH) %{($javainput == null) ? null : $javainput.getBytes("UTF-8")%}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Java_heap_allocations">27.7.6 Overriding new and delete to
|
|
allocate from Java heap</a></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">27.8 Java typemaps</a></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 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="https://www.oracle.com/technetwork/java/index.html">
|
|
the 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="Java_default_primitive_type_mappings">27.8.1 Default
|
|
primitive type mappings</a></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>size_t
|
|
<br> const size_t &</td><td>long</td><td>jlong</td></tr>
|
|
<tr><td>char *
|
|
<br>char []</td><td>String</td><td>jstring</td></tr>
|
|
</table>
|
|
<p> Note that default mappings for the C long type is more suitable for
|
|
32-bit systems. If long is 64-bit, the full range can be obtained by
|
|
defining <tt>SWIGWORDSIZE64</tt> when invoking SWIG. The long type will
|
|
instead be mapped as follows:</p>
|
|
<table BORDER summary="SWIGWORDSIZE64 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>long
|
|
<br> const long &</td><td>long</td><td>jlong</td></tr>
|
|
<tr><td>unsigned long
|
|
<br>const unsigned long &</td><td>java.math.BigInteger</td><td>jobject</td>
|
|
</tr>
|
|
</table>
|
|
<p> Note that when size_t is 64-bit in C, the full unsigned range is not
|
|
available. This can be fixed by applying the 64-bit unsigned long long
|
|
typemaps as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%apply unsigned long long { size_t };
|
|
%apply const unsigned long long & { const size_t & };
|
|
</pre>
|
|
</div>
|
|
<p> The net effect then changes from the default shown earlier to:</p>
|
|
<table BORDER summary="64-bit size_t 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>size_t
|
|
<br> const size_t &</td><td>java.math.BigInteger</td><td>jobject</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">27.8.2 Default
|
|
typemaps for non-primitive types</a></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="Java_jvm64">27.8.3 Sixty four bit JVMs</a></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="Java_what_is_typemap">27.8.4 What is a typemap?</a></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="Java_typemaps_c_to_java_types">27.8.5 Typemaps for mapping
|
|
C/C++ types to Java types</a></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>jboxtype</td><td>Java boxed type. These are Java code typemaps
|
|
to provide the Java boxed type, such as, <tt>Integer</tt> for C type <tt>
|
|
int</tt>. As autoboxing is only relevant to the Java primitive types,
|
|
these are only provided for the C types that map to Java primitive
|
|
types. This typemap is usually only used by C++ STL container wrappers
|
|
that are wrapped by Java generic types as the boxed type must be used
|
|
instead of the unboxed/primitive type when declaring a Java generic
|
|
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="#Java_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="#Java_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.
|
|
<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.
|
|
<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.
|
|
<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>
|
|
<tr><td>unsigned char *</td><td>NIOBUFFER</td><td>various.i</td><td>
|
|
input
|
|
<br> output</td><td>java.nio.Buffer</td><td>Use for mapping directly
|
|
allocated buffers to c/c++. useful with directors and long lived memory
|
|
objects</td></tr>
|
|
</td></tr>
|
|
</td></tr>
|
|
</td></tr>
|
|
</table>
|
|
<h3><a name="Java_typemap_attributes">27.8.6 Java typemap attributes</a></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="#Java_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="#Java_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="#Java_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="Java_special_variables">27.8.7 Java special variables</a></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>. The class name is fully qualified with the package name
|
|
when using the <a href="#SWIGPlus_nspace">nspace feature</a>.</p>
|
|
<p><b> <tt>$javaclazzname</tt></b>
|
|
<br> This special variable works like <tt>$javaclassname</tt>, but
|
|
expands the fully qualified C++ class into the package name, if used by
|
|
the <a href="#SWIGPlus_nspace">nspace feature</a>, and the proxy class
|
|
name, mangled for use as a function name. For example, <tt>
|
|
Namespace1::Namespace2::Klass</tt> is expanded into <tt>
|
|
Namespace1_Namespace2_Klass_</tt>. This special variable is usually used
|
|
for making calls to a function in the intermediary JNI class, as they
|
|
are mangled with this prefix.</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>$error, $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>
|
|
<p><b> <tt>$imfuncname</tt></b>
|
|
<br> This special variable expands to the name of the function in the
|
|
intermediary class that will be used in $jnicall. Like, $jnicall, this
|
|
special variable is only expanded in the "javaout" typemap.</p>
|
|
<p><b> <tt>$javainterfacename</tt></b>
|
|
<br> This special variable is only expanded when the <tt>interface</tt>
|
|
feature is applied to a class. It works much like <tt>$javaclassname</tt>
|
|
, but instead of expanding to the proxy classname, it expands to the
|
|
value in the <tt>name</tt> attribute in the <tt>interface</tt> feature.
|
|
For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("interface", name="MyInterface") MyClass;
|
|
%typemap(jstype) MyClass "$&javainterfacename"
|
|
%typemap(jstype) MyClass * "$javainterfacename"
|
|
</pre>
|
|
</div>
|
|
<p> will result in the <tt>jstype</tt> typemap expanding to <tt>
|
|
MyInterface</tt> for both <tt>MyClass</tt> and <tt>MyClass *</tt>. The
|
|
interface name is fully qualified with the package name when using the <a
|
|
href="#SWIGPlus_nspace">nspace feature</a>.</p>
|
|
<p><b> <tt>$interfacename</tt></b>
|
|
<br> This special variable is only expanded when the <tt>interface</tt>
|
|
feature is applied to a class. It expands to just the interface name
|
|
and is thus different to <tt>$javainterfacename</tt> in that it is not
|
|
fully qualified with the package name when using the <a href="#SWIGPlus_nspace">
|
|
nspace feature</a>.</p>
|
|
<h3><a name="Java_typemaps_for_c_and_cpp">27.8.8 Typemaps for both C and
|
|
C++ compilation</a></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">27.8.9 Java code typemaps</a></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 As there can only be one "javacode" typemap per class,
|
|
also consider using the <a href="#Java_proxycode">%proxycode</a>
|
|
directive which can be used multiple times per class and offers nearly
|
|
identical functionality.</div>
|
|
<p><tt>%typemap(javadestruct, methodname="delete",
|
|
methodmodifiers="public synchronized", parameters="")</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. If a <tt>
|
|
%javamethodmodifiers</tt> is attached to the class' destructor, it will
|
|
be used in preference to the <tt>methodmodifiers</tt> typemap attribute
|
|
for the class. The <tt>delete</tt> method's parameters declaration can
|
|
be provided in the optional <tt>parameters</tt> typemap attribute.</div>
|
|
<p><tt>%typemap(javadestruct_derived, methodname="delete",
|
|
methodmodifiers="public synchronized", parameters="")</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. If a <tt>
|
|
%javamethodmodifiers</tt> is attached to the class' destructor, it will
|
|
be used in preference to the <tt>methodmodifiers</tt> typemap attribute
|
|
for the class. The <tt>delete</tt> method's parameters declaration can
|
|
be provided in the optional <tt>parameters</tt> typemap 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 (implements) 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
|
|
<p> Note that the default javafinalize typemap must contain the full
|
|
implementation of the finalize method. Any customization to this
|
|
typemap must still declare a java finalize method with the correct
|
|
signature. Note also that the name of the generated "delete" method may
|
|
be affected by <tt>javadestruct</tt> and <tt>javadestruct_derived</tt>
|
|
typemaps. Below shows an example modifying the finalizer, assuming the <tt>
|
|
delete</tt> method has been renamed to <tt>swig_delete</tt>.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(javafinalize) SWIGTYPE %{
|
|
protected void finalize() {
|
|
swig_delete(); // renamed to prevent conflict with existing delete method
|
|
}
|
|
]%
|
|
</pre>
|
|
</div></div>
|
|
<p><tt>%typemap(javainterfacemodifiers)</tt></p>
|
|
<div class="indent"> Interface modifiers for the Java interface
|
|
generated when using the <tt>interface</tt> feature, see <a href="#Java_interfaces">
|
|
Java interfaces</a> section. The default is "public interface".
|
|
<p><b> Compatibility note:</b> This typemap was added in SWIG-4.1.0.</p>
|
|
</div>
|
|
<p><tt>%typemap(javainterfacecode, declaration="...", cptrmethod="...")</tt>
|
|
</p>
|
|
<div class="indent">
|
|
<p> The code in this typemap is added to the body of a Java proxy class
|
|
but only when a class is marked with the <tt>interface</tt> feature.
|
|
The typemap is used in the proxy class marked with the interface
|
|
feature as well as all proxy classes derived from the marked C++ class,
|
|
as they are all generated as implementing the Java interface. The
|
|
default typemap used in the <tt>%interface</tt> family of macros
|
|
mentioned in the <a href="#Java_interfaces">Java interfaces</a>
|
|
section, where <tt>CTYPE</tt> is the C++ class macro argument, is as
|
|
follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(javainterfacecode,
|
|
declaration=" long $interfacename_GetInterfaceCPtr();\n",
|
|
cptrmethod="$interfacename_GetInterfaceCPtr") CTYPE %{
|
|
public long $interfacename_GetInterfaceCPtr() {
|
|
return $imclassname.$javaclazzname$interfacename_GetInterfaceCPtr(swigCPtr);
|
|
}
|
|
%}
|
|
</pre>
|
|
</div></div>
|
|
<p> The special variable <tt>$interfacename</tt> is expanded into the
|
|
name specified in the <tt>interface</tt> feature.</p>
|
|
<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. The <tt>javainterfacecode</tt> typemap and interface feature
|
|
was introduced in SWIG-3.0.9.</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 ]
|
|
[ javainterfacecode 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 <tt>javainterfacecode</tt> typemap is only used when bases are
|
|
marked by the <tt>interface</tt> feature and the <tt>implements</tt>
|
|
list will also then be expanded to include these Java interfaces.</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 Java interface turned on by the <tt>interface</tt> feature is
|
|
fairly simple:</p>
|
|
<div class="code">
|
|
<pre>
|
|
[ javaimports typemap ]
|
|
[ javainterfacemodifiers typemap ] [ name ] [extends additional [, ...] ] {
|
|
[ javainterfacecode:cptrmethod typemap attribute ]
|
|
... interface declarations ...
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> where <tt>name</tt> is the <tt>name</tt> attribute and <tt>
|
|
additional</tt> is the <tt>additional</tt> attribute in the <a href="#Java_interfaces">
|
|
interface feature</a>.</p>
|
|
<p> The defaults can be overridden to tailor the generated classes. Here
|
|
is an example which will change the <tt>getCPtr</tt> method and
|
|
constructor from the default public access to protected access. If the
|
|
classes in one package are not using the classes in another package,
|
|
then these methods need not be public and removing access to these low
|
|
level implementation details, is a good thing. If you are invoking SWIG
|
|
more than once and generating the wrapped classes into different
|
|
packages in each invocation, then you cannot do this as you will then
|
|
have different packages.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(javabody) SWIGTYPE %{
|
|
private transient long swigCPtr;
|
|
protected transient boolean swigCMemOwn;
|
|
|
|
protected $javaclassname(long cPtr, boolean cMemoryOwn) {
|
|
swigCMemOwn = cMemoryOwn;
|
|
swigCPtr = cPtr;
|
|
}
|
|
|
|
protected 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 last 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 transient long swigCPtr;
|
|
|
|
protected $javaclassname(long cPtr, boolean bFutureUse) {
|
|
swigCPtr = cPtr;
|
|
}
|
|
|
|
protected $javaclassname() {
|
|
swigCPtr = 0;
|
|
}
|
|
|
|
protected 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>
|
|
<p> When using <a href="#Modules">multiple modules</a> or the <a href="#Java_namespaces">
|
|
nspace feature</a> it is common to invoke SWIG with a different <tt>
|
|
-package</tt> command line option for each module. However, by default
|
|
the generated code may not compile if generated classes in one package
|
|
use generated classes in another package. The visibility of the <tt>
|
|
getCPtr()</tt> and pointer constructor generated from the <tt>javabody</tt>
|
|
typemaps needs changing. The default visibility is <tt>protected</tt>
|
|
but it needs to be <tt>public</tt> for access from a different package.
|
|
Just changing 'protected' to 'public' in the typemap achieves this. Two
|
|
macros are available in <tt>java.swg</tt> to make this easier and using
|
|
them is the preferred approach over simply copying the typemaps and
|
|
modifying as this is forward compatible with any changes in the <tt>
|
|
javabody</tt> typemap in future versions of SWIG. The macros are for the
|
|
proxy and typewrapper classes and can respectively be used to to make
|
|
the method and constructor public:</p>
|
|
<div class="code">
|
|
<pre>
|
|
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
|
|
SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Java_directors_typemaps">27.8.10 Director specific typemaps</a>
|
|
</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 used in director methods.</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;", noblock=1) char * {
|
|
$input = 0;
|
|
if ($1) {
|
|
$input = JCALL1(NewStringUTF, jenv, (const char *)$1);
|
|
if (!$input) return $null;
|
|
}
|
|
Swig::LocalRefGuard $1_refguard(jenv, $input);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>Swig::LocalRefGuard</tt> class should be used in directorin
|
|
typemaps for newly allocated objects. It is used to control local
|
|
reference counts ensuring the count is decremented after the call up
|
|
into Java has completed. Its destructor simply calls <tt>
|
|
jenv->DeleteLocalRef(obj)</tt> on the <tt>obj</tt> passed in during
|
|
construction.</p>
|
|
<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. Note that the <code>
|
|
$packagepath</code> substitution always uses the path separator '/' when
|
|
expanded. The <code>$javaclassname</code> expansion can be confusing as
|
|
it is normally expanded using the '.' separator. However, <code>
|
|
$javaclassname</code> is expanded using the path separator '/' in
|
|
typemap's "descriptor" attribute as well as in the "directorthrows"
|
|
typemap.</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(directorthrows)</tt></p>
|
|
<div class="indent">
|
|
<p> Conversion of Java exceptions to C++ exceptions in director method's
|
|
exception handling. This typemap is expected to test the <tt>$error</tt>
|
|
special variable for a matching Java exception and if successful
|
|
convert and throw it into a C++ exception given by the typemap's type.
|
|
The <code>$error</code> special variable is of type <code>jthrowable</code>
|
|
and is substituted with a unique variable name in the generated code.</p>
|
|
<p> The example below converts a Java <code>
|
|
java.lang.IndexOutOfBoundsException</code> exception to the typemap's
|
|
type, that is <code>std::out_of_range</code>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(directorthrows) std::out_of_range %{
|
|
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException")) {
|
|
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The utility function <code>Swig::ExceptionMatches</code> and class <code>
|
|
Swig::JavaExceptionMessage</code> are helpers available when using
|
|
directors and are described in the <a href="#Java_exceptions_from_directors">
|
|
Java Exceptions from Directors</a> section.</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.
|
|
The typemap is only used if the type is used in a director method, that
|
|
is, in a virtual method in a director class. 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();
|
|
virtual 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();
|
|
virtual 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="Java_typemap_examples">27.9 Typemap Examples</a></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="Java_simpler_enum_classes">27.9.1 Simpler Java enums for
|
|
enums without initializers</a></h3>
|
|
<p> The default <a href="#Java_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="Java_exception_typemap">27.9.2 Handling C++ exception
|
|
specifications as Java exceptions</a></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="Typemaps.html#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="#Java_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="Java_nan_exception_typemap">27.9.3 NaN Exception -
|
|
exception handling for a particular type</a></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="#Java_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="Java_converting_java_string_arrays">27.9.4 Converting Java
|
|
String arrays to char **</a></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="Java_expanding_java_object">27.9.5 Expanding a Java object
|
|
to multiple arguments</a></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="Java_using_typemaps_return_arguments">27.9.6 Using typemaps
|
|
to return arguments</a></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="Java_adding_downcasts">27.9.7 Adding Java downcasts to
|
|
polymorphic return types</a></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="Java_adding_equals_method">27.9.8 Adding an equals method
|
|
to the Java classes</a></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="Java_void_pointers">27.9.9 Void pointers and a common Java
|
|
base class</a></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="Java_struct_pointer_pointer">27.9.10 Struct pointer to
|
|
pointer</a></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">27.9.11 Memory
|
|
management when returning references to member variables</a></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 = 0) : 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">27.9.12 Memory management
|
|
for objects passed to the C++ layer</a></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 occurring...</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;
|
|
|
|
public void setElement(Element e) {
|
|
exampleJNI.Container_setElement(swigCPtr, this, Element.getCPtr(e), e);
|
|
elementReference = e;
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> The following typemaps can be used to generate this code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%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;
|
|
%}
|
|
|
|
%typemap(javain,
|
|
post=" elementReference = $javainput;"
|
|
) Element *e "Element.getCPtr($javainput)"
|
|
</pre>
|
|
</div>
|
|
<p> The 'javacode' typemap simply adds in the specified code into the
|
|
Java proxy class. The 'javain' typemap matches the input parameter type
|
|
and name for the <tt>setElement</tt> method and the 'post' typemap
|
|
attribute allows adding code after the JNI call. The 'post' code is
|
|
generated into a finally block after the JNI call so the resulting code
|
|
isn't quite as mentioned earlier, <tt>setElement</tt> is actually:</p>
|
|
<div class="code">
|
|
<pre>
|
|
public void setElement(Element e) {
|
|
try {
|
|
exampleJNI.Container_setElement(swigCPtr, this, Element.getCPtr(e), e);
|
|
} finally {
|
|
elementReference = e;
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Java_date_marshalling">27.9.13 Date marshalling using the
|
|
javain typemap and associated attributes</a></h3>
|
|
<p> The <a href="#Java_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 modified 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">27.10 Living with Java Directors</a></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="Java_odds_ends">27.11 Odds and ends</a></h2>
|
|
<h3><a name="Java_javadoc_comments">27.11.1 JavaDoc comments</a></h3>
|
|
<p> SWIG can translate <a href="https://doxygen.org/">Doxygen</a>
|
|
comments in the C/C++ headers being wrapped to JavaDoc. For details of
|
|
this, see the <a href="Doxygen.html#Doxygen_to_javadoc">Doxygen to
|
|
Javadoc</a> section.</p>
|
|
<p> If you don't have Doxygen comments to translate then it's possible
|
|
to add JavaDoc comments from your interface file. 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="Java_functional_interface">27.11.2 Functional interface
|
|
without proxy classes</a></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="Java_using_own_jni_functions">27.11.3 Using your own JNI
|
|
functions</a></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> Note that if you're wanting to effectively<b> replace</b> the JNI
|
|
code generated for a C/C++ function then you'll need to use <tt>%ignore</tt>
|
|
as well to tell SWIG not to automatically generate a JNI wrapper for
|
|
it.</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="Java_performance">27.11.4 Performance concerns and hints</a>
|
|
</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">27.11.5 Debugging</a></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 notable 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 overridden 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">27.12 Java Examples</a></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="Javascript">28 SWIG and Javascript</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Javascript_overview">Overview</a></li>
|
|
<li><a href="#Javascript_preliminaries">Preliminaries</a>
|
|
<ul>
|
|
<li><a href="#Javascript_running_swig">Running SWIG</a></li>
|
|
<li><a href="#Javascript_running_tests_examples">Running Tests and
|
|
Examples</a></li>
|
|
<li><a href="#Javascript_known_issues">Known Issues</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Javascript_integration">Integration</a>
|
|
<ul>
|
|
<li><a href="#Javascript_node_extensions">Creating node.js Extensions</a>
|
|
<ul>
|
|
<li><a href="#Javascript_using_yeoman">Using <code>yeoman</code> to
|
|
generate a Node-API skeleton</a></li>
|
|
<li><a href="#Javascript_troubleshooting">Troubleshooting</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Javascript_embedded_webkit">Embedded Webkit</a>
|
|
<ul>
|
|
<li><a href="#Javascript_osx">Mac OS X</a></li>
|
|
<li><a href="#Javascript_gtk">GTK</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Javascript_applications_webkit">Creating Applications with
|
|
node-webkit</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Javascript_examples">Examples</a>
|
|
<ul>
|
|
<li><a href="#Javascript_simple_example">Simple</a></li>
|
|
<li><a href="#Javascript_class_example">Class</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Javascript_implementation">Implementation</a>
|
|
<ul>
|
|
<li><a href="#Javascript_source_code">Source Code</a></li>
|
|
<li><a href="#Javascript_code_templates">Code Templates</a></li>
|
|
<li><a href="#Javascript_emitter">Emitter</a></li>
|
|
<li><a href="#Javascript_emitter_states">Emitter states</a></li>
|
|
<li><a href="#Javascript_jsc_exceptions">Handling Exceptions in
|
|
JavascriptCore</a></li>
|
|
<li><a href="#Javascript_napi_exceptions">Handling Exceptions in
|
|
Node-API</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p>This chapter describes SWIG's support of Javascript. It does not
|
|
cover SWIG basics, but only information that is specific to this
|
|
module.</p>
|
|
<h2><a name="Javascript_overview">28.1 Overview</a></h2>
|
|
<p>Javascript is a prototype-based scripting language that is dynamic,
|
|
weakly typed and has first-class functions. Its arguably the most
|
|
popular language for web development. Javascript has gone beyond being
|
|
a browser-based scripting language and can be used as a backend
|
|
development language with <a href="https://nodejs.org">node.js</a>.</p>
|
|
<p>Native Javascript extensions can be used for applications that embed
|
|
a web-browser view or that embed a Javascript engine (such as<em>
|
|
node.js</em>). Extending a general purpose web-browser is not possible
|
|
as this would be a severe security issue.</p>
|
|
<p>SWIG/Javascript currently supports:</p>
|
|
<ul>
|
|
<li><strong>Node.js</strong> 12 or later. SWIG can optionally generate
|
|
Node-API code, which needs Node.js 12.17 or later.</li>
|
|
<li><strong>JavascriptCore</strong> 4.0 or later. JavascriptCore is used
|
|
by Safari/Webkit</li>
|
|
<li><a href="https://v8.dev/"><strong>v8</strong></a> 7.4 or later (we
|
|
currently CI test with 7.8 and 10.2). v8 is used by Chromium and
|
|
Node.js.</li>
|
|
</ul>
|
|
<p><a href="https://webkit.org/">WebKit</a> is a modern browser
|
|
implementation available as open-source which can be embedded into an
|
|
application. <a href="https://github.com/nwjs/nw.js">NW.jst</a>
|
|
provides an app runtime which uses Google's Chromium as Web-Browser
|
|
widget and node.js for javascript extensions.</p>
|
|
<h2><a name="Javascript_preliminaries">28.2 Preliminaries</a></h2>
|
|
<h3><a name="Javascript_running_swig">28.2.1 Running SWIG</a></h3>
|
|
<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 Javascript module, run SWIG using the <code>-javascript</code>
|
|
option and a desired target engine <code>-jsc</code>, <code>-v8</code>,
|
|
<code>-node</code> or <code>-napi</code>. <code>-v8</code> allows for
|
|
interfacing with a raw embedded version of V8. In this case, it is up
|
|
to the user to implement a binary module loading protocol. There are
|
|
two generators supporting Node.js. The older generator for <code>node</code>
|
|
is essentially delegating to the <code>v8</code> generator and adds
|
|
some necessary preprocessor definitions. The more recent <code>-napi</code>
|
|
generator produces <code>node-addon-api</code> that interfaces to
|
|
Node.js through Node-API. The V8 generator is more mature, while the
|
|
Node-API generator offers a number of advantages such as binary stable
|
|
ABI allowing for publishing of universal binary modules on npm,
|
|
Electron support and automatic multi-threading.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -javascript -jsc example.i</pre>
|
|
</div>
|
|
<p>If building a C++ extension, add the -c++ option:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c++ -javascript -jsc example.i</pre>
|
|
</div>
|
|
<p>To generate code for V8, you would run swig like so:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c++ -javascript -v8 example.i</pre>
|
|
</div>
|
|
<p>This creates a C/C++ source file <code>example_wrap.c</code> or <code>
|
|
example_wrap.cxx</code>. 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 <code>example.i</code>, the
|
|
name of the wrapper file is <code>example_wrap.c</code>. To change
|
|
this, you can use the -o option. The wrapped module will export one
|
|
function which must be called to register the module with the
|
|
Javascript interpreter. For example, if your module is named <code>
|
|
example</code> the corresponding initializer for JavascriptCore would be</p>
|
|
<div class="code">
|
|
<pre>
|
|
bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports)</pre>
|
|
</div>
|
|
<p>and for v8:</p>
|
|
<div class="code">
|
|
<pre>
|
|
void example_initialize(v8::Handle<v8::Object> exports)</pre>
|
|
</div>
|
|
<p><b> Note</b>: be aware that <code>v8</code> has a C++ API, and thus,
|
|
the generated modules must be compiled as C++.</p>
|
|
<h3><a name="Javascript_running_tests_examples">28.2.2 Running Tests and
|
|
Examples</a></h3>
|
|
<p>The configuration for tests and examples currently supports Linux and
|
|
Mac only and not MinGW (Windows) yet.</p>
|
|
<p>The default interpreter is <code>node.js</code> as it is available on
|
|
all platforms and convenient to use.</p>
|
|
<p>Running the examples with JavascriptCore requires <code>
|
|
libjavascriptcoregtk-1.0</code> to be installed, e.g., under Ubuntu with</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ sudo apt-get install libjavascriptcoregtk-1.0-dev</pre>
|
|
</div>
|
|
<p>Running with <code>V8</code> requires <code>libv8</code>:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ sudo apt-get install libnode-dev</pre>
|
|
</div>
|
|
<p>Running with Node-API requires <code>node-addon-api</code>:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ sudo npm install -g node-addon-api</pre>
|
|
</div>
|
|
<p>Examples can be run using</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ make check-javascript-examples ENGINE=jsc</pre>
|
|
</div>
|
|
<p><code>ENGINE</code> can be <code>node</code>, <code>jsc</code>, <code>
|
|
v8</code>, or <code>napi</code>.</p>
|
|
<p>The test-suite can be run using</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ make check-javascript-test-suite ENGINE=jsc</pre>
|
|
</div>
|
|
<h3><a name="Javascript_known_issues">28.2.3 Known Issues</a></h3>
|
|
<p>At the moment, the Javascript generators pass all tests
|
|
syntactically, i.e., the generated source code compiles. However, there
|
|
are still remaining runtime issues.</p>
|
|
<ul>
|
|
<li>
|
|
<p>Default optional arguments do not work for all targeted interpreters
|
|
except Node-API</p>
|
|
</li>
|
|
<li>
|
|
<p>Multiple output arguments do not work for JSC</p>
|
|
</li>
|
|
<li>
|
|
<p>C89 incompatibility: the JSC generator might still generate C89
|
|
violating code</p>
|
|
</li>
|
|
<li>
|
|
<p><code>long long</code> is not supported except with Node-API</p>
|
|
</li>
|
|
<li>
|
|
<p>Javascript callbacks are not supported</p>
|
|
</li>
|
|
<li>
|
|
<p><code>instanceOf</code> does not work under JSC</p>
|
|
</li>
|
|
</ul>
|
|
<p>The primary development environment has been Linux (Ubuntu 22.04).
|
|
Windows and Mac OS X have been tested sporadically. Therefore, the
|
|
generators might have more issues on those platforms. Please report
|
|
back any problem you observe to help us improving this module quickly.</p>
|
|
<h2><a name="Javascript_integration">28.3 Integration</a></h2>
|
|
<p>This chapter gives a short introduction how to use a native
|
|
Javascript extension: as a <code>node.js</code> module, and as an
|
|
extension for an embedded Webkit.</p>
|
|
<h3><a name="Javascript_node_extensions">28.3.1 Creating node.js
|
|
Extensions</a></h3>
|
|
<p>To install <code>node.js</code> you can download an installer from
|
|
their <a href="https://launchpad.net/~chris-lea/+archive/node.js">
|
|
web-site</a> for Mac OS X and Windows. For Linux you can either build
|
|
the source yourself and run <code>sudo checkinstall</code> or keep to
|
|
the (probably stone-age) packaged version. For Ubuntu there is a <a href="https://launchpad.net/~chris-lea/+archive/ubuntu/node.js/">
|
|
PPA</a> available.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ sudo add-apt-repository ppa:chris-lea/node.js
|
|
$ sudo apt-get update
|
|
$ sudo apt-get install nodejs</pre>
|
|
</div>
|
|
<p>As <code>v8</code> is written in C++ and comes as a C++ library it is
|
|
crucial to compile your module using the same compiler flags as used
|
|
for building v8. To make things easier, <code>node.js</code> provides a
|
|
build tool called <code>node-gyp</code>.</p>
|
|
<p>You have to install it using <code>npm</code>:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ sudo npm install -g node-gyp</pre>
|
|
</div>
|
|
<p><code>node-gyp</code> expects a configuration file named <code>
|
|
binding.gyp</code> which is basically in JSON format and conforms to the
|
|
same format that is used with Google's build-tool <code>gyp</code>.</p>
|
|
<p><code>binding.gyp</code>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
{
|
|
"targets": [
|
|
{
|
|
"target_name": "example",
|
|
"sources": [ "example.cxx", "example_wrap.cxx" ]
|
|
}
|
|
]
|
|
}</pre>
|
|
</div>
|
|
<p>First create the wrapper using SWIG:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -javascript -node -c++ example.i</pre>
|
|
</div>
|
|
<p>Then run <code>node-gyp build</code> to actually create the module:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ node-gyp build</pre>
|
|
</div>
|
|
<p>This will create a <code>build</code> folder containing the native
|
|
module. To use the extension you need to 'require' it in your
|
|
Javascript source file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
require("./build/Release/example")</pre>
|
|
</div>
|
|
<p>A more detailed explanation is given in the <a href="#Javascript_examples">
|
|
Examples</a> section.</p>
|
|
<h4><a name="Javascript_using_yeoman">28.3.1.1 Using <code>yeoman</code>
|
|
to generate a Node-API skeleton</a></h4>
|
|
<p>If targeting Node-API, the easiest way to bootstrap a project is by
|
|
using the <code>yeoman</code> generator:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ sudo npm install -g yo
|
|
$ sudo npm install -g generator-napi-module
|
|
$ mkdir example
|
|
$ cd example
|
|
$ yo napi-module # the choice of template is irrelevant, SWIG will replace the C++ code
|
|
$ npm install node-addon-api@latest # the yeoman version is outdated
|
|
$ swig -javascript -napi -c++ -o src/example.cc example.i
|
|
$ node-gyp configure
|
|
$ node-gyp build
|
|
</pre>
|
|
</div>
|
|
<p>There is also the <a href="https://github.com/mmomtchev/node-magickwand">
|
|
<code>node-magickwand</code></a> project that can be used as a tutorial
|
|
for building and publishing a complex C++ library to npm as a
|
|
ready-to-use real-world binary module.</p>
|
|
<h4><a name="Javascript_troubleshooting">28.3.1.2 Troubleshooting</a></h4>
|
|
<ul>
|
|
<li><em>'module' object has no attribute 'script_main'</em></li>
|
|
</ul>
|
|
<p>This error happens when <code>gyp</code> is installed as a
|
|
distribution package. It seems to be outdated. Removing it resolves the
|
|
problem.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ sudo apt-get remove gyp</pre>
|
|
</div>
|
|
<h3><a name="Javascript_embedded_webkit">28.3.2 Embedded Webkit</a></h3>
|
|
<p>Webkit is pre-installed on Mac OS X and available as a library for
|
|
GTK.</p>
|
|
<h4><a name="Javascript_osx">28.3.2.1 Mac OS X</a></h4>
|
|
<p>There is general information about programming with WebKit on <a href="https://developer.apple.com/library/mac/documentation/cocoa/conceptual/DisplayWebContent/DisplayWebContent.html">
|
|
Apple Developer Documentation</a>. Details about <code>Cocoa</code>
|
|
programming are not covered here.</p>
|
|
<p>An integration of a native extension 'example' would look like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#import "appDelegate.h"
|
|
|
|
extern bool example_initialize(JSGlobalContextRef context, JSObjectRef* exports);
|
|
|
|
|
|
@implementation ExampleAppDelegate
|
|
|
|
@synthesize webView;
|
|
|
|
- (void)addGlobalObject:(JSContextRef) context:(NSString *)objectName:(JSObjectRef) theObject {
|
|
JSObjectRef global = JSContextGetGlobalObject(context);
|
|
JSStringRef objectJSName = JSStringCreateWithCFString( (CFStringRef) objectName )
|
|
if ( objectJSName != NULL ) {
|
|
JSObjectSetProperty(context, global, objectJSName, theObject, kJSPropertyAttributeReadOnly, NULL);
|
|
JSStringRelease( objectJSName );
|
|
}
|
|
}
|
|
|
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
|
|
|
// Start a webview with the bundled index.html file
|
|
NSString *path = [[NSBundle mainBundle] bundlePath];
|
|
NSString *url = [NSString stringWithFormat: @"file://%@/Contents/Assets/index.html", path];
|
|
|
|
WebFrame *webframe = [webView mainFrame];
|
|
JSGlobalContextRef context = [webframe globalContext];
|
|
|
|
JSObjectRef example;
|
|
example_initialize(context, &example);
|
|
[self addGlobalObject:context:@"example":example]
|
|
|
|
JSObjectSetProperty(context, global, JSStringRef propertyName, example, JSPropertyAttributes attributes, NULL);
|
|
|
|
[ [webView mainFrame] loadRequest:
|
|
[NSURLRequest requestWithURL: [NSURL URLWithString:url] ]
|
|
];
|
|
}
|
|
|
|
@end</pre>
|
|
</div>
|
|
<h4><a name="Javascript_gtk">28.3.2.2 GTK</a></h4>
|
|
<p>There is general information about programming GTK at <a href="https://developer.gnome.org/gtk2/">
|
|
GTK documentation</a> and in the <a href="https://developer.gnome.org/gtk-tutorial/">
|
|
GTK tutorial</a>, and for Webkit there is a <a href="https://webkitgtk.org/reference/webkitgtk/stable/index.html">
|
|
Webkit GTK+ API Reference</a>.</p>
|
|
<p>An integration of a native extension 'example' would look like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
#include <gtk/gtk.h>
|
|
#include <webkit/webkit.h>
|
|
|
|
extern bool example_initialize(JSGlobalContextRef context);
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
// Initialize GTK+
|
|
gtk_init(&argc, &argv);
|
|
|
|
...
|
|
|
|
// Create a browser instance
|
|
WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
|
|
WebFrame *webframe = webkit_web_view_get_main_frame(webView);
|
|
JSGlobalContextRef context = webkit_web_frame_get_global_context(webFrame);
|
|
JSObjectRef global = JSContextGetGlobalObject(context);
|
|
|
|
JSObjectRef exampleModule;
|
|
example_initialize(context, &exampleModule);
|
|
JSStringRef jsName = JSStringCreateWithUTF8CString("example");
|
|
JSObjectSetProperty(context, global, jsName, exampleModule, kJSPropertyAttributeReadOnly, NULL);
|
|
JSStringRelease(jsName);
|
|
|
|
...
|
|
|
|
// Load a web page into the browser instance
|
|
webkit_web_view_load_uri(webView, "https://www.webkitgtk.org/");
|
|
|
|
...
|
|
|
|
// Run the main GTK+ event loop
|
|
gtk_main();
|
|
|
|
return 0;
|
|
}</pre>
|
|
</div>
|
|
<h3><a name="Javascript_applications_webkit">28.3.3 Creating
|
|
Applications with node-webkit</a></h3>
|
|
<p>To get started with <code>node-webkit</code> there is a very
|
|
informative set of <a href="https://github.com/rogerwang/node-webkit/wiki">
|
|
wiki pages</a>.</p>
|
|
<p>Similar to <code>node.js</code>, <code>node-webkit</code> is started
|
|
from command line within a <code>node.js</code> project directory.
|
|
Native extensions are created in the very same way as for <code>node.js</code>
|
|
, except that a customized <code>gyp</code> derivate has to be used: <a href="https://github.com/rogerwang/nw-gyp">
|
|
nw-gyp</a>.</p>
|
|
<p> A simple example would have the following structure:</p>
|
|
<div class="code">
|
|
<pre>
|
|
- package.json
|
|
- app.html
|
|
- app.js
|
|
- node_modules
|
|
/ example
|
|
... (as known from node.js)
|
|
</pre>
|
|
</div>
|
|
<p> The configuration file essentially conforms to <code>node.js</code>
|
|
syntax. It has some extras to configure <code>node-webkit</code>. See
|
|
the <a href="https://github.com/rogerwang/node-webkit/wiki/Manifest-format">
|
|
Manifest</a> specification for more details.</p>
|
|
<p> <code>package.json</code>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
{
|
|
"name": "example",
|
|
"main": "app.html",
|
|
"window": {
|
|
"show": true,
|
|
"width": 800,
|
|
"height": 600
|
|
}
|
|
}</pre>
|
|
</div>
|
|
<p> The <code>'main'</code> property of <code>package.json</code>
|
|
specifies a web-page to be rendered in the main window.</p>
|
|
<p> <code>app.html</code>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
<html>
|
|
<head>
|
|
<script src="app.js"></script>
|
|
</head>
|
|
<body>
|
|
<div>
|
|
The greatest common divisor of
|
|
<span id="x"></span> and
|
|
<span id="y"></span> is
|
|
<span id="z"></span>.
|
|
</div>
|
|
</body>
|
|
</html></pre>
|
|
</div>
|
|
<p> As known from <code>node.js</code> one can use <code>require</code>
|
|
to load javascript modules. Additionally, <code>node-webkit</code>
|
|
provides an API that allows manipulating the window's menu, open new
|
|
windows, and many more things.</p>
|
|
<p> <code>app.js</code>:</p>
|
|
<div class="code">
|
|
<pre>window.onload = function() {
|
|
var example = require("example");
|
|
var x = 18;
|
|
var y = 24;
|
|
var z = example.gcd(x, y);
|
|
document.querySelector('#x').innerHTML = x;
|
|
document.querySelector('#y').innerHTML = y;
|
|
document.querySelector('#z').innerHTML = z;
|
|
};</pre>
|
|
</div>
|
|
<h2><a name="Javascript_examples">28.4 Examples</a></h2>
|
|
<p>Some basic examples are shown here in more detail.</p>
|
|
<h3><a name="Javascript_simple_example">28.4.1 Simple</a></h3>
|
|
<p>The common example <code>simple</code> looks like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File : example.i */
|
|
%module example
|
|
|
|
%inline %{
|
|
extern int gcd(int x, int y);
|
|
extern double Foo;
|
|
%}</pre>
|
|
</div>
|
|
<p>To make this available as a node extension a <code>binding.gyp</code>
|
|
has to be created:</p>
|
|
<div class="code">
|
|
<pre>
|
|
{
|
|
"targets": [
|
|
{
|
|
"target_name": "example",
|
|
"sources": [ "example.cxx", "example_wrap.cxx" ]
|
|
}
|
|
]
|
|
}</pre>
|
|
</div>
|
|
<p>Then <code>node-gyp</code> is used to build the extension:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ node-gyp configure build</pre>
|
|
</div>
|
|
<p>From a 'nodejs` application the extension would be used like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// import the extension via require
|
|
var example = require("./build/Release/example");
|
|
|
|
// calling the global method
|
|
var x = 42;
|
|
var y = 105;
|
|
var g = example.gcd(x, y);
|
|
|
|
// Accessing the global variable
|
|
var f = example.Foo;
|
|
example.Foo = 3.1415926;</pre>
|
|
</div>
|
|
<p>First the module <code>example</code> is loaded from the previously
|
|
built extension. Global methods and variables are available in the
|
|
scope of the module.</p>
|
|
<p><b>Note</b>: ECMAScript 5, the currently implemented Javascript
|
|
standard, does not have modules. <code>node.js</code> and other
|
|
implementations provide this mechanism defined by the <a href="https://wiki.commonjs.org/wiki/CommonJS">
|
|
CommonJS</a> group. For browsers this is provided by <a href="https://browserify.org">
|
|
Browserify</a>, for instance.</p>
|
|
<h3><a name="Javascript_class_example">28.4.2 Class</a></h3>
|
|
<p>The common example <code>class</code> defines three classes, <code>
|
|
Shape</code>, <code>Circle</code>, and <code>Square</code>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class Shape {
|
|
public:
|
|
Shape() {
|
|
nshapes++;
|
|
}
|
|
virtual ~Shape() {
|
|
nshapes--;
|
|
}
|
|
double x, y;
|
|
void move(double dx, double dy);
|
|
virtual double area(void) = 0;
|
|
virtual double perimeter(void) = 0;
|
|
static int nshapes;
|
|
};
|
|
|
|
class Circle : public Shape {
|
|
private:
|
|
double radius;
|
|
public:
|
|
Circle(double r) : radius(r) { }
|
|
virtual double area(void);
|
|
virtual double perimeter(void);
|
|
};
|
|
|
|
class Square : public Shape {
|
|
private:
|
|
double width;
|
|
public:
|
|
Square(double w) : width(w) { }
|
|
virtual double area(void);
|
|
virtual double perimeter(void);
|
|
};</pre>
|
|
</div>
|
|
<p><code>Circle</code> and <code>Square</code> inherit from <code>Shape</code>
|
|
. <code>Shape</code> has a static variable <code>nshapes</code>, a
|
|
function <code>move</code> that can't be overridden (non-virtual), and
|
|
two abstract functions <code>area</code> and <code>perimeter</code>
|
|
(pure virtual) that must be overridden by the sub-classes.</p>
|
|
<p>A <code>nodejs</code> extension is built the same way as for the <code>
|
|
simple</code> example.</p>
|
|
<p>In Javascript it can be used as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
var example = require("./build/Release/example");
|
|
|
|
// local aliases for convenience
|
|
var Shape = example.Shape;
|
|
var Circle = example.Circle;
|
|
var Square = example.Square;
|
|
|
|
// creating new instances using the 'new' operator
|
|
var c = new Circle(10);
|
|
var s = new Square(10);
|
|
|
|
// accessing a static member
|
|
Shape.nshapes;
|
|
|
|
// accessing member variables
|
|
c.x = 20;
|
|
c.y = 30;
|
|
s.x = -10;
|
|
s.y = 5;
|
|
|
|
// calling some methods
|
|
c.area();
|
|
c.perimeter();
|
|
s.area();
|
|
s.perimeter();
|
|
|
|
// instantiation of Shape is not permitted
|
|
new Shape();</pre>
|
|
</div>
|
|
<p>Running these commands in an interactive node shell results in the
|
|
following output:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ node -i
|
|
& var example = require("./build/Release/example");
|
|
undefined
|
|
& var Shape = example.Shape;
|
|
undefined
|
|
& var Circle = example.Circle;
|
|
undefined
|
|
& var Square = example.Square;
|
|
undefined
|
|
& var c = new Circle(10);
|
|
undefined
|
|
& var s = new Square(10);
|
|
undefined
|
|
& Shape.nshapes;
|
|
2
|
|
& c.x = 20;
|
|
20
|
|
& c.y = 30;
|
|
30
|
|
& s.x = -10;
|
|
-10
|
|
& s.y = 5;
|
|
5
|
|
& c.area();
|
|
314.1592653589793
|
|
& c.perimeter();
|
|
62.83185307179586
|
|
& s.area();
|
|
100
|
|
& s.perimeter();
|
|
40
|
|
& c.move(40, 40)
|
|
undefined
|
|
& c.x
|
|
60
|
|
& c.y
|
|
70
|
|
& new Shape()
|
|
Error: Class Shape can not be instantiated
|
|
at repl:1:2
|
|
at REPLServer.self.eval (repl.js:110:21)
|
|
at Interface.<anonymous> (repl.js:239:12)
|
|
at Interface.EventEmitter.emit (events.js:95:17)
|
|
at Interface._onLine (readline.js:202:10)
|
|
at Interface._line (readline.js:531:8)
|
|
at Interface._ttyWrite (readline.js:760:14)
|
|
at ReadStream.onkeypress (readline.js:99:10)
|
|
at ReadStream.EventEmitter.emit (events.js:98:17)
|
|
at emitKey (readline.js:1095:12)</pre>
|
|
</div>
|
|
<p><b> Note</b>: In ECMAScript 5 there is no concept for classes.
|
|
Instead each function can be used as a constructor function which is
|
|
executed by the 'new' operator. Furthermore, during construction the
|
|
key property <code>prototype</code> of the constructor function is used
|
|
to attach a prototype instance to the created object. A prototype is
|
|
essentially an object itself that is the first-class delegate of a
|
|
class used whenever the access to a property of an object fails. The
|
|
very same prototype instance is shared among all instances of one type.
|
|
Prototypal inheritance is explained in more detail on in <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">
|
|
Inheritance and the prototype chain</a>, for instance.</p>
|
|
<h2><a name="Javascript_implementation">28.5 Implementation</a></h2>
|
|
<p>The Javascript Module implementation has taken a very different
|
|
approach compared to other language modules in order to support
|
|
different Javascript interpreters.</p>
|
|
<h3><a name="Javascript_source_code">28.5.1 Source Code</a></h3>
|
|
<p>The Javascript module is implemented in <code>
|
|
Source/Modules/javascript.cxx</code>. It dispatches the code generation
|
|
to a <code>JSEmitter</code> instance, <code>V8Emitter</code>, <code>
|
|
JSCEmitter</code> or <code>NAPIEmitter</code>. Additionally there are
|
|
some helpers: <code>Template</code>, for templated code generation, and
|
|
<code>JSEmitterState</code>, which is used to manage state information
|
|
during AST traversal. This rough map shall make it easier to find a way
|
|
through this huge source file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// module wide defines
|
|
|
|
#define NAME "name"
|
|
...
|
|
|
|
// ###############################
|
|
// # Helper class declarations
|
|
|
|
class JSEmitterState { ... };
|
|
|
|
class Template { ... };
|
|
|
|
// ###############################
|
|
// # JSEmitter declaration
|
|
|
|
class JSEmitter { ... };
|
|
|
|
// Emitter factory declarations
|
|
|
|
JSEmitter *swig_javascript_create_JSCEmitter();
|
|
JSEmitter *swig_javascript_create_V8Emitter();
|
|
JSEmitter *swig_javascript_create_NAPIEmitter();
|
|
|
|
// ###############################
|
|
// # Javascript module
|
|
|
|
// Javascript module declaration
|
|
|
|
class JAVASCRIPT:public Language { ... };
|
|
|
|
// Javascript module implementation
|
|
|
|
int JAVASCRIPT::functionWrapper(Node *n) { ... }
|
|
...
|
|
|
|
// Module factory implementation
|
|
|
|
static Language *new_swig_javascript() { ... }
|
|
|
|
extern "C" Language *swig_javascript(void) { ... }
|
|
|
|
// ###############################
|
|
// # JSEmitter base implementation
|
|
|
|
JSEmitter::JSEmitter() { ... }
|
|
|
|
Template JSEmitter::getTemplate(const String *name) { ... }
|
|
...
|
|
|
|
// ###############################
|
|
// # JSCEmitter
|
|
|
|
// JSCEmitter declaration
|
|
|
|
class JSCEmitter: public JSEmitter { ... };
|
|
|
|
// JSCEmitter implementation
|
|
|
|
JSCEmitter::JSCEmitter() { ... }
|
|
|
|
void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { ... }
|
|
...
|
|
|
|
// JSCEmitter factory
|
|
|
|
JSEmitter *swig_javascript_create_JSCEmitter() { ... }
|
|
|
|
|
|
// ###############################
|
|
// # V8Emitter
|
|
|
|
// V8Emitter declaration
|
|
|
|
class V8Emitter: public JSEmitter { ... };
|
|
|
|
// V8Emitter implementation
|
|
|
|
V8Emitter::V8Emitter() { ... }
|
|
|
|
int V8Emitter::initialize(Node *n) { ... }
|
|
|
|
// V8Emitter factory
|
|
|
|
JSEmitter *swig_javascript_create_V8Emitter() { ... }
|
|
|
|
|
|
// ###############################
|
|
// # Helper implementation (JSEmitterState, Template)
|
|
|
|
JSEmitterState::JSEmitterState() { ... }
|
|
...
|
|
|
|
Template::Template(const String *code_) { ... }
|
|
...</pre>
|
|
</div>
|
|
<h3><a name="Javascript_code_templates">28.5.2 Code Templates</a></h3>
|
|
<p>All generated code is created on the basis of code templates. The
|
|
templates for<em> JavascriptCore</em> can be found in <code>
|
|
Lib/javascript/jsc/javascriptcode.swg</code>, for<em> v8</em> in <code>
|
|
Lib/javascript/v8/javascriptcode.swg</code> and for<em> Node-API</em> in
|
|
<code>Lib/javascript/napi/javascriptcode.swg</code>.</p>
|
|
<p>To track the originating code template for generated code you can run</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -javascript -jsc -debug-codetemplates</pre>
|
|
</div>
|
|
<p>which wraps generated code with a descriptive comment</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* begin fragment("template_name") */
|
|
|
|
...generated code ...
|
|
|
|
/* end fragment("template_name") */</pre>
|
|
</div>
|
|
<p>The Template class is used like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
Template t_register = getTemplate("jsv8_register_static_variable");
|
|
t_register.replace("$jsparent", state.clazz(NAME_MANGLED))
|
|
.replace("$jsname", state.variable(NAME))
|
|
.replace("$jsgetter", state.variable(GETTER))
|
|
.replace("$jssetter", state.variable(SETTER))
|
|
.trim().
|
|
print(f_init_static_wrappers);</pre>
|
|
</div>
|
|
<p>A code template is registered with the<em> JSEmitter</em> via <code>
|
|
fragment(name, "template")</code>, e.g.,</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment ("jsc_variable_declaration", "templates")
|
|
%{
|
|
{"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone},
|
|
%}</pre>
|
|
</div>
|
|
<p><code>Template</code> creates a copy of that string and <code>
|
|
Template::replace</code> uses Swig's <code>Replaceall</code> to replace
|
|
variables in the template. <code>Template::trim</code> can be used to
|
|
eliminate leading and trailing whitespaces. <code>Template::print</code>
|
|
is used to write the final template string to a Swig <code>DOH</code>
|
|
(based on <code>Printv</code>). All methods allow chaining.</p>
|
|
<h3><a name="Javascript_emitter">28.5.3 Emitter</a></h3>
|
|
<p>The Javascript module delegates code generation to a <code>JSEmitter</code>
|
|
instance. The following extract shows the essential interface:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class JSEmitter {
|
|
...
|
|
|
|
/**
|
|
* Opens output files and temporary output DOHs.
|
|
*/
|
|
virtual int initialize(Node *n);
|
|
|
|
/**
|
|
* Writes all collected code into the output file(s).
|
|
*/
|
|
virtual int dump(Node *n) = 0;
|
|
|
|
/**
|
|
* Cleans up all open output DOHs.
|
|
*/
|
|
virtual int close() = 0;
|
|
|
|
...
|
|
|
|
/**
|
|
* Invoked at the beginning of the classHandler.
|
|
*/
|
|
virtual int enterClass(Node *);
|
|
|
|
/**
|
|
* Invoked at the end of the classHandler.
|
|
*/
|
|
virtual int exitClass(Node *) {
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/**
|
|
* Invoked at the beginning of the variableHandler.
|
|
*/
|
|
virtual int enterVariable(Node *);
|
|
|
|
/**
|
|
* Invoked at the end of the variableHandler.
|
|
*/
|
|
virtual int exitVariable(Node *) {
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/**
|
|
* Invoked at the beginning of the functionHandler.
|
|
*/
|
|
virtual int enterFunction(Node *);
|
|
|
|
/**
|
|
* Invoked at the end of the functionHandler.
|
|
*/
|
|
virtual int exitFunction(Node *) {
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/**
|
|
* Invoked by functionWrapper callback after call to Language::functionWrapper.
|
|
*/
|
|
virtual int emitWrapperFunction(Node *n);
|
|
|
|
/**
|
|
* Invoked from constantWrapper after call to Language::constantWrapper.
|
|
**/
|
|
virtual int emitConstant(Node *n);
|
|
|
|
/**
|
|
* Registers a given code snippet for a given key name.
|
|
*
|
|
* This method is called by the fragmentDirective handler
|
|
* of the JAVASCRIPT language module.
|
|
**/
|
|
int registerTemplate(const String *name, const String *code);
|
|
|
|
/**
|
|
* Retrieve the code template registered for a given name.
|
|
*/
|
|
Template getTemplate(const String *name);
|
|
|
|
State &getState();
|
|
|
|
...
|
|
|
|
}</pre>
|
|
</div>
|
|
<p>The module calls <code>initialize</code>, <code>dump</code>, and <code>
|
|
close</code> from within the <code>top</code> method:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int JAVASCRIPT::top(Node *n) {
|
|
emitter->initialize(n);
|
|
|
|
Language::top(n);
|
|
|
|
emitter->dump(n);
|
|
emitter->close();
|
|
|
|
return SWIG_OK;
|
|
}</pre>
|
|
</div>
|
|
<p>The methods <code>enterClass</code> and <code>exitClass</code> are
|
|
called from within the <code>classHandler</code> method:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int JAVASCRIPT::classHandler(Node *n) {
|
|
|
|
emitter->enterClass(n);
|
|
Language::classHandler(n);
|
|
emitter->exitClass(n);
|
|
|
|
return SWIG_OK;
|
|
}</pre>
|
|
</div>
|
|
<p>In <code>enterClass</code> the emitter stores state information that
|
|
is necessary when processing class members. In <code>exitClass</code>
|
|
the wrapper code for the whole class is generated.</p>
|
|
<h3><a name="Javascript_emitter_states">28.5.4 Emitter states</a></h3>
|
|
<p>For storing information during the AST traversal the emitter provides
|
|
a <code>JSEmitterState</code> with different slots to store data
|
|
representing the scopes global, class, function, and variable.</p>
|
|
<div class="code">
|
|
<pre>
|
|
class JSEmitterState {
|
|
|
|
public:
|
|
|
|
JSEmitterState();
|
|
|
|
~JSEmitterState();
|
|
|
|
DOH *global();
|
|
|
|
DOH *global(const char* key, DOH *initial = 0);
|
|
|
|
DOH *clazz(bool reset = false);
|
|
|
|
DOH *clazz(const char* key, DOH *initial = 0);
|
|
|
|
DOH *function(bool reset = false);
|
|
|
|
DOH *function(const char* key, DOH *initial = 0);
|
|
|
|
DOH *variable(bool reset = false);
|
|
|
|
DOH *variable(const char* key, DOH *initial = 0);
|
|
|
|
static int IsSet(DOH *val);
|
|
|
|
...
|
|
};</pre>
|
|
</div>
|
|
<p>When entering a scope, such as in <code>enterClass</code>, the
|
|
corresponding state is reset and new data is stored:</p>
|
|
<div class="code">
|
|
<pre>
|
|
state.clazz(RESET);
|
|
state.clazz(NAME, Getattr(n, "sym:name"));</pre>
|
|
</div>
|
|
<p>State information can be retrieved using <code>state.clazz(NAME)</code>
|
|
or with <code>Getattr</code> on <code>state.clazz()</code> which
|
|
actually returns a <code>Hash</code> instance.</p>
|
|
<h3><a name="Javascript_jsc_exceptions">28.5.5 Handling Exceptions in
|
|
JavascriptCore</a></h3>
|
|
<p>Applications with an embedded JavascriptCore should be able to
|
|
present detailed exception messages that occur in the Javascript
|
|
engine. Below is an example derived from code provided by Brian Barnes
|
|
on how these exception details can be extracted.</p>
|
|
<div class="code">
|
|
<pre>
|
|
void script_exception_to_string(JSContextRef js_context, JSValueRef exception_value_ref, char* return_error_string, int return_error_string_max_length)
|
|
{
|
|
JSObjectRef exception_object;
|
|
JSValueRef value_ref;
|
|
JSStringRef jsstring_property_name = NULL;
|
|
JSValueRef temporary_exception = NULL;
|
|
JSStringRef js_return_string = NULL;
|
|
size_t bytes_needed;
|
|
char* c_result_string = NULL;
|
|
exception_object = JSValueToObject(js_context, exception_value_ref, NULL);
|
|
|
|
/* source url */
|
|
strcpy(return_error_string, "[");
|
|
jsstring_property_name = JSStringCreateWithUTF8CString("sourceURL");
|
|
value_ref = JSObjectGetProperty(js_context, exception_object, jsstring_property_name, &temporary_exception);
|
|
JSStringRelease(jsstring_property_name);
|
|
js_return_string = JSValueToStringCopy(js_context, value_ref, NULL);
|
|
bytes_needed = JSStringGetMaximumUTF8CStringSize(js_return_string);
|
|
c_result_string = (char*)calloc(bytes_needed, sizeof(char));
|
|
JSStringGetUTF8CString(js_return_string, c_result_string, bytes_needed);
|
|
JSStringRelease(js_return_string);
|
|
strncat(return_error_string, c_result_string, return_error_string_max_length-1);
|
|
free(c_result_string);
|
|
|
|
strncat(return_error_string, ":", return_error_string_max_length-1);
|
|
|
|
/* line number */
|
|
|
|
jsstring_property_name = JSStringCreateWithUTF8CString("line");
|
|
value_ref = JSObjectGetProperty(js_context, exception_object, jsstring_property_name, &temporary_exception);
|
|
JSStringRelease(jsstring_property_name);
|
|
js_return_string = JSValueToStringCopy(js_context, value_ref, NULL);
|
|
bytes_needed = JSStringGetMaximumUTF8CStringSize(js_return_string);
|
|
c_result_string = (char*)calloc(bytes_needed, sizeof(char));
|
|
JSStringGetUTF8CString(js_return_string, c_result_string, bytes_needed);
|
|
JSStringRelease(js_return_string);
|
|
strncat(return_error_string, c_result_string, return_error_string_max_length-1);
|
|
free(c_result_string);
|
|
|
|
strncat(return_error_string, "]", return_error_string_max_length-1);
|
|
|
|
/* error message */
|
|
|
|
jsstring_property_name = JSStringCreateWithUTF8CString("message");
|
|
value_ref = JSObjectGetProperty(js_context, exception_object, jsstring_property_name, &temporary_exception);
|
|
JSStringRelease(jsstring_property_name);
|
|
if(NULL == value_ref)
|
|
{
|
|
strncat(return_error_string, "Unknown Error", return_error_string_max_length-1);
|
|
}
|
|
else
|
|
{
|
|
js_return_string = JSValueToStringCopy(js_context, value_ref, NULL);
|
|
bytes_needed = JSStringGetMaximumUTF8CStringSize(js_return_string);
|
|
c_result_string = (char*)calloc(bytes_needed, sizeof(char));
|
|
JSStringGetUTF8CString(js_return_string, c_result_string, bytes_needed);
|
|
JSStringRelease(js_return_string);
|
|
strncat(return_error_string, c_result_string, return_error_string_max_length-1);
|
|
free(c_result_string);
|
|
}
|
|
}</pre>
|
|
</div>
|
|
<p>It would be used in the following way:</p>
|
|
<div class="code">
|
|
<pre>
|
|
if(js_exception)
|
|
{
|
|
char return_error_string[256];
|
|
script_exception_to_string(js_context, js_exception, return_error_string, 256);
|
|
printf("Compile error is %s", return_error_string);
|
|
}</pre>
|
|
</div>
|
|
<h3><a name="Javascript_napi_exceptions">28.5.6 Handling Exceptions in
|
|
Node-API</a></h3>
|
|
<p>Node-API is the only generator that provides fully automatic
|
|
conversion of C++ exceptions to JavaScript exceptions when building
|
|
with C++ exceptions enabled in `binding.gyp`:</p>
|
|
<div class="code">
|
|
<pre>
|
|
'conditions': [
|
|
['OS=="mac"',
|
|
{
|
|
'xcode_settings': {
|
|
'GCC_ENABLE_CPP_RTTI': 'YES',
|
|
'GCC_ENABLE_CPP_EXCEPTIONS' : 'YES'
|
|
}
|
|
}
|
|
],
|
|
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"',
|
|
{
|
|
'cflags!': [ '-fno-exceptions' ],
|
|
'cflags_cc!': [ '-fno-exceptions', '-fno-rtti' ]
|
|
}
|
|
]
|
|
]
|
|
</pre>
|
|
</div>
|
|
<p>In this case, nothing else is needed for the C++ exceptions to be
|
|
passed to JavaScript.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Lua">29 SWIG and Lua</a></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_commandline">Additional command line options</a></li>
|
|
<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>
|
|
<ul>
|
|
<li><a href="#Lua_nn13">Constants/enums and classes/structures</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Lua_nn12">Pointers</a></li>
|
|
<li><a href="#Lua_structures">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">Using %newobject to release memory</a></li>
|
|
<li><a href="#Lua_nn21">C++ templates</a></li>
|
|
<li><a href="#Lua_nn22">C++ Smart Pointers</a></li>
|
|
<li><a href="#Lua_nn23">C++ Exceptions</a></li>
|
|
<li><a href="#Lua_namespaces">Namespaces</a>
|
|
<ul>
|
|
<li><a href="#Lua_nn27">Compatibility Note</a></li>
|
|
<li><a href="#Lua_nn29">Names</a></li>
|
|
<li><a href="#Lua_nn30">Inheritance</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Lua_nn24">Typemaps</a>
|
|
<ul>
|
|
<li><a href="#Lua_nn25">What is a typemap?</a></li>
|
|
<li><a href="#Lua_nn26">Using typemaps</a></li>
|
|
<li><a href="#Lua_typemap_arrays">Typemaps and arrays</a></li>
|
|
<li><a href="#Lua_typemaps_ptr_ptr_functions">Typemaps and
|
|
pointer-pointer functions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Lua_writing_typemaps">Writing typemaps</a>
|
|
<ul>
|
|
<li><a href="#Lua_typemaps_write">Typemaps you can write</a></li>
|
|
<li><a href="#Lua_nn31">SWIG's Lua-C API</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Lua_nn32">Customization of your Bindings</a>
|
|
<ul>
|
|
<li><a href="#Lua_nn33">Writing your own custom wrappers</a></li>
|
|
<li><a href="#Lua_nn34">Adding additional Lua code</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Lua_nn35">Details on the Lua binding</a>
|
|
<ul>
|
|
<li><a href="#Lua_nn36">Binding global data into the module.</a></li>
|
|
<li><a href="#Lua_nn37">Userdata and Metatables</a></li>
|
|
<li><a href="#Lua_nn38">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 ISO C and C++). It's 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="https://www.lua.org">
|
|
https://www.lua.org</a></p>
|
|
<p> eLua stands for Embedded Lua (can be thought of as a flavor of Lua)
|
|
and offers the full implementation of the Lua programming language to
|
|
the embedded world, extending it with specific features for efficient
|
|
and portable software embedded development. eLua runs on smaller
|
|
devices like microcontrollers and provides the full features of the
|
|
regular Lua desktop version. More information on eLua can be found
|
|
here: <a href="http://www.eluaproject.net">http://www.eluaproject.net</a>
|
|
</p>
|
|
<h2><a name="Lua_nn2">29.1 Preliminaries</a></h2>
|
|
<p> The current SWIG implementation is designed to work with Lua 5.0.x,
|
|
5.1.x and 5.2.x. It should work with later versions of Lua, but
|
|
certainly not with Lua 4.0 due to substantial API changes. 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). SWIG also has support for
|
|
eLua starting from eLua 0.8. Due to substantial changes between SWIG
|
|
2.x and SWIG 3.0 and unavailability of testing platform, eLua status
|
|
was downgraded to 'experimental'.</p>
|
|
<h2><a name="Lua_nn3">29.2 Running SWIG</a></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 wrapped 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>
|
|
<p> To build an eLua module, run SWIG using <tt>-lua</tt> and add either
|
|
<tt>-elua</tt> or <tt>-eluac</tt>.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -lua -elua example.i
|
|
</pre>
|
|
</div>
|
|
<p> or</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -lua -eluac example.i
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>-elua</tt> option puts all the C function wrappers and
|
|
variable get/set wrappers in rotables. It also generates a metatable
|
|
which will control the access to these variables from eLua. It also
|
|
offers a significant amount of module size compression. On the other
|
|
hand, the <tt>-eluac</tt> option puts all the wrappers in a single
|
|
rotable. With this option, no matter how huge the module, it will
|
|
consume no additional microcontroller SRAM (crass compression). There
|
|
is a catch though: Metatables are not generated with <tt>-eluac</tt>.
|
|
To access any value from eLua, one must directly call the wrapper
|
|
function associated with that value.</p>
|
|
<h3><a name="Lua_commandline">29.2.1 Additional command line options</a></h3>
|
|
<p> The following table list the additional commandline options
|
|
available for the Lua module. They can also be seen by using:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
swig -lua -help
|
|
</pre>
|
|
</div>
|
|
<table summary="Lua specific options">
|
|
<tr><th>Lua specific options</th></tr>
|
|
<tr><td>-elua</td><td>Generates LTR compatible wrappers for smaller
|
|
devices running elua.</td></tr>
|
|
<tr><td>-eluac</td><td>LTR compatible wrappers in "crass compress" mode
|
|
for elua.</td></tr>
|
|
<tr><td>-nomoduleglobal</td><td>Do not register the module name as a
|
|
global variable but return the module table from calls to require.</td></tr>
|
|
<tr><td>-no-old-metatable-bindings</td><td>Disable backward
|
|
compatibility: old-style binding names generations and a few other
|
|
things. Explanations are included in appropriate later sections. This
|
|
option is considered deprecated and will be removed in the near future.</td>
|
|
</tr>
|
|
<tr><td>-squash-bases</td><td>Squashes symbols from all inheritance tree
|
|
of a given class into itself. Emulates pre-SWIG3.0 inheritance.
|
|
Insignificantly speeds things up, but increases memory consumption.</td>
|
|
</tr>
|
|
</table>
|
|
<h3><a name="Lua_nn4">29.2.2 Compiling and Linking and Interpreter</a></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 wrapped 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>
|
|
<p> For eLua, the source must be built along with the wrappers generated
|
|
by SWIG. Make sure the eLua source files <tt>platform_conf.h</tt> and <tt>
|
|
auxmods.h</tt> are updated with the entries of your new module. Please
|
|
note: <tt>"mod"</tt> is the module name.</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* Sample platform_conf.h */
|
|
#define LUA_PLATFORM_LIBS_ROM\
|
|
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
|
|
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
|
|
_ROM( AUXLIB_MOD, luaopen_mod, mod_map )\
|
|
....
|
|
</pre>
|
|
</div><div class="code">
|
|
<pre>
|
|
/* Sample auxmods.h */
|
|
#define AUXLIB_PIO "pio"
|
|
LUALIB_API int ( luaopen_pio )(lua_State *L );
|
|
|
|
#define AUXLIB_MOD "mod"
|
|
LUALIB_API int ( luaopen_mod )(lua_State *L );
|
|
....
|
|
</pre>
|
|
</div>
|
|
<p> More information on building and configuring eLua can be found here:
|
|
<a href="http://www.eluaproject.net/doc/v0.8/en_building.html">
|
|
http://www.eluaproject.net/doc/v0.8/en_building.html</a></p>
|
|
<h3><a name="Lua_nn5">29.2.3 Compiling a dynamic module</a></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. Assuming you have code you need to link to in
|
|
a file called <tt>example.c</tt>, the commands will be something like
|
|
this:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -lua example.i -o example_wrap.c
|
|
$ gcc -fPIC -I/usr/include/lua -c example_wrap.c -o example_wrap.o
|
|
$ gcc -fPIC -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 and later. 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) -- make sure it's 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 a
|
|
package. So it's just loadlib().</p>
|
|
<p> if 'a' is a function, this is 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
|
|
message '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">29.2.4 Using your module</a></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">29.3 A tour of basic C/C++ wrapping</a></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">29.3.1 Modules</a></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">29.3.2 Functions</a></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 keeps all
|
|
the functions, constants, classes and global variables in. It is
|
|
possible to copy the functions, constants and classes (but not
|
|
variables) 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">29.3.3 Global variables</a></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 affect the original example.Foo
|
|
> print(example.Foo, c)
|
|
4 5
|
|
</pre>
|
|
</div>
|
|
<p> It 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 a 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 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>
|
|
<p> If you have used the <tt>-eluac</tt> option for your eLua module,
|
|
you will have to follow a different approach while manipulating global
|
|
variables. (This is not applicable for wrappers generated with <tt>
|
|
-elua</tt>)</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> -- Applicable only with -eluac. (num is defined)
|
|
> print(example.num_get())
|
|
20
|
|
> example.num_set(50) -- new value added
|
|
> print(example.num_get())
|
|
50
|
|
</pre>
|
|
</div>
|
|
<p> In general, functions of the form <tt>"variable_get()"</tt> and <tt>
|
|
"variable_set()"</tt> are automatically generated by SWIG for use with <tt>
|
|
-eluac</tt>.</p>
|
|
<h3><a name="Lua_nn11">29.3.4 Constants and enums</a></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>
|
|
<p> If you're using eLua and have used <tt>-elua</tt> or <tt>-eluac</tt>
|
|
to generate your wrapper, macro constants and enums should be accessed
|
|
through a rotable called <tt>"const"</tt>. In eLua, macro constants and
|
|
enums are guaranteed to remain constants since they are all contained
|
|
within a rotable. A regular C constant is accessed from eLua just as if
|
|
it were a regular global variable, just that the property of value
|
|
immutability is demonstrated if an attempt at modifying a C constant is
|
|
made.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(example.ICONST)
|
|
10
|
|
> print(example.const.SUNDAY)
|
|
0
|
|
> print(example.const.SCONST)
|
|
Hello World
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Lua_nn13">29.3.4.1 Constants/enums and classes/structures</a>
|
|
</h4>
|
|
<p> Enums are exported into a class table. For example, given some
|
|
enums:</p>
|
|
<div class="code">
|
|
<pre>%module example
|
|
enum Days { SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };
|
|
struct Test {
|
|
enum { TEST1 = 10, TEST2 = 20 };
|
|
#ifdef __cplusplus // There are no static members in C
|
|
static const int ICONST = 12;
|
|
#endif
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> There is a slight difference in behaviour wrapping C and C++ code
|
|
due to the different scoping rules of C and C++. The wrapped C++ code
|
|
is used as follows from Lua code:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(example.SUNDAY)
|
|
0
|
|
> print(example.Test.TEST1)
|
|
10
|
|
> print(example.Test.ICONST)
|
|
12
|
|
</pre>
|
|
</div>
|
|
<p>Enums within a C struct are in the global namespace and are used as
|
|
follows from Lua</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(example.SUNDAY)
|
|
0
|
|
> -- See the difference here
|
|
> print(example.TEST1)
|
|
10
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility Note:</b> Versions of SWIG prior to SWIG-3.0.0 did
|
|
not generate the class table members above. There is no change in the C
|
|
wrappers, but the following code was the only way to access these
|
|
constants/enums when wrapping C++ member constants:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(example.Test_TEST1)
|
|
10
|
|
> print(example.Test_ICONST)
|
|
12
|
|
</pre>
|
|
</div>
|
|
<p> The old-style bindings are still generated in addition to the new
|
|
ones. If the <tt>-no-old-metatable-bindings</tt> option is used, then
|
|
these old-style bindings are not generated.</p>
|
|
<p> It is worth mentioning, that <tt>example.Test.TEST1</tt> and <tt>
|
|
example.Test_TEST1</tt> are different entities and changing one does not
|
|
change the other. Given the fact that these are constants and they are
|
|
not supposed to be changed, it is up to you to avoid such issues.</p>
|
|
<h3><a name="Lua_nn12">29.3.5 Pointers</a></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 wrapped object).</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(f)
|
|
userdata: 003FDA80
|
|
> print(swig_type(f))
|
|
FILE * -- it's 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_structures">29.3.6 Structures</a></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 can be created using a function <tt>new_Point()</tt>,
|
|
and both C structures and C++ classes can be 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 effectively 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 immutables, 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>
|
|
<p> For eLua with the <tt>-eluac</tt> option, structure manipulation has
|
|
to be performed with specific structure functions generated by SWIG.
|
|
Let's say you have the following structure definition:</p>
|
|
<div class="code">
|
|
<pre>struct data {
|
|
int x, y;
|
|
double z;
|
|
};
|
|
|
|
> --From eLua
|
|
> a = example.new_data()
|
|
> example.data_x_set(a, 10)
|
|
> example.data_y_set(a, 20)
|
|
> print(example.data_x_get(a), example.data_y_get(a))
|
|
10 20
|
|
</pre>
|
|
</div>
|
|
<p> In general, functions of the form <tt>"new_struct()"</tt>, <tt>
|
|
"struct_member_get()"</tt>, <tt>"struct_member_set()"</tt> and <tt>
|
|
"free_struct()"</tt> are automatically generated by SWIG for each
|
|
structure defined in C. (Please note: This doesn't apply for modules
|
|
generated with the <tt>-elua</tt> option)</p>
|
|
<h3><a name="Lua_nn14">29.3.7 C++ classes</a></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>, it's 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="code">
|
|
<pre>
|
|
class Spam {
|
|
public:
|
|
static void foo();
|
|
static int bar;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> In Lua, C++ static members can be accessed as follows:</p>
|
|
<div class="targetlang">
|
|
<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>
|
|
<p><b> Compatibility Note:</b> In versions prior to SWIG-3.0.0 only the
|
|
following names would work:</p>
|
|
<div class="targetlang">
|
|
<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> Both style names are generated by default now. However, if the <tt>
|
|
-no-old-metatable-bindings</tt> option is used, then the backward
|
|
compatible names are not generated in addition to ordinary ones.</p>
|
|
<h3><a name="Lua_nn15">29.3.8 C++ inheritance</a></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">29.3.9 Pointers, references, values, and arrays</a>
|
|
</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">29.3.10 C++ overloaded functions</a></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 method spam(short) effectively ignored,
|
|
example.i:11: Warning 509: as it is shadowed by spam(int).
|
|
</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">29.3.11 C++ operators</a></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="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>
|
|
<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>__unm__</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 (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>
|
|
<p> C++ operators are mapped to Lua predefined metafunctions. Class
|
|
inherits from its bases the following list of metafunctions ( thus
|
|
inheriting the folloging operators and pseudo-operators):</p>
|
|
<ul>
|
|
<li><tt>__add__</tt></li>
|
|
<li><tt>__sub__</tt></li>
|
|
<li><tt>__mul__</tt></li>
|
|
<li><tt>__div__</tt></li>
|
|
<li><tt>__unm__</tt></li>
|
|
<li><tt>__mod__</tt></li>
|
|
<li><tt>__call__</tt></li>
|
|
<li><tt>__pow__</tt></li>
|
|
<li><tt>__concat__</tt></li>
|
|
<li><tt>__eq__</tt></li>
|
|
<li><tt>__lt__</tt></li>
|
|
<li><tt>__le__</tt></li>
|
|
<li><tt>__len__</tt></li>
|
|
<li><tt>__getitem__</tt></li>
|
|
<li><tt>__setitem__</tt></li>
|
|
<li><tt>__tostring</tt> used internally by Lua for tostring() function.
|
|
__str__ is mapped to this function</li>
|
|
</ul>
|
|
<p>No other lua metafunction is inherited. For example, __gc is not
|
|
inherited and must be redefined in every class. <tt>__tostring</tt> is
|
|
subject to a special handling. If absent in class and in class bases, a
|
|
default one will be provided by SWIG.</p>
|
|
<h3><a name="Lua_nn19">29.3.12 Class extension with %extend</a></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">29.3.13 Using %newobject to release memory</a></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 <a href="#Customization_ownership">
|
|
%newobject directive</a>.</p>
|
|
<div class="code">
|
|
<pre>%newobject foo;
|
|
...
|
|
char *foo();
|
|
</pre>
|
|
</div>
|
|
<p> This will release the allocated memory.</p>
|
|
<h3><a name="Lua_nn21">29.3.14 C++ templates</a></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_nn22">29.3.15 C++ Smart Pointers</a></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_nn23">29.3.16 C++ Exceptions</a></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 an error string.</p>
|
|
<p> However it's not so simple 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 to 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. (This is 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 an additional <tt>%apply</tt>
|
|
statement, to tell 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: it 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="#Customization_exception">
|
|
Exception handling with %exception</a>" section, for more details on how
|
|
to add exception specification to functions or globally (respectively).</p>
|
|
<h3><a name="Lua_namespaces">29.3.17 Namespaces</a></h3>
|
|
<p> C++ namespaces are supported via the %nspace feature.</p>
|
|
<p> Namespaces are mapped into Lua tables. Each of those tables contains
|
|
names that were defined within an appropriate namespace. Namespace
|
|
hierarchies (a.k.a nested namespaces) are preserved. Consider the
|
|
following C++ code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%nspace MyWorld::World;
|
|
%nspace MyWorld::Nested::Dweller;
|
|
|
|
int module_function() { return 7; }
|
|
int module_variable = 9;
|
|
|
|
namespace MyWorld {
|
|
class World {
|
|
public:
|
|
World() : world_max_count(9) {}
|
|
int create_world() { return 17; }
|
|
const int world_max_count; // = 9
|
|
};
|
|
namespace Nested {
|
|
class Dweller {
|
|
public:
|
|
enum Gender { MALE = 0, FEMALE = 1 };
|
|
static int count() { return 19; }
|
|
};
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Now, from Lua usage is as follows:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(example.module_function())
|
|
7.0
|
|
> print(example.module_variable)
|
|
9.0
|
|
> print(example.MyWorld.World():create_world())
|
|
17.0
|
|
> print(example.MyWorld.World().world_max_count)
|
|
9.0
|
|
> print(example.MyWorld.Nested.Dweller.MALE)
|
|
0
|
|
> print(example.MyWorld.Nested.Dweller.count())
|
|
19.0
|
|
</pre>
|
|
</div>
|
|
<p> The hierarchies in Lua are the same as the C++ hierarchies when
|
|
using <tt>%nspace</tt>, however, we could instead completely change
|
|
these hierarchies with <tt>%nspacemove</tt>. Consider the code above
|
|
with the two <tt>%nspace</tt> lines of code removed and replaced with
|
|
the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%nspacemove(DifferentWorld::SubSpace1::SubSpace2) MyWorld::World;
|
|
%nspacemove(DifferentWorld) MyWorld::Nested::Dweller;
|
|
</pre>
|
|
</div>
|
|
<p> The Lua code uses the completely modified hierarchies:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(example.module_function())
|
|
7.0
|
|
> print(example.module_variable)
|
|
9.0
|
|
> print(example.DifferentWorld.SubSpace1.SubSpace2.World():create_world())
|
|
17.0
|
|
> print(example.DifferentWorld.SubSpace1.SubSpace2.World().world_max_count)
|
|
9.0
|
|
> print(example.DifferentWorld.Dweller.MALE)
|
|
0
|
|
> print(example.DifferentWorld.Dweller.count())
|
|
19.0
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Lua_nn27">29.3.17.1 Compatibility Note</a></h4>
|
|
<p> The nspace feature was first supported by the Lua module in
|
|
SWIG-3.0.0</p>
|
|
<p> If SWIG is running in a backwards compatible way, i.e. without the <tt>
|
|
-no-old-metatable-bindings</tt> option, then additional old-style names
|
|
are generated (notice the underscore):</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(example.MyWorld.Nested.Dweller_MALE)
|
|
0
|
|
> print(example.MyWorld.Nested.Dweller_count())
|
|
19.0
|
|
</pre>
|
|
</div>
|
|
<p> The ability to move symbols into different namespaces via <tt>
|
|
%nspacemove</tt> was introduced in SWIG-4.3.0.</p>
|
|
<h4><a name="Lua_nn29">29.3.17.2 Names</a></h4>
|
|
<p> If SWIG is launched without <tt>-no-old-metatable-bindings</tt>
|
|
option, then it enters backward-compatible mode. While in this mode, it
|
|
tries to generate additional names for static functions, class static
|
|
constants and class enums. Those names are in a form <tt>
|
|
$classname_$symbolname</tt> and are added to the scope surrounding the
|
|
class. If %nspace is enabled, then class namespace is taken as scope.
|
|
If there is no namespace, or %nspace is disabled, then module is
|
|
considered a class namespace.</p>
|
|
<p> Consider the following C++ code</p>
|
|
<div class="code">
|
|
<pre>%module example
|
|
%nspace MyWorld::Test;
|
|
namespace MyWorld {
|
|
class Test {
|
|
public:
|
|
enum { TEST1 = 10, TEST2 }
|
|
static const int ICONST = 12;
|
|
};
|
|
class Test2 {
|
|
public:
|
|
enum { TEST3 = 20, TEST4 }
|
|
static const int ICONST2 = 23;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> When in backward compatible mode, in addition to the usual names,
|
|
the following ones will be generated (notice the underscore):</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
9
|
|
> print(example.MyWorld.Test_TEST1) -- Test has %nspace enabled
|
|
10
|
|
> print(example.MyWorld.Test_ICONST) -- Test has %nspace enabled
|
|
12
|
|
> print(example.Test2_TEST3) -- Test2 doesn't have %nspace enabled
|
|
20
|
|
> print(example.Test2_ICONST2) -- Test2 doesn't have %nspace enabled
|
|
23
|
|
>
|
|
</pre>
|
|
</div>
|
|
<p> There is a slight difference with enums when in C mode. As per C
|
|
standard, enums from C structures are exported to surrounding scope
|
|
without any prefixing. Pretending that Test2 is a struct, not class,
|
|
that would be:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(example.TEST3) -- NOT Test2_TEST3
|
|
20
|
|
>
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Lua_nn30">29.3.17.3 Inheritance</a></h4>
|
|
<p> The internal organization of inheritance has changed. Consider the
|
|
following C++ code:</p>
|
|
<div class="code">
|
|
<pre>%module example
|
|
class Base {
|
|
public:
|
|
int base_func()
|
|
};
|
|
class Derived : public Base {
|
|
public:
|
|
int derived_func()
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p>Lets assume for a moment that class member functions are stored in <tt>
|
|
.fn</tt> table. Previously, when classes were exported to Lua during
|
|
module initialization, for every derived class all service tables <tt>
|
|
ST(i.e. ".fn")</tt> were squashed and added to corresponding derived
|
|
class <tt>ST</tt>: Everything from <tt>.fn</tt> table of class Base was
|
|
copied to <tt>.fn</tt> table of class Derived and so on. This was a
|
|
recursive procedure, so in the end the whole inheritance tree of
|
|
derived class was squashed into derived class.</p>
|
|
<p> That means that any changes done to class Base after module
|
|
initialization wouldn't affect class Derived:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
base = example.Base()
|
|
der = example.Derived()
|
|
> print(base.base_func)
|
|
function: 0x1367940
|
|
> getmetatable(base)[".fn"].new_func = function (x) return x -- Adding new function to class Base (to class, not to an instance!)
|
|
> print(base.new_func) -- Checking this function
|
|
function
|
|
> print(der.new_func) -- Wouldn't work. Derived doesn't check Base any more.
|
|
nil
|
|
>
|
|
</pre>
|
|
</div>
|
|
<p> This behaviour was changed. Now unless -squash-bases option is
|
|
provided, Derived stores a list of its bases and if some symbol is not
|
|
found in its own service tables then its bases are searched for it.
|
|
Option -squash-bases will effectively return old behaviour.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
> print(der.new_func) -- Now it works
|
|
function
|
|
>
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Lua_nn24">29.4 Typemaps</a></h2>
|
|
<p>This section explains what typemaps are and how to use them. The
|
|
default wrapping 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 wrapping. This section will be
|
|
explaining how to use typemaps to best effect</p>
|
|
<h3><a name="Lua_nn25">29.4.1 What is a typemap?</a></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_nn26">29.4.2 Using typemaps</a></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_typemap_arrays">29.4.3 Typemaps and arrays</a></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, size_t len);
|
|
extern void sort_double(double* arr, size_t 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 it's a bit tedious. More details can be found in the <a href="#Library_carrays">
|
|
carrays.i</a> documentation.</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 %apply 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 functions for manipulating C integer arrays
|
|
%array_functions(int, int)
|
|
|
|
extern void sort_int(int* arr, size_t len); // the function to wrap
|
|
|
|
// using typemaps
|
|
%include <typemaps.i>
|
|
%apply (double *INOUT, int) {(double* arr, size_t len)};
|
|
|
|
extern void sort_double(double* arr, size_t len); // the function to wrap
|
|
</pre>
|
|
</div>
|
|
<p>Once wrapped, 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_typemaps_ptr_ptr_functions">29.4.4 Typemaps and
|
|
pointer-pointer functions</a></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 wrapping 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 it's 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 an iMath* which is returned with the int (ok)
|
|
ptr=nil -- the iMath* will be GC'ed as normal
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Lua_writing_typemaps">29.5 Writing typemaps</a></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 wrapping, 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, and look at the existing 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 an
|
|
idea to base your work on).</p>
|
|
<h3><a name="Lua_typemaps_write">29.5.1 Typemaps you can write</a></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_nn31">29.5.2 SWIG's Lua-C API</a></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
|
|
necessary 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> This 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 wrapped 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 wrapped 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_nn32">29.6 Customization of your Bindings</a></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_nn33">29.6.1 Writing your own custom wrappers</a></h3>
|
|
<p> Sometimes, it may be necessary to add your own special functions,
|
|
which bypass the normal SWIG wrapper 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 wrapper 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_nn34">29.6.2 Adding additional Lua code</a></h3>
|
|
<p> As well as adding additional C/C++ code, it's 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
|
|
an 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_nn35">29.7 Details on the Lua binding</a></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. It's mainly for people who need to know what's going on within
|
|
the code.</i></p>
|
|
<h3><a name="Lua_nn36">29.7.1 Binding global data into the module.</a></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_nn37">29.7.2 Userdata and Metatables</a></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). It's 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 functions
|
|
inside. However to allow the intuitive use of the userdata, SWIG 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 a new object is
|
|
instantiated, the metatable is found in the registry and the userdata
|
|
associated with the metatable. Currently, derived classes make a
|
|
complete copy of the base class' table and then add on their own
|
|
additional functions.</p>
|
|
<p> Some of the internals can be seen by looking at the metatable of a
|
|
class:</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 class' 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 it's 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 wrapped
|
|
classes/structs use the same 'swig_lua_userdata' structure. Though the
|
|
opaque structures 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 class' metatable.
|
|
The current implementation is a bit rough as it will add any member
|
|
function beginning with '__' into the metatable too, assuming it's an
|
|
operator overload.</p>
|
|
<h3><a name="Lua_nn38">29.7.3 Memory management</a></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 wrapped 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) 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="Octave">30 SWIG and Octave</a></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_nn4">Command-line options</a></li>
|
|
<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>
|
|
<ul>
|
|
<li><a href="#Octave_smart_pointers_shared_ptr">The shared_ptr Smart
|
|
Pointer</a></li>
|
|
<li><a href="#Octave_smart_pointers_generic">Generic Smart Pointers</a></li>
|
|
</ul>
|
|
</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="https://octave.org/">Octave web site</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">30.1 Preliminaries</a></h2>
|
|
<p> SWIG is regularly tested against the following versions of Octave:
|
|
5.2, 6.4. SWIG 4.2.1 has also been manually tested with 7.3, 8.4 and
|
|
9.0.</p>
|
|
<p> Every effort is made to maintain backward compatibility with older
|
|
versions of Octave. This cannot be guaranteed however, as in recent
|
|
times new Octave releases have required nontrivial updates to SWIG,
|
|
which may break backward compatibility for older Octave versions
|
|
against which SWIG is not regularly tested.</p>
|
|
<p> The SWIG runtime exports the function <tt>swig_octave_prereq()</tt>
|
|
for checking the version of Octave.</p>
|
|
<h2><a name="Octave_nn3">30.2 Running SWIG</a></h2>
|
|
<p> Let's start with a very simple SWIG interface file, example.i:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module swigexample
|
|
%{
|
|
#include "example.h"
|
|
%}
|
|
int gcd(int x, int y);
|
|
extern double Foo; </pre>
|
|
</div>
|
|
<p> To build an Octave module when wrapping C code, run SWIG using the <tt>
|
|
-octave</tt> option:</p>
|
|
<div class="shell">
|
|
<pre>$ swig -octave -o example_wrap.cpp example.i </pre>
|
|
</div>
|
|
<p> The <tt>-c++</tt> option is also required when wrapping C++ code:</p>
|
|
<div class="shell">
|
|
<pre>$ swig -octave -c++ -o example_wrap.cpp example.i </pre>
|
|
</div>
|
|
<h3><a name="Octave_nn4">30.2.1 Command-line options</a></h3>
|
|
<p> The swig command line has a number of options you can use, like to
|
|
redirect its output. Use <tt>swig -help</tt> to learn about these.
|
|
Options specific to the Octave module are:</p>
|
|
<div class="shell">
|
|
<pre>$ swig -octave -help
|
|
...
|
|
Octave Options (available with -octave)
|
|
-globals <em>name</em> - Set <em>name</em> used to access C global variables [default: 'cvar']
|
|
Use '.' to load C global variables into module namespace
|
|
-opprefix <em>str</em> - Prefix <em>str</em> for global operator functions [default: 'op_']
|
|
</pre>
|
|
</div>
|
|
<p> The<em> -globals</em> option sets the name of the variable which is
|
|
the namespace for C global variables exported by the module. The
|
|
special name "." loads C global variables into the module namespace,
|
|
i.e. alongside C functions and structs exported by the module. The<em>
|
|
-opprefix</em> options sets the prefix of the names of global/friend <a href="#Octave_nn18">
|
|
operator</a> functions.</p>
|
|
<h3><a name="Octave_nn5">30.2.2 Compiling a dynamic module</a></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++ -o example_wrap.cpp example.i
|
|
$ mkoctfile example_wrap.cpp 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 "swigexample.oct", which contains the
|
|
compiled extension module. Loading it into Octave is then a matter of
|
|
invoking</p>
|
|
<div class="targetlang">
|
|
<pre>octave:1> swigexample</pre>
|
|
</div>
|
|
<h3><a name="Octave_nn6">30.2.3 Using your module</a></h3>
|
|
<p> Assuming all goes well, you will be able to do this:
|
|
<br></p>
|
|
<div class="targetlang">
|
|
<pre>$ octave -q
|
|
octave:1> swigexample
|
|
octave:2> swigexample.gcd(4, 6)
|
|
ans = 2
|
|
octave:3> swigexample.cvar.Foo
|
|
ans = 3
|
|
octave:4> swigexample.cvar.Foo=4;
|
|
octave:5> swigexample.cvar.Foo
|
|
ans = 4 </pre>
|
|
</div>
|
|
<h2><a name="Octave_nn7">30.3 A tour of basic C/C++ wrapping</a></h2>
|
|
<h3><a name="Octave_nn8">30.3.1 Modules</a></h3>
|
|
<p> The SWIG module directive specifies the name of the Octave module.
|
|
If you specify "module swigexample", then in Octave everything in the
|
|
module will be accessible under "swigexample", 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>swigexample</tt>, it will try to
|
|
find the ".m" or ".oct" file that defines the function "swigexample".
|
|
You therefore need to make sure that "swigexample.oct" is in Octave's
|
|
search path, which can be specified with the environment variable
|
|
"OCTAVE_PATH".</p>
|
|
<p> To load an Octave module, simply type its name:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
octave:1> swigexample;
|
|
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> Modules can also be loaded from within functions, even before being
|
|
loaded in the base context. If the module is also used in the base
|
|
context, however, it must first be loaded again:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
octave:1> function l = my_lcm(a, b)
|
|
> swigexample
|
|
> l = abs(a*b)/swigexample.gcd(a, b);
|
|
> endfunction
|
|
octave:2> my_lcm(4, 6)
|
|
ans = 12
|
|
octave:3> swigexample.gcd(4, 6)
|
|
error: can't perform indexing operations for <unknown type> type
|
|
octave:3> swigexample;
|
|
octave:4> swigexample.gcd(4, 6)
|
|
ans = 2
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Octave_nn9">30.3.2 Functions</a></h3>
|
|
<p> Global functions are wrapped as new Octave built-in functions. For
|
|
example,</p>
|
|
<div class="code">
|
|
<pre>%module swigexample
|
|
int fact(int n); </pre>
|
|
</div>
|
|
<p> creates a built-in function <tt>swigexample.fact(n)</tt> that works
|
|
exactly like you think it does:</p>
|
|
<div class="targetlang">
|
|
<pre>octave:1> swigexample.fact(4)
|
|
24 </pre>
|
|
</div>
|
|
<h3><a name="Octave_nn10">30.3.3 Global variables</a></h3>
|
|
<p> Global variables are a little special in Octave. Given a global
|
|
variable:</p>
|
|
<div class="code">
|
|
<pre>%module swigexample
|
|
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> swigexample;
|
|
octave:2> c=swigexample.cvar.Foo
|
|
c = 3
|
|
octave:3> swigexample.cvar.Foo=4;
|
|
octave:4> c
|
|
c = 3
|
|
octave:5> swigexample.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 swigexample
|
|
%immutable;
|
|
extern double Foo;
|
|
%mutable;
|
|
</pre>
|
|
</div>
|
|
<p> SWIG will allow 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> swigexample
|
|
octave:2> swigexample.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> swigexample;
|
|
octave:2> swigexample.PI=3.142;
|
|
octave:3> swigexample.PI
|
|
ans = 3.1420 </pre>
|
|
</div>
|
|
<h3><a name="Octave_nn11">30.3.4 Constants and enums</a></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 swigexample
|
|
%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>swigexample.ICONST=42
|
|
swigexample.SCONST="Hello World"
|
|
swigexample.SUNDAY=0
|
|
.... </pre>
|
|
</div>
|
|
<h3><a name="Octave_nn12">30.3.5 Pointers</a></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 swigexample
|
|
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> swigexample;
|
|
octave:2> f=swigexample.fopen("w", "junk");
|
|
octave:3> swigexample.fputs("Hello world", f);
|
|
octave:4> swigexample.fclose(f);
|
|
</pre>
|
|
</div>
|
|
<p> Simply printing the value of a wrapped C++ type will print its
|
|
typename. E.g.,</p>
|
|
<div class="targetlang">
|
|
<pre>octave:1> swigexample;
|
|
octave:2> f=swigexample.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> swigexample;
|
|
octave:2> f=swigexample.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>
|
|
<p> NULL C/C++ pointers are represented by the Octave null matrix, <tt>
|
|
[]</tt>.</p>
|
|
<h3><a name="Octave_nn13">30.3.6 Structures and C++ classes</a></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> swigexample;
|
|
octave:2> p=swigexample.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> swigexample;
|
|
octave:2> p1=swigexample.Point(3, 5);
|
|
octave:3> p2=swigexample.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">30.3.7 C++ inheritance</a></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">30.3.8 C++ overloaded functions</a></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">30.3.9 C++ operators</a></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>
|
|
<p> Octave can also utilise friend (i.e. non-member) operators with a
|
|
simple %rename: see the example in the Examples/octave/operator
|
|
directory.</p>
|
|
<p> Octave has several operators for which no corresponding C++
|
|
operators exist. For example, the Octave code</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
x=[a,b,c];
|
|
</pre>
|
|
</div>
|
|
<p> calls the Octave operator <tt>horzcat</tt> of the class of <tt>a</tt>
|
|
. Hence, if <tt>a</tt> is of type <tt>swig_ref</tt> you can write an
|
|
overload for this operator for your wrapped C++ class by placing a file
|
|
<tt>@swig_ref/horzcat.m</tt> in the Octave load path (like for every
|
|
Octave class, see <a href="https://docs.octave.org/latest/Creating-a-Class.html">
|
|
Creating a Class</a>). This Octave function file is then called whenever
|
|
the above Octave code is executed for a variable of type <tt>swig_ref</tt>
|
|
.</p>
|
|
<h3><a name="Octave_nn19">30.3.10 Class extension with %extend</a></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>
|
|
<p> Similarly, Octave can use the <tt>__float__</tt> method to convert
|
|
an object to a numeric value.</p>
|
|
<p> Octave 3.8.0 and later versions will also map unary functions X() to
|
|
the corresponding <tt>__X__</tt> method, where X includes: abs(),
|
|
acos(), acosh(), angle(), arg(), asin(), asinh(), atan(), atanh(),
|
|
cbrt(), ceil(), conj(), cos(), cosh(), dawson(), erf(), erfc(),
|
|
erfcinv(), erfcx(), erfi(), erfinv(), exp(), expm1(), finite(), fix(),
|
|
floor(), gamma(), imag(), isalnum(), isalpha(), isascii(), iscntrl(),
|
|
isdigit(), isgraph(), isinf(), islower(), isna(), isnan(), isprint(),
|
|
ispunct(), isspace(), isupper(), isxdigit(), lgamma(), log(), log10(),
|
|
log1p(), log2(), real(), round(), roundb(), signbit(), signum(), sin(),
|
|
sinh(), sqrt(), tan(), tanh(), toascii(), tolower(), toupper()</p>
|
|
<h3><a name="Octave_nn20">30.3.11 C++ templates</a></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 swigexample
|
|
%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 swigexample
|
|
%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">30.3.12 C++ Smart Pointers</a></h3>
|
|
<h4><a name="Octave_smart_pointers_shared_ptr">30.3.12.1 The shared_ptr
|
|
Smart Pointer</a></h4>
|
|
<p> The C++11 standard provides <tt>std::shared_ptr</tt> which was
|
|
derived from the Boost implementation, <tt>boost::shared_ptr</tt>. Both
|
|
of these are available for Octave in the SWIG library and usage is
|
|
outlined in the <a href="#Library_std_shared_ptr">shared_ptr smart
|
|
pointer</a> library section.</p>
|
|
<h4><a name="Octave_smart_pointers_generic">30.3.12.2 Generic Smart
|
|
Pointers</a></h4>
|
|
<p> C++ smart pointers are fully supported as in other modules.</p>
|
|
<h3><a name="Octave_nn22">30.3.13 Directors (calling Octave from C++
|
|
code)</a></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">30.3.14 Threads</a></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">30.3.15 Memory management</a></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. 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">30.3.16 STL support</a></h3>
|
|
<p> Various STL library files are provided for wrapping STL containers.</p>
|
|
<h3><a name="Octave_nn26">30.3.17 Matrix typemaps</a></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">31 SWIG and Perl5</a></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>
|
|
<li><a href="#Perl5_directors">Cross language polymorphism</a>
|
|
<ul>
|
|
<li><a href="#Perl5_nn48">Enabling directors</a></li>
|
|
<li><a href="#Perl5_nn49">Director classes</a></li>
|
|
<li><a href="#Perl5_nn50">Ownership and object destruction</a></li>
|
|
<li><a href="#Perl5_nn51">Exception unrolling</a></li>
|
|
<li><a href="#Perl5_nn52">Overhead and code bloat</a></li>
|
|
<li><a href="#Perl5_nn53">Typemaps</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 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. As of SWIG
|
|
4.1.0, the minimum version of Perl we aim to support is Perl 5.8.0. We
|
|
can no longer easily test with older versions, and they no longer seem
|
|
to be in active use.</p>
|
|
<h2><a name="Perl5_nn2">31.1 Overview</a></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">31.2 Preliminaries</a></h2>
|
|
<p> To build a Perl5 module, run SWIG using the <tt>-perl</tt> or <tt>
|
|
-perl5</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">31.2.1 Getting the right header files</a></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/perl/5.14/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 located, an easy way to find out is to ask
|
|
Perl itself:</p>
|
|
<div class="code">
|
|
<pre>
|
|
$ perl -e 'use Config; print "$Config{archlib}\n";'
|
|
/usr/lib/perl/5.14
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Perl5_nn5">31.2.2 Compiling a dynamic module</a></h3>
|
|
<p> The preferred approach to building an extension module is to compile
|
|
it into a shared object file or DLL. Assuming you have code you need to
|
|
link to in a file called <tt>example.c</tt>, you will need to compile
|
|
your program using commands like this (shown for Linux):</p>
|
|
<div class="code">
|
|
<pre>
|
|
$ swig -perl example.i
|
|
$ gcc -fPIC example.c
|
|
$ gcc -fPIC -c example_wrap.c -I/usr/lib/perl/5.14/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="https://github.com/swig/swig/wiki">
|
|
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">31.2.3 Building a dynamic module with MakeMaker</a>
|
|
</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">31.2.4 Building a static version of Perl</a></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/perl/5.14/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">31.2.5 Using the module</a></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: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) 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/perl/5.14/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/perl/5.14/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">31.2.6 Compilation problems and compiling with
|
|
C++</a></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++ -fPIC -c example.cxx
|
|
$ g++ -fPIC -c example_wrap.cxx -I/usr/lib/perl/5.14/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
|
|
$ CC -Kpic -c example.cxx
|
|
$ CC -Kpic -c example_wrap.cxx -I/usr/lib/perl/5.14/i386-linux/CORE
|
|
$ CC -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++ -fPIC -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}\n";'
|
|
</pre>
|
|
</div>
|
|
<p> So you could also compile the wrapper like</p>
|
|
<div class="code">
|
|
<pre>
|
|
$ g++ -fPIC -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE \
|
|
`perl -MConfig -e '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="https://www.swig.org/mail.html">swig-user mailing list</a>.</p>
|
|
<h3><a name="Perl5_nn10">31.2.7 Compiling for 64-bit platforms</a></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">31.3 Building Perl Extensions under Windows</a></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">31.3.1 Running SWIG from Developer Studio</a></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.
|
|
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">31.3.2 Using other compilers</a></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">31.4 The low-level interface</a></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">31.4.1 Functions</a></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">31.4.2 Global variables</a></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">31.4.3 Constants</a></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">31.4.4 Pointers</a></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">31.4.5 Structures</a></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 Perl 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">31.4.6 C++ classes</a></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">31.4.7 C++ classes and type-checking</a></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">31.4.8 C++ overloaded functions</a></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">31.4.9 Operators</a></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">31.4.10 Modules and packages</a></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">31.5 Input and output parameters</a></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 *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">31.6 Exception handling</a></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>
|
|
<h2><a name="Perl5_nn27">31.7 Remapping datatypes with typemaps</a></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">31.7.1 A simple typemap example</a></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">31.7.2 Perl5 typemaps</a></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();
|
|
sv_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(check)</tt></p>
|
|
<div class="indent"> Check value of input parameter.</div>
|
|
<h3><a name="Perl5_nn30">31.7.3 Typemap variables</a></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">31.7.4 Useful functions</a></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">31.8 Typemap Examples</a></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">31.8.1 Converting a Perl5 array to a char **</a>
|
|
</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">31.8.2 Return values</a></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($result, (IV) *($1));
|
|
argvi++;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Perl5_nn35">31.8.3 Returning values from arguments</a></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">31.8.4 Accessing array structure members</a></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 because 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">31.8.5 Turning Perl references into C pointers</a>
|
|
</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">31.8.6 Pointer handling</a></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_IsOK(SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
|
|
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_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
}
|
|
</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_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Perl5_nn39">31.9 Proxy classes</a></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">31.9.1 Preliminaries</a></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">31.9.2 Structure and class wrappers</a></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 implementation details 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">31.9.3 Object Ownership</a></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
|
|
calling the <tt>DISOWN</tt> method (which will delete the object from
|
|
the internal <tt>%OWNER</tt> hash).</p>
|
|
<p> The <tt>%OWNER</tt> hash is an implementation detail, discussed here
|
|
only to help clarify the operation of <tt>ACQUIRE</tt> and <tt>DISOWN</tt>
|
|
. You should not access <tt>%OWNER</tt> directly - the details of how it
|
|
works (and possibly even its existence) may change in future SWIG
|
|
versions.</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">31.9.4 Nested Objects</a></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">31.9.5 Proxy Functions</a></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">31.9.6 Inheritance</a></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">31.9.7 Modifying the proxy methods</a></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="#Customization_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">31.10 Adding additional Perl code</a></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>
|
|
<h2><a name="Perl5_directors">31.11 Cross language polymorphism</a></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 Perl. In particular, if a C++ class has been extended in Perl
|
|
(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 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 Perl implementations lower in the
|
|
inheritance chain. The upshot is that C++ classes can be extended in
|
|
Perl and from C++ these extensions look exactly like native C++
|
|
classes. Neither C++ code nor Perl 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="Perl5_nn48">31.11.1 Enabling directors</a></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 the virtual methods in class Foo
|
|
%feature("director") Foo;
|
|
</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 the 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 Perl side you can define</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
use mymodule;
|
|
|
|
package MyFoo;
|
|
use base 'mymodule::Foo';
|
|
|
|
sub one {
|
|
print "one from Perl\n";
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Perl5_nn49">31.11.2 Director classes</a></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 Perl
|
|
proxy classes. The director classes store a pointer to their underlying
|
|
Perl object and handle various issues related to object ownership.</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). Virtual methods that have a final specifier
|
|
are unsurprisingly excluded. Thus the virtual method calls, whether
|
|
they originate in C++ or in Perl 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 Perl 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 Perl. 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 Perl, the Perl API is
|
|
used to call the method of the underlying Perl object (after which the
|
|
usual virtual method resolution in Perl 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 Perl, unless
|
|
there's a good reason not to. The reason for this is simple: Perl has
|
|
the most "extended" implementation of the method. This assertion is
|
|
guaranteed, since at a minimum the Perl 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 Perl 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 Perl
|
|
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 Perl, SWIG creates an instance of the original C++ class.
|
|
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
|
|
Perl.</p>
|
|
<h3><a name="Perl5_nn50">31.11.3 Ownership and object destruction</a></h3>
|
|
<p> Memory management issues are slightly more complicated with
|
|
directors than for proxy classes alone. Perl instances hold a pointer
|
|
to the associated C++ director object, and the director in turn holds a
|
|
pointer back to a Perl 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
|
|
director class increments the reference count of the Perl object. When
|
|
the director class is deleted it decrements the reference count.
|
|
Assuming no outstanding references to the Perl object remain, the Perl
|
|
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> Also note that due to the proxy implementation, the <tt>DESTROY()</tt>
|
|
method on directors can be called for several reasons, many of which
|
|
have little to do with the teardown of an object instance. To help
|
|
disambiguate this, a second argument is added to the <tt>DESTROY()</tt>
|
|
call when a C++ director object is being released. So, to avoid running
|
|
your clean-up code when an object is not really going away, or after it
|
|
has already been reclaimed, it is suggested that custom destructors in
|
|
Perl subclasses looks something like:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
sub DESTROY {
|
|
my($self, $final) = @_;
|
|
if($final) {
|
|
# real teardown code
|
|
}
|
|
shift->SUPER::DESTROY(@_);
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Perl5_nn51">31.11.4 Exception unrolling</a></h3>
|
|
<p> With directors routing method calls to Perl, 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 Perl. 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 Perl error state after each method call
|
|
from a director into Perl, and throw a C++ exception if an error
|
|
occurred. This exception can be caught in C++ to implement an error
|
|
handler.</p>
|
|
<p> It may be the case that a method call originates in Perl, travels up
|
|
to C++ through a proxy class, and then back into Perl via a director
|
|
method. If an exception occurs in Perl 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 Perl error state is still set when
|
|
Swig::DirectorMethodException is thrown, Perl will register the
|
|
exception as soon as the C wrapper function returns.</p>
|
|
<h3><a name="Perl5_nn52">31.11.5 Overhead and code bloat</a></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 Perl 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 Perl. Relative to the speed of Perl execution this is probably
|
|
completely negligible. For worst case routing, a method call that
|
|
ultimately resolves in C++ may take one extra detour through Perl in
|
|
order to ensure that the method does not have an extended Perl
|
|
implementation. This could result in a noticeable overhead in some
|
|
cases.</p>
|
|
<p> Although directors make it natural to mix native C++ objects with
|
|
Perl objects (as director objects) via a common base class pointer, one
|
|
should be aware of the obvious fact that method calls to Perl 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
|
|
Perl.</p>
|
|
<h3><a name="Perl5_nn53">31.11.6 Typemaps</a></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>
|
|
<HR NOSHADE>
|
|
<h1><a name="Php">32 SWIG and PHP</a></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 -noproxy</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>
|
|
<li><a href="#Php_nn2_6_5">Specifying Implemented Interfaces</a></li>
|
|
<li><a href="#Php_nn2_6_6">Dynamic Properties</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> In this chapter, we discuss SWIG's support of PHP. Currently any
|
|
PHP8 release should work.</p>
|
|
<p> Support for PHP8 was added in SWIG 4.1.0. Support for PHP7 was added
|
|
in SWIG 3.0.11 and removed in 4.2.0. Support for PHP5 was removed in
|
|
SWIG 4.0.0 and support for PHP4 was removed in SWIG 1.3.37. There never
|
|
was a PHP6 release.</p>
|
|
<p> In order to use this module, you will need to have a copy of the PHP
|
|
include files to compile the SWIG generated C/C++ sources. 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">32.1 Generating PHP Extensions</a></h2>
|
|
<p> To build a PHP extension, run swig using the <tt>-php</tt> option
|
|
(you can also use <tt>-php7</tt> - PHP7 and PHP8 have a largely
|
|
compatible C extension API, hence the same option name has been used
|
|
for both). For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
swig -php example.i
|
|
</pre>
|
|
</div>
|
|
<p> This will produce 2 files: example_wrap.c and php_example.h. 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.</p>
|
|
<p> If the interface file uses <tt>%pragma(php) include=</tt>... or <tt>
|
|
%pragma(php) code=</tt>... then SWIG will also generate a third file, <tt>
|
|
example.php</tt> to contain what these specify. In SWIG < 4.1.0, this
|
|
third file was always generated as it defined the PHP classes, etc (but
|
|
this is now done via C code in <tt>example_wrap.c</tt>) and also
|
|
contained code to dynamically load the extension (but this used the PHP
|
|
<tt>dl()</tt> function, which isn't recommended nowadays).</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>. The generated
|
|
C++ wrapper will be called example_wrap.cxx. You can specify a
|
|
different extension for the C++ wrapper using <tt>-cppext</tt> - e.g.
|
|
if you want example_wrap.cc use <tt>-cppext cc</tt>.</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).</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">32.1.1 Building a loadable extension</a></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="shell">
|
|
<pre>
|
|
$ gcc `php-config --includes` -fPIC -c example_wrap.c example.c
|
|
$ gcc -shared example_wrap.o example.o -o example.so
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Php_nn1_3">32.1.2 Using PHP Extensions</a></h3>
|
|
<p> To test the extension from a PHP script, you first need to tell PHP
|
|
to load it. The recommended (and simplest!) way to do this is to copy
|
|
it to PHP's default extension directory and add a line like this to the
|
|
<tt>[PHP]</tt> section of <tt>php.ini</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
extension=modulename
|
|
</pre>
|
|
</div>
|
|
<p> If the module is not in PHP's default extension directory, you also
|
|
need to specify the path, in which case you'll also need to deal with
|
|
platform-specific naming - for example, on Linux:</p>
|
|
<div class="code">
|
|
<pre>
|
|
extension=/path/to/modulename.so
|
|
</pre>
|
|
</div>
|
|
<p> but on Microsoft Windows you'd need to use:</p>
|
|
<div class="code">
|
|
<pre>
|
|
extension=/path/to/php_modulename.dll
|
|
</pre>
|
|
</div>
|
|
<p> If you're using the PHP CLI SAPI it's possible (but not recommended)
|
|
to use the <a href="https://www.php.net/manual/en/function.dl.php">dl()
|
|
function</a> to load an extension at run time, by adding a line like
|
|
this to the start of each PHP script which uses your extension:</p>
|
|
<div class="code">
|
|
<pre>
|
|
dl("modulename"); // Load the module
|
|
</pre>
|
|
</div>
|
|
<p> Again, if the module isn't in PHP's default extension directory
|
|
you'll also need to specify the path and deal with that varying by
|
|
platform.</p>
|
|
<p> For security reasons PHP no longer supports <tt>dl()</tt> when
|
|
running PHP through a webserver, so this isn't an option there.</p>
|
|
<h2><a name="Php_nn2">32.2 Basic PHP interface</a></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. At
|
|
present SWIG doesn't have support for generating wrappers which make
|
|
use of PHP's namespace feature.</p>
|
|
<h3><a name="Php_nn2_1">32.2.1 Constants</a></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>
|
|
echo "PI = " . PI . "\n";
|
|
echo "E = " . E . "\n";
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Php_nn2_2">32.2.2 Global Variables</a></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>
|
|
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. To support additional types, you just need to
|
|
supply the standard <tt>in</tt> and <tt>out</tt> typemaps, which get
|
|
used because of the wrapping as <tt>_get()</tt> and <tt>_set()</tt>
|
|
functions.</p>
|
|
<p> SWIG honors the <tt>%immutable</tt> modifier by not generating a <tt>
|
|
_set</tt> method (so attempting to call it will give a PHP fatal error).
|
|
A <tt>_get</tt> method is still generated so this provides read-only
|
|
access to the variable from the PHP script.</p>
|
|
<p> At this time SWIG does not support custom accessor methods.</p>
|
|
<h3><a name="Php_nn2_3">32.2.3 Functions</a></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>
|
|
$a = foo(2);
|
|
$b = bar(3.5, -1.5);
|
|
$c = bar(3.5); # Use default argument for 2nd parameter
|
|
|
|
</pre>
|
|
</div>
|
|
<p> SWIG generates PHP type declarations for function parameters and
|
|
return types for PHP 8 and later.</p>
|
|
<p> You can control the generation of PHP type declarations using the
|
|
"php:type" %feature. This has three settings:</p>
|
|
<ul>
|
|
<li>
|
|
<p>If unset or set to "0" then no type declarations are generated, e.g.:
|
|
<tt>%feature("php:type", "0");</tt></p>
|
|
</li>
|
|
<li>
|
|
<p>If set to "1" then type declarations are generated for both
|
|
parameters and return types, e.g.: <tt>%feature("php:type", "1");</tt></p>
|
|
</li>
|
|
<li>
|
|
<p>The default setting is "compat", which is the same as "1" except no
|
|
return type declarations are generated for virtual methods for which
|
|
directors are enabled. This provides better compatibility for PHP
|
|
subclasses of wrapped virtual methods in existing SWIG-generated
|
|
bindings, e.g.: <tt>%feature("php:type", "compat");</tt></p>
|
|
</li>
|
|
</ul>
|
|
<p> If you have an existing PHP interface and are upgrading to SWIG >=
|
|
4.1.0 then the default "compat" setting should work well.</p>
|
|
<p> If you're writing a new set of bindings and<b> only targeting PHP8
|
|
or newer</b> then enabling type declarations everywhere probably makes
|
|
sense. It will only actually make a difference if you enable directors
|
|
and are wrapping C++ classes with virtual methods, but doing it anyway
|
|
means you won't forget to if the code you are wrapping later evolves to
|
|
have such classes and methods.</p>
|
|
<p> The type declaration information will make the generated source code
|
|
and compiler extension module larger, so you might want to turn off
|
|
type declarations if keeping these small is important to you. If you
|
|
find you need to turn off type declarations to fix a problem, please
|
|
let us know via our github issue tracker.</p>
|
|
<p> Note that being a SWIG feature this can be specified globally (like
|
|
above) or per class, per method, etc. See the <a href="#Customization_features">
|
|
%feature directives</a> section for full details of how to control at a
|
|
fine-grained level.</p>
|
|
<p> The PHP type information is specified via a "phptype" attribute on
|
|
"in" and "out" typemaps, and these have been added for all the typemaps
|
|
we supply for PHP. We don't currently support this for "argout"
|
|
templates, but probably will in a future version.</p>
|
|
<p> If you have written custom SWIG typemaps for PHP and want to add PHP
|
|
type declarations, then the syntax is very like how you'd specify the
|
|
type in PHP code, e.g. <tt>%typemap(in, phptype="int|string|Foo")</tt>
|
|
means the typemap accepts a PHP int or string or an object of class
|
|
Foo, <tt>%typemap(in, phptype="?int")</tt> means a PHP int or NULL,
|
|
etc. As well as the standard PHP type declaration types, SWIG also
|
|
understands the special type "SWIGTYPE" as an entry in phptype, which
|
|
means the PHP type corresponding to the type that this typemap matched
|
|
on - for a object this will give you the PHP class for the object, and
|
|
for a pointer to a non-class type it will give you the name of the PHP
|
|
class SWIG created for that pointer type.</p>
|
|
|
|
<!-- 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">32.2.4 Overloading</a></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">
|
|
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">32.2.5 Pointers and References</a></h3>
|
|
<p> Since SWIG 4.1.0, SWIG wraps C/C++ classes directly with PHP
|
|
objects. Pointers to other types are also wrapped as PHP objects -
|
|
mostly this is an implementation detail, but it's visible from PHP via <tt>
|
|
is_object()</tt> and similar. In earlier SWIG versions, PHP resources
|
|
were used to wrap both classes and pointers to other types.</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
|
|
|
|
$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
|
|
|
|
$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 REF.</p>
|
|
<p> In case you write your own typemaps, SWIG supports an attribute
|
|
called <tt>byref</tt>: if you set that, then SWIG will make sure that
|
|
the generated wrapper function will want the input parameter as a
|
|
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
|
|
|
|
$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">32.2.6 Structures and C++ classes</a></h3>
|
|
<p> SWIG wraps C++ structs and classes with PHP classes. Since SWIG
|
|
4.1.0, this is done entirely via PHP's C API - earlier SWIG versions
|
|
generated a PHP wrapper script which defined proxy classes which called
|
|
a set of flat functions which actually wrapped 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 PHP:</p>
|
|
<div class="code">
|
|
<pre>
|
|
<?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">32.2.6.1 Using -noproxy</a></h4>
|
|
<p> SWIG/PHP used to support a <tt>-noproxy</tt> option to flatten the
|
|
class structure and generate collections of named flat functions. This
|
|
is no longer supported as of SWIG 4.1.0.</p>
|
|
<h4><a name="Php_nn2_6_2">32.2.6.2 Constructors and Destructors</a></h4>
|
|
<p> The constructor is called when <tt>new Object()</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, 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">32.2.6.3 Static Member Variables</a></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>
|
|
echo "There have 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 have now been " . Ko::threats() . " threats\n";
|
|
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Php_nn2_6_4">32.2.6.4 Static Member Functions</a></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>
|
|
<p> would be executed in PHP as</p>
|
|
<div class="code">
|
|
<pre>
|
|
Ko::threats();
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Php_nn2_6_5">32.2.6.5 Specifying Implemented Interfaces</a></h4>
|
|
<p> PHP supports the concept of abstract interfaces which a class can
|
|
implement. Since SWIG 3.0.3, you can tell SWIG that a wrapped class
|
|
(for example <code>MyIterator</code>) implements the <code>Iterator</code>
|
|
interface like so:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap("phpinterfaces") MyIterator "Iterator"
|
|
</pre>
|
|
</div>
|
|
<p> If there are multiple interfaces, just list them separated by
|
|
commas.</p>
|
|
<h4><a name="Php_nn2_6_6">32.2.6.6 Dynamic Properties</a></h4>
|
|
<p> Historically PHP has supported dynamic class properties and SWIG has
|
|
implemented them too (because we implement the magic <tt>__get()</tt>, <tt>
|
|
__set()</tt> and <tt>__isset()</tt> methods we need to include explicit
|
|
handling).</p>
|
|
<p> PHP 8.2 <a href="https://wiki.php.net/rfc/deprecate_dynamic_properties">
|
|
deprecates dynamic class properties</a> - initially they'll warn, and
|
|
apparently they'll not work by default in PHP 9.0.</p>
|
|
<p> In PHP code dynamic properties can be enabled for a class by marking
|
|
that class with the attribute <tt>#[AllowDynamicProperties]</tt>.</p>
|
|
<p> To follow this PHP change, as of SWIG 4.1.0 you now need enable
|
|
dynamic properties for any classes you want to support them. To enable
|
|
for class <tt>Foo</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("php:allowdynamicproperties", 1) Foo;
|
|
</pre>
|
|
</div>
|
|
<p> or to enable them for all wrapped classes:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("php:allowdynamicproperties", 1);
|
|
</pre>
|
|
</div>
|
|
<p> Note that unknown features are ignored, so you can add use these
|
|
unconditionally in your interface file and it'll work with older SWIG
|
|
too.</p>
|
|
<p> There was a bug in SWIG 4.1.0 where setting this feature to any
|
|
value enabled it - SWIG 4.2.0 fixed this and you can now set it to 0 to
|
|
turn it off (for example, you might want to enabled it for everything
|
|
and then selectively turn it off for specific classes).</p>
|
|
<h3><a name="Php_nn2_7">32.2.7 PHP Pragmas, Startup and Shutdown code</a>
|
|
</h3>
|
|
<p> You can get SWIG to generate an "example.php" file by specifying the
|
|
code to put in it using the<b> code</b> pragma.</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> version</b> pragma can be used to add version to generated
|
|
PHP extension module. The version is inserted in the zend_module_entry
|
|
block.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%pragma(php) version="1.5"
|
|
</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>%shutdown</tt> or <tt>%mshutdown</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 are very
|
|
similar but insert code into the request init (PHP_RINIT_FUNCTION) and
|
|
request shutdown (PHP_RSHUTDOWN_FUNCTION) code respectively.</p>
|
|
<h2><a name="Php_nn3">32.3 Cross language polymorphism</a></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.</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">32.3.1 Enabling directors</a></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 the virtual methods in class Foo
|
|
%feature("director") Foo;
|
|
</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 the 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>
|
|
class MyFoo extends Foo {
|
|
function one() {
|
|
print "one from php\n";
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Php_nn3_2">32.3.2 Director classes</a></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 <tt>struct
|
|
swig_object_wrapper</tt> which is used to implement 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). Virtual methods that have a final specifier
|
|
are unsurprisingly excluded. Thus the 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
|
|
stores it in the <tt>struct swig_object_wrapper</tt>. This is true
|
|
whether or not directors are enabled for the particular class in
|
|
question. However when a class<i> derived</i> from a proxy class is
|
|
created, SWIG instead 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">32.3.3 Ownership and object destruction</a></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">32.3.4 Exception unrolling</a></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,
|
|
an exception thrown in PHP code called from C++ causes the PHP
|
|
interpreter to flag that an exception is thrown, then return passes to
|
|
C++ as if the PHP function had returned <code>Null</code>. Assuming the
|
|
directorout typemaps handle this (those SWIG defines by default should)
|
|
then once control returns to PHP code again, the PHP exception will
|
|
actually propagate.</p>
|
|
<p> Sometimes this control flow is problematic, and you want to skip any
|
|
handling in the C++ code. To achieve this, it is necessary to
|
|
temporarily translate the PHP exception into a C++ exception. This can
|
|
be achieved using the %feature("director:except") directive. The
|
|
following code should suffice in most cases:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director:except") {
|
|
#if SWIG_VERSION >= 0x040100
|
|
if ($error != NULL)
|
|
#else
|
|
if ($error == FAILURE)
|
|
#endif
|
|
{
|
|
throw Swig::DirectorMethodException();
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> If you only need to support SWIG >= 4.1.0, you can just use the <tt>
|
|
($error != NULL)</tt> condition.</p>
|
|
<p> In SWIG 4.1.0, <tt>$error</tt> was changed in the SWIG/PHP director
|
|
implementation to make it work more like how it does for other
|
|
languages. Previously, <tt>$error</tt> didn't actually indicate an
|
|
exception, but instead was only set to <tt>FAILURE</tt> if there was a
|
|
problem calling the PHP method. Now <tt>$error</tt> indicates if the
|
|
PHP method threw a PHP exception, and directorout typemaps for PHP no
|
|
longer need to be gated by <tt>if (EG(exception))</tt>.</p>
|
|
<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">32.3.5 Overhead and code bloat</a></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">32.3.6 Typemaps</a></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">32.3.7 Miscellaneous</a></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="Python">33 SWIG and Python</a></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>
|
|
<li><a href="#Python_commandline">Additional Python commandline options</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>
|
|
<ul>
|
|
<li><a href="#Python_smart_pointers_shared_ptr">The shared_ptr Smart
|
|
Pointer</a></li>
|
|
<li><a href="#Python_smart_pointers_generic">Generic Smart Pointers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Python_nn27a">C++ reference counted objects</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_builtin_types">Built-in Types</a>
|
|
<ul>
|
|
<li><a href="#Python_builtin_limitations">Limitations</a></li>
|
|
<li><a href="#Python_builtin_overloads">Operator overloads and slots --
|
|
use them!</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Python_nn30">Memory management</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_director_thread_safety">Thread safety</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>
|
|
<li><a href="#Python_optimization">Optimization options</a>
|
|
<ul>
|
|
<li><a href="#Python_fastproxy">-fastproxy</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Python_stable_abi">Stable ABI</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_default_args">Default arguments</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 a 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>
|
|
<li><a href="#Python_memory_management_member_variables">Memory
|
|
management when returning references to member variables</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_autodoc2">%feature("autodoc", "2")</a></li>
|
|
<li><a href="#Python_autodoc3">%feature("autodoc", "3")</a></li>
|
|
<li><a href="#Python_nn70">%feature("autodoc", "docstring")</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Python_nn71">%feature("docstring")</a></li>
|
|
<li><a href="#Python_doxygen_docstrings">Doxygen comments</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Python_nn72">Python Packages</a>
|
|
<ul>
|
|
<li><a href="#Python_modulepackage">Setting the Python package</a></li>
|
|
<li><a href="#Python_absrelimports">Absolute and relative imports</a></li>
|
|
<li><a href="#Python_absimport">Enforcing absolute import semantics</a></li>
|
|
<li><a href="#Python_importfrominit">Importing from __init__.py</a></li>
|
|
<li><a href="#Python_implicit_namespace_packages">Implicit namespace
|
|
packages</a></li>
|
|
<li><a href="#Python_package_search">Location of modules</a>
|
|
<ul>
|
|
<li><a href="#Python_package_search_both_package_modules">Both modules
|
|
in the same package</a></li>
|
|
<li><a href="#Python_package_search_both_global_modules">Both modules
|
|
are global</a></li>
|
|
<li><a href="#Python_package_search_wrapper_split">Split modules custom
|
|
configuration</a></li>
|
|
<li><a href="#Python_custom_module_import">More on customizing the
|
|
module import code</a></li>
|
|
<li><a href="#Python_package_search_static">Statically linked C modules</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Python_python3support">Python 3 Support</a>
|
|
<ul>
|
|
<li><a href="#Python_annotations">Python function annotations and
|
|
variable annotations</a>
|
|
<ul>
|
|
<li><a href="#Python_annotations_c">C/C++ annotation types</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Python_nn75">Buffer interface</a></li>
|
|
<li><a href="#Python_nn76">Abstract base classes</a></li>
|
|
<li><a href="#Python_nn77">Byte string output conversion</a></li>
|
|
<li><a href="#Python_2_unicode">Python 2 Unicode</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Python_multithreaded">Support for Multithreaded
|
|
Applications</a>
|
|
<ul>
|
|
<li><a href="#Python_thread_UI">UI for Enabling Multithreading Support</a>
|
|
</li>
|
|
<li><a href="#Python_thread_performance">Multithread Performance</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> This chapter describes SWIG's support of Python. SWIG is compatible
|
|
with all recent Python versions (Python 2.7 and Python >= 3.5). Python
|
|
3.3 and 3.4 may still work but we are no longer regularly testing with
|
|
them. SWIG 4.0.x supported Python 3.2. SWIG 3.0.x supported older
|
|
Python 2.x and 3.x.</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">33.1 Overview</a></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">33.2 Preliminaries</a></h2>
|
|
<h3><a name="Python_nn4">33.2.1 Running SWIG</a></h3>
|
|
<p> Suppose that you defined a SWIG module such as the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File: example.i */
|
|
%module example
|
|
|
|
%{
|
|
#include "example.h"
|
|
%}
|
|
|
|
int fact(int n);
|
|
</pre>
|
|
</div>
|
|
<p> 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">33.2.2 Using distutils</a></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="https://docs.python.org/3/library/distutils.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 python3
|
|
|
|
"""
|
|
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">33.2.3 Hand compiling a dynamic module</a></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="https://github.com/swig/swig/wiki">
|
|
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">33.2.4 Static linking</a></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 -lembed.i example.i
|
|
$ gcc example.c example_wrap.c \
|
|
-Xlinker -export-dynamic \
|
|
-DHAVE_CONFIG_H -I/usr/include/python2.7 \
|
|
-I/usr/lib/python2.7/config-x86_64-linux-gnu \
|
|
-I/usr/lib/python2.7/config \
|
|
-L/usr/lib/python2.7/config -lpython2.7 -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 actively maintained for many years. Even
|
|
though it appears to "work" with Python 2.7, 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">33.2.5 Using your module</a></h3>
|
|
<p> To use your module, simply use the Python <tt>import</tt> statement.
|
|
If all goes well, you will be able to run 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">33.2.6 Compilation of C++ extensions</a></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">33.2.7 Compiling for 64-bit platforms</a></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">33.2.8 Building Python extensions under
|
|
Windows</a></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 (.dsp files) for Visual C++ 6. These can be
|
|
opened by more recent versions of Visual Studio. You might want to take
|
|
a quick look at these examples 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 "python27.lib". Also, set the name of the output file to match
|
|
the name of your Python module, i.e. <tt>_example.pyd</tt></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> A 'Debug' build of the wrappers requires a debug build of the Python
|
|
interpreter. This normally requires building the Python interpreter
|
|
from source, which is not a job for the feint-hearted. Alternatively
|
|
you can use the 'Release' build of the Python interpreter with a
|
|
'Debug' build of your wrappers by defining the <tt>
|
|
SWIG_PYTHON_INTERPRETER_NO_DEBUG</tt> symbol under the preprocessor
|
|
options. Or you can ensure this macro is defined at the beginning of
|
|
the wrapper code using the following in your interface file, where <tt>
|
|
_MSC_VER</tt> ensures it is only used by the Visual Studio compiler:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%begin %{
|
|
#ifdef _MSC_VER
|
|
#define SWIG_PYTHON_INTERPRETER_NO_DEBUG
|
|
#endif
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<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="https://github.com/swig/swig/wiki">
|
|
SWIG Wiki</a>.</p>
|
|
<h3><a name="Python_commandline">33.2.9 Additional Python commandline
|
|
options</a></h3>
|
|
<p> The following table lists the additional commandline options
|
|
available for the Python module. They can also be seen by using:</p>
|
|
<div class="code">
|
|
<pre>
|
|
swig -python -help
|
|
</pre>
|
|
</div>
|
|
<table summary="Python specific options">
|
|
<tr><th>Python specific options</th></tr>
|
|
<tr><td>-builtin</td><td>Create Python built-in types rather than proxy
|
|
classes, for better performance</td></tr>
|
|
<tr><td>-castmode</td><td>Enable the casting mode, which allows implicit
|
|
cast between types in Python</td></tr>
|
|
<tr><td>-debug-doxygen-parser</td><td>Display doxygen parser module
|
|
debugging information</td></tr>
|
|
<tr><td>-debug-doxygen-translator</td><td>Display doxygen translator
|
|
module debugging information</td></tr>
|
|
<tr><td>-dirvtable</td><td>Generate a pseudo virtual table for directors
|
|
for faster dispatch (warning: currently the vtable is per-object and
|
|
never freed so this option causes memory leaks)</td></tr>
|
|
<tr><td>-doxygen</td><td>Convert C++ doxygen comments to pydoc comments
|
|
in proxy classes</td></tr>
|
|
<tr><td>-extranative</td><td>Return extra native wrappers for C++ std
|
|
containers wherever possible</td></tr>
|
|
<tr><td>-fastproxy</td><td>Use fast proxy mechanism for member methods</td>
|
|
</tr>
|
|
<tr><td>-flatstaticmethod</td><td>Generate additional flattened Python
|
|
methods for C++ static methods</td></tr>
|
|
<tr><td>-globals <name></td><td>Set <name> used to access C global
|
|
variable (default: 'cvar')</td></tr>
|
|
<tr><td>-interface <mod></td><td>Set low-level C/C++ module name to
|
|
<mod> (default: module name prefixed by '_')</td></tr>
|
|
<tr><td>-keyword</td><td>Use keyword arguments</td></tr>
|
|
<tr><td>-nofastunpack</td><td>Use traditional UnpackTuple method to
|
|
parse the argument functions</td></tr>
|
|
<tr><td>-noh</td><td>Don't generate the output header file</td></tr>
|
|
<tr><td>-noproxy</td><td>Don't generate proxy classes</td></tr>
|
|
<tr><td>-nortti</td><td>Disable the use of the native C++ RTTI with
|
|
directors</td></tr>
|
|
<tr><td>-nothreads</td><td>Disable thread support for the entire
|
|
interface</td></tr>
|
|
<tr><td>-olddefs</td><td>Keep the old method definitions when using
|
|
-fastproxy</td></tr>
|
|
<tr><td>-relativeimport</td><td>Use relative Python imports</td></tr>
|
|
<tr><td>-threads</td><td>Add thread support for all the interface</td></tr>
|
|
<tr><td>-O</td><td>Enable the following optimization options:
|
|
-fastdispatch -fastproxy -fvirtual</td></tr>
|
|
</table>
|
|
<p> Many of these options are covered later on and their use should
|
|
become clearer by the time you have finished reading this section on
|
|
SWIG and Python.</p>
|
|
<h2><a name="Python_nn13">33.3 A tour of basic C/C++ wrapping</a></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">33.3.1 Modules</a></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">33.3.2 Functions</a></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">33.3.3 Global variables</a></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">33.3.4 Constants and enums</a></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">33.3.5 Pointers</a></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 of type 'FILE *' at 0xb7d6f470>
|
|
</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">33.3.6 Structures</a></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)
|
|
3.5 7.2 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 <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>
|
|
<p> Note that there is a limitation with structs within structs that
|
|
will cause a problem if the outer struct is not a named variable in
|
|
Python. The following will cause a segfault:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Bar().f.a = 3
|
|
</pre>
|
|
</div>
|
|
<p> because the unnamed Python proxy class for <tt>Bar()</tt> has its
|
|
reference count decremented by the Python interpreter after <tt>f</tt>
|
|
has been obtained from it and before <tt>f</tt> is used to obtain <tt>a</tt>
|
|
. This results in the underlying <tt>Bar</tt> instance being deleted,
|
|
which of course also deletes <tt>f</tt> inside it. Hence the pointer to
|
|
<tt>f</tt> points to deleted memory and use of it results in a segfault
|
|
or some sort of other undefined behaviour.</p>
|
|
<h3><a name="Python_nn20">33.3.7 C++ classes</a></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 accessed in three different
|
|
ways:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> s = example.Spam()
|
|
>>> s.foo() # Spam::foo() via an instance
|
|
>>> example.Spam.foo() # Spam::foo() using class method
|
|
>>> example.Spam_foo() # Spam::foo() "flattened" name
|
|
</pre>
|
|
</div>
|
|
<p> The last technique is only available when using the <tt>
|
|
-flatstaticmethod</tt> option. This option is not recommended, it is
|
|
only available for backwards compatibility as ancient versions of
|
|
Python did not have Python class methods.</p>
|
|
<p> Static member variables are currently accessed as global variables.
|
|
This means, they are accessed through <tt>cvar</tt> or via an instance
|
|
property:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> example.cvar.Spam_bar # Spam::bar
|
|
7
|
|
>>> s = example.Spam()
|
|
>>> s.bar # Spam::bar via an instance property
|
|
7
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>-builtin</tt> option uses a metaclass to additionally
|
|
provide access as follows:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> example.Spam.bar # Spam::bar using -builtin option only
|
|
7
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Python_nn21">33.3.8 C++ inheritance</a></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">33.3.9 Pointers, references, values, and
|
|
arrays</a></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">33.3.10 C++ overloaded functions</a></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 method spam(short) effectively ignored,
|
|
example.i:11: Warning 509: as it is shadowed by spam(int).
|
|
</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">33.3.11 C++ operators</a></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>
|
|
<p> Operator overloading is implemented in the <tt>pyopers.swg</tt>
|
|
library file. In particular overloaded operators are marked with the <tt>
|
|
python:maybecall</tt> feature, also known as <tt>%pythonmaybecall</tt>.
|
|
This feature forces SWIG to generate code that returns an instance of
|
|
Python's <tt>NotImplemented</tt> instead of raising the usual <tt>
|
|
TypeError</tt> exception when an incorrect type is passed to a SWIG
|
|
wrapped method. This follows the guidelines in <a href="https://www.python.org/dev/peps/pep-0207/">
|
|
PEP 207 - Rich Comparisons</a> and <a href="https://docs.python.org/3/library/constants.html#NotImplemented">
|
|
NotImplemented Python constant</a>.</p>
|
|
<h3><a name="Python_nn25">33.3.12 C++ namespaces</a></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">33.3.13 C++ templates</a></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">33.3.14 C++ Smart Pointers</a></h3>
|
|
<h4><a name="Python_smart_pointers_shared_ptr">33.3.14.1 The shared_ptr
|
|
Smart Pointer</a></h4>
|
|
<p> The C++11 standard provides <tt>std::shared_ptr</tt> which was
|
|
derived from the Boost implementation, <tt>boost::shared_ptr</tt>. Both
|
|
of these are available for Python in the SWIG library and usage is
|
|
outlined in the <a href="#Library_std_shared_ptr">shared_ptr smart
|
|
pointer</a> library section.</p>
|
|
<h4><a name="Python_smart_pointers_generic">33.3.14.2 Generic Smart
|
|
Pointers</a></h4>
|
|
<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">33.3.15 C++ reference counted objects</a></h3>
|
|
<p> The <a href="#SWIGPlus_ref_unref">C++ reference counted objects</a>
|
|
section contains Python examples of memory management using referencing
|
|
counting.</p>
|
|
<h2><a name="Python_nn28">33.4 Further details on the Python class
|
|
interface</a></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>
|
|
<p><b>New in SWIG version 2.0.4:</b> The use of Python proxy classes has
|
|
performance implications that may be unacceptable for a
|
|
high-performance library. The new <tt>-builtin</tt> option instructs
|
|
SWIG to forego the use of proxy classes, and instead create wrapped
|
|
types as new built-in Python types. When this option is used, the
|
|
following section ("Proxy classes") does not apply. Details on the use
|
|
of the <tt>-builtin</tt> option are in the <a href="#Python_builtin_types">
|
|
Built-in Types</a> section.</p>
|
|
<h3><a name="Python_nn29">33.4.1 Proxy classes</a></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 = True
|
|
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_builtin_types">33.4.2 Built-in Types</a></h3>
|
|
<p> The <tt>-builtin</tt> option provides a significant performance
|
|
improvement in the wrapped code. To understand the difference between
|
|
proxy classes and built-in types, let's take a look at what a wrapped
|
|
object looks like under both circumstances.</p>
|
|
<p>When proxy classes are used, each wrapped object in Python is an
|
|
instance of a pure Python class. As a reminder, here is what the <tt>
|
|
__init__</tt> method looks like in a proxy class:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class Foo(object):
|
|
def __init__(self):
|
|
self.this = _example.new_Foo()
|
|
self.thisown = True
|
|
</pre>
|
|
</div>
|
|
<p>When a <tt>Foo</tt> instance is created, the call to <tt>
|
|
_example.new_Foo()</tt> creates a new C++ <tt>Foo</tt> instance; wraps
|
|
that C++ instance inside an instance of a Python built-in type called <tt>
|
|
SwigPyObject</tt>; and stores the <tt>SwigPyObject</tt> instance in the
|
|
'this' field of the Python Foo object. Did you get all that? So, the
|
|
Python <tt>Foo</tt> object is composed of three parts:</p>
|
|
<ul>
|
|
<li> The Python <tt>Foo</tt> instance, which contains...</li>
|
|
<li> ... an instance of <tt>struct SwigPyObject</tt>, which contains...</li>
|
|
<li> ... a C++ <tt>Foo</tt> instance</li>
|
|
</ul>
|
|
<p>When <tt>-builtin</tt> is used, the pure Python layer is stripped
|
|
off. Each wrapped class is turned into a new Python built-in type which
|
|
inherits from <tt>SwigPyObject</tt>, and <tt>SwigPyObject</tt>
|
|
instances are returned directly from the wrapped methods. For more
|
|
information about Python built-in extensions, please refer to the
|
|
Python documentation:</p>
|
|
<p><a href="https://docs.python.org/3/extending/newtypes.html">
|
|
https://docs.python.org/3/extending/newtypes.html</a></p>
|
|
<h4><a name="Python_builtin_limitations">33.4.2.1 Limitations</a></h4>
|
|
<p>Use of the <tt>-builtin</tt> option implies a couple of limitations:</p>
|
|
<ul>
|
|
<li>
|
|
<p>Some legacy syntax is no longer supported; in particular:</p>
|
|
<ul>
|
|
<li>The functional interface is no longer exposed. For example, you may
|
|
no longer call <tt>Whizzo.new_CrunchyFrog()</tt>. Instead, you must use
|
|
<tt>Whizzo.CrunchyFrog()</tt>.</li>
|
|
<li>Static member variables are no longer accessed through the 'cvar'
|
|
field (e.g., <tt>Dances.cvar.FishSlap</tt>). They are instead accessed
|
|
in the idiomatic way (<tt>Dances.FishSlap</tt>).</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Wrapped types may not be raised as Python exceptions. Here's why: the
|
|
Python internals expect that all sub-classes of Exception will have
|
|
this struct layout:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef struct {
|
|
PyObject_HEAD
|
|
PyObject *dict;
|
|
PyObject *args;
|
|
PyObject *message;
|
|
} PyBaseExceptionObject;
|
|
</pre>
|
|
</div>
|
|
<p>But swig-generated wrappers expect that all swig-wrapped classes will
|
|
have this struct layout:</p>
|
|
<div class="code">
|
|
<pre>
|
|
typedef struct {
|
|
PyObject_HEAD
|
|
void *ptr;
|
|
swig_type_info *ty;
|
|
int own;
|
|
PyObject *next;
|
|
PyObject *dict;
|
|
} SwigPyObject;
|
|
</pre>
|
|
</div>
|
|
<p>There are workarounds for this. For example, if you wrap this class:<div
|
|
class="code">
|
|
<pre>
|
|
class MyException {
|
|
public:
|
|
MyException (const char *msg_);
|
|
~MyException ();
|
|
|
|
const char *what () const;
|
|
|
|
private:
|
|
char *msg;
|
|
};
|
|
</pre>
|
|
</div></p>
|
|
<p>... you can define this Python class, which may be raised as an
|
|
exception:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class MyPyException(Exception):
|
|
def __init__(self, msg, *args):
|
|
Exception.__init__(self, *args)
|
|
self.myexc = MyException(msg)
|
|
def what(self):
|
|
return self.myexc.what()
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>Reverse binary operators (e.g., <tt>__radd__</tt>) are not supported.</p>
|
|
<p>To illustrate this point, if you have a wrapped class called <tt>
|
|
MyString</tt>, and you want to use instances of <tt>MyString</tt>
|
|
interchangeably with native Python strings, you can define an <tt>
|
|
'operator+ (const char*)'</tt> method :</p>
|
|
<div class="code">
|
|
<pre>
|
|
class MyString {
|
|
public:
|
|
MyString (const char *init);
|
|
MyString operator+ (const char *other) const;
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> SWIG will automatically create an operator overload in Python that
|
|
will allow this:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from MyModule import MyString
|
|
|
|
mystr = MyString("No one expects")
|
|
episode = mystr + " the Spanish Inquisition"
|
|
</pre>
|
|
</div>
|
|
<p> This works because the first operand (<tt>mystr</tt>) defines a way
|
|
to add a native string to itself. However, the following will<b> not</b>
|
|
work:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from MyModule import MyString
|
|
|
|
mystr = MyString("Parrot")
|
|
episode = "Dead " + mystr
|
|
</pre>
|
|
</div>
|
|
<p> The above code fails, because the first operand -- a native Python
|
|
string -- doesn't know how to add an instance of <tt>MyString</tt> to
|
|
itself.</p>
|
|
</li>
|
|
<li>
|
|
<p>If you have multiple SWIG modules that share type information (<a href="#Modules_nn2">
|
|
more info</a>), the <tt>-builtin</tt> option requires a bit of extra
|
|
discipline to ensure that base classes are initialized before derived
|
|
classes. Specifically:</p>
|
|
<ul>
|
|
<li>
|
|
<p>There must be an unambiguous dependency graph for the modules.</p>
|
|
</li>
|
|
<li>
|
|
<p>Module dependencies must be explicitly stated with <tt>%import</tt>
|
|
statements in the SWIG interface file.</p>
|
|
</li>
|
|
</ul>
|
|
<p>As an example, suppose module <tt>A</tt> has this interface in <tt>
|
|
A.i</tt> :</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module "A";
|
|
|
|
class Base {
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p>If you want to wrap another module containing a class that inherits
|
|
from <tt>A</tt>, this is how it would look :</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module "B";
|
|
|
|
%import "A.i"
|
|
|
|
class Derived : public Base {
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p>The <tt>import "A.i"</tt> statement is required, because module <tt>B</tt>
|
|
depends on module <tt>A</tt>.</p>
|
|
<p>As long as you obey these requirements, your Python code may import
|
|
the modules in any order :</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
import B
|
|
import A
|
|
|
|
assert(issubclass(B.Derived, A.Base))
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p><a href="#Python_annotations">Python annotations</a> are not
|
|
supported.</p>
|
|
</li>
|
|
</ul>
|
|
<h4><a name="Python_builtin_overloads">33.4.2.2 Operator overloads and
|
|
slots -- use them!</a></h4>
|
|
<p>The entire justification for the <tt>-builtin</tt> option is improved
|
|
performance. To that end, the best way to squeeze maximum performance
|
|
out of your wrappers is to<b> use operator overloads.</b> Named method
|
|
dispatch is slow in Python, even when compared to other scripting
|
|
languages. However, Python built-in types have a large number of
|
|
"slots", analogous to C++ operator overloads, which allow you to
|
|
short-circuit named method dispatch for certain common operations.</p>
|
|
<p>By default, SWIG will translate most C++ arithmetic operator
|
|
overloads into Python slot entries. For example, suppose you have this
|
|
class:<div class="code">
|
|
<pre>
|
|
class Twit {
|
|
public:
|
|
Twit operator+ (const Twit& twit) const;
|
|
|
|
// Forward to operator+
|
|
Twit add (const Twit& twit) const {
|
|
return *this + twit;
|
|
}
|
|
};
|
|
</pre>
|
|
</div></p>
|
|
<p>SWIG will automatically register <tt>operator+</tt> as a Python slot
|
|
operator for addition. You may write Python code like this:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from MyModule import Twit
|
|
|
|
nigel = Twit()
|
|
emily = Twit()
|
|
percival = nigel + emily
|
|
percival = nigel.add(emily)
|
|
</pre>
|
|
</div>
|
|
<p>The last two lines of the Python code are equivalent, but<b> the line
|
|
that uses the '+' operator is much faster</b>.</p>
|
|
<p>In-place operators (e.g., <tt>operator+=</tt>) and comparison
|
|
operators (<tt>operator==, operator<</tt>, etc.) are also converted to
|
|
Python slot operators. For a complete list of C++ operators that are
|
|
automatically converted to Python slot operators, refer to the file <tt>
|
|
python/pyopers.swg</tt> in the SWIG library.</p>
|
|
<p> Read about all of the available Python slots here: <a href="https://docs.python.org/3/c-api/typeobj.html">
|
|
https://docs.python.org/3/c-api/typeobj.html</a></p>
|
|
<p> There are two ways to define a Python slot function: dispatch to a
|
|
statically defined function; or dispatch to a method defined on the
|
|
operand.</p>
|
|
<p> To dispatch to a statically defined function, use
|
|
%feature("python:<slot>"), where <slot> is the name of a field in a <tt>
|
|
PyTypeObject, PyNumberMethods, PyMappingMethods, PySequenceMethods</tt>
|
|
or <tt>PyBufferProcs</tt>. You may override (almost) all of these
|
|
slots.</p>
|
|
<p> Let's consider an example setting the <tt>tp_hash</tt> slot for the <tt>
|
|
MyClass</tt> type. This is akin to providing a <tt>__hash__</tt> method
|
|
(for non-builtin types) to make a type hashable. The hashable type can
|
|
then for example be added to a Python <tt>dict</tt>.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("python:tp_hash") MyClass "myHashFunc";
|
|
|
|
class MyClass {
|
|
public:
|
|
long field1;
|
|
long field2;
|
|
...
|
|
};
|
|
|
|
%{
|
|
#if PY_VERSION_HEX >= 0x03020000
|
|
static Py_hash_t myHashFunc(PyObject *pyobj)
|
|
#else
|
|
static long myHashFunc(PyObject *pyobj)
|
|
#endif
|
|
{
|
|
MyClass *cobj;
|
|
// Convert pyobj to cobj
|
|
return (cobj->field1 * (cobj->field2 << 7));
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> If you examine the generated code, the supplied hash function will
|
|
now be the function callback in the tp_hash slot for the builtin type
|
|
for <tt>MyClass</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
static PyHeapTypeObject SwigPyBuiltin__MyClass_type = {
|
|
...
|
|
(hashfunc) myHashFunc, /* tp_hash */
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> NOTE: It is the responsibility of the programmer (that's you!) to
|
|
ensure that a statically defined slot function has the correct
|
|
signature, the <tt>hashfunc</tt> typedef in this case.</p>
|
|
<p> If, instead, you want to dispatch to an instance method, you can use
|
|
%feature("python:slot"). For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc;
|
|
|
|
#if PY_VERSION_HEX < 0x03020000
|
|
#define Py_hash_t long
|
|
#endif
|
|
|
|
class MyClass {
|
|
public:
|
|
Py_hash_t myHashFunc() const;
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> NOTE: Some Python slots use a method signature which does not match
|
|
the signature of SWIG-wrapped methods. For those slots, SWIG will
|
|
automatically generate a "closure" function to re-marshal the arguments
|
|
before dispatching to the wrapped method. Setting the "functype"
|
|
attribute of the feature enables SWIG to generate the chosen closure
|
|
function.</p>
|
|
<p> There is further information on <tt>%feature("python:slot")</tt> in
|
|
the file <tt>python/pyopers.swg</tt> in the SWIG library.</p>
|
|
<h3><a name="Python_nn30">33.4.3 Memory management</a></h3>
|
|
<p>NOTE: Although this section refers to proxy objects, everything here
|
|
also applies when the <tt>-builtin</tt> option is used.</p>
|
|
<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 <tt>True</tt>, the Python interpreter
|
|
will destroy the C++ object when the proxy class is garbage collected.
|
|
If set to <tt>False</tt> (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();
|
|
};
|
|
Foo CreateFoo();
|
|
</pre>
|
|
</div>
|
|
<p> In Python:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> f = Foo()
|
|
>>> f.thisown
|
|
True
|
|
>>> g = CreateFoo()
|
|
>>> g.thisown
|
|
True
|
|
</pre>
|
|
</div>
|
|
<p> The type information is a Python class, a proxy of the underlying
|
|
C++ type:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> type(f)
|
|
<class 'example.Foo'>
|
|
>>> f
|
|
<example.Foo; proxy of <Swig Object of type 'Foo *' at 0x7f5a86d48600> >
|
|
True
|
|
</pre>
|
|
</div>
|
|
<p> Unlike a C or C++ compiler, SWIG can work with incomplete type
|
|
information and generate wrapper code even if the definition of <tt>
|
|
class Foo</tt> is not provided to SWIG. However, this has negative
|
|
consequences in the form of a memory leak.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> h = CreateFoo()
|
|
>>> type(h)
|
|
<class 'SwigPyObject'>
|
|
>>> h
|
|
<Swig Object of type 'Foo *' at 0x7fc341b4d6f0>
|
|
>>> quit()
|
|
swig/python detected a memory leak of type 'Foo *', no destructor found.
|
|
</pre>
|
|
</div>
|
|
<p> Note that the type is no longer a proxy Python class, but is instead
|
|
a generic <tt>SwigPyObject</tt> type. The memory leak warning is shown
|
|
as SWIG has no way of knowing how to call the destructor with this
|
|
generic type. The recommendation is to fix the leak by providing the
|
|
missing type information. However, for those who don't care about
|
|
memory leaks, the warning can also be suppressed by by defining <tt>
|
|
SWIG_PYTHON_SILENT_MEMLEAK</tt> when compiling the generated C/C++
|
|
wrapper code, such as passing <tt>-DSWIG_PYTHON_SILENT_MEMLEAK</tt> to
|
|
the compiler or getting SWIG to define this macro at the beginning of
|
|
the generated wrapper code by adding the following to the interface
|
|
file using:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%begin %{
|
|
#define SWIG_PYTHON_SILENT_MEMLEAK
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The generic <tt>SwigPyObject</tt> type also has a <tt>disown()</tt>
|
|
method which can be called to deactivate the warning.</p>
|
|
<p> Next, let's consider returning raw pointers even when the full type
|
|
information is available to SWIG. When pointers or references are
|
|
returned to Python, there is often no way to know where they came from
|
|
and how to manage the memory that they point to. Therefore, the
|
|
ownership is set to <tt>False</tt>. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class Foo {
|
|
public:
|
|
Foo();
|
|
~Foo();
|
|
};
|
|
Foo *PointerCreate();
|
|
Foo &ReferenceCreate();
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
>>> p = PointerCreate()
|
|
>>> p.thisown
|
|
False
|
|
>>> r = ReferenceCreate()
|
|
>>> r.thisown
|
|
False
|
|
</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
|
|
True
|
|
>>> example.cvar.head = f
|
|
>>> f.thisown
|
|
False
|
|
>>>
|
|
</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
|
|
True
|
|
>>> g.thisown
|
|
True
|
|
>>> f.next = g
|
|
>>> g.thisown
|
|
False
|
|
>>>
|
|
</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
|
|
True
|
|
>>> 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 = False
|
|
</pre>
|
|
</div>
|
|
<p> It is also possible to deal with situations like this using
|
|
typemaps--an advanced topic discussed later.</p>
|
|
<h2><a name="Python_directors">33.5 Cross language polymorphism</a></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">33.5.1 Enabling directors</a></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 the virtual methods in class Foo
|
|
%feature("director") Foo;
|
|
</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 the 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 ~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.__init__(self, foo)
|
|
# super().__init__(foo) # Alternative construction for Python3
|
|
|
|
def one(self):
|
|
print("one from Python")
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Python_nn34">33.5.2 Director classes</a></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). Virtual methods that have a final specifier
|
|
are unsurprisingly excluded. Thus the 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">33.5.3 Ownership and object destruction</a></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 <tt>False</tt>, 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. 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">33.5.4 Exception unrolling</a></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">33.5.5 Overhead and code bloat</a></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">33.5.6 Typemaps</a></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_director_thread_safety">33.5.7 Thread safety</a></h3>
|
|
<p> The director implementation uses a <tt>std::map</tt> to manage C++
|
|
pointer ownership. This code is not thread-safe by default. See <a href="#Python_multithreaded">
|
|
Thread safety</a> for turning on thread-safety. This defines a macro
|
|
called <tt>SWIG_THREADS</tt> which forces the C++ code to then use a
|
|
mutex for managing the pointer ownership, which in turn makes the
|
|
directors implementation thread-safe.</p>
|
|
<p> Please see the <tt>director_guard.swg</tt> Library file for details
|
|
of the implementation.</p>
|
|
<h3><a name="Python_nn39">33.5.8 Miscellaneous</a></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 on 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 nor 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 return by value semantics
|
|
instead.</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">33.6 Common customization features</a></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">33.6.1 C/C++ helper functions</a></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">33.6.2 Adding additional Python code</a></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>
|
|
/* Rename the SWIG-generated wrapper. */
|
|
%rename _set_transform set_transform;
|
|
|
|
...
|
|
|
|
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> There is also <tt>%pythonbegin</tt> which is another directive very
|
|
similar to <tt>%pythoncode</tt>, but generates the given Python code at
|
|
the beginning of the <tt>.py</tt> file. This directive works in the
|
|
same way as <tt>%pythoncode</tt>, except the code is copied just after
|
|
the SWIG banner (comment) at the top of the file, before any real code.
|
|
This provides an opportunity to add your own description in a comment
|
|
near the top of the file as well as Python imports that have to appear
|
|
at the top of the file, such as "<tt>from __future__ import</tt>"
|
|
statements.</p>
|
|
<p> The following example for Python 2.x shows how to insert code into
|
|
the generated wrapper to enable <tt>print</tt> to be used as a
|
|
Python3-compatible function instead of a statement:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%pythonbegin %{
|
|
# This module provides wrappers to the Whizz Bang library
|
|
%}
|
|
|
|
%pythonbegin %{
|
|
from __future__ import print_function
|
|
print("Loading", "Whizz", "Bang", sep=' ... ')
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The insert code can be seen at the start of the generated <tt>.py</tt>
|
|
file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
# This file was automatically generated by SWIG (https://www.swig.org).
|
|
# Version 4.0.0
|
|
#
|
|
# Do not make changes to this file unless you know what you are doing--modify
|
|
# the SWIG interface file instead.
|
|
|
|
# This module provides wrappers to the Whizz Bang library
|
|
|
|
from __future__ import print_function
|
|
print("Loading", "Whizz", "Bang", sep=' ... ')
|
|
|
|
</pre>
|
|
</div>
|
|
<p>When using <tt>%pythoncode</tt> and <tt>%pythonbegin</tt> you
|
|
generally want to make sure that the block is delimited by <tt>%{</tt>
|
|
and <tt>%}</tt>. If you delimit it with <tt>{</tt> and <tt>}</tt> then
|
|
any lines with a leading <tt>#</tt> will be handled by SWIG as
|
|
preprocessor directives, when you probably meant them as Python
|
|
comments. Prior to SWIG 3.0.3, invalid preprocessor directives were
|
|
silently ignored, so generally using the wrong delimiters resulted in
|
|
such comments not appearing in the generated output (though a comment
|
|
starting with a valid preprocessor directive could cause problems, for
|
|
example: <tt># error handling</tt>). SWIG 3.0.3 and later report an
|
|
error for invalid preprocessor directives, so you may have to update
|
|
existing interface files to delimit blocks of Python code correctly.</p>
|
|
<p>As an alternative to providing a block containing Python code, you
|
|
can include Python code from a file. The code is inserted exactly as in
|
|
the file, so this avoids any issues with the SWIG preprocessor. It's a
|
|
good approach if you have a non-trivial chunk of Python code to insert.
|
|
To use this feature you specify a filename in double quotes, for
|
|
example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%pythoncode "somecode.py"
|
|
</pre>
|
|
</div>
|
|
<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 to 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. Note that this does not include the arguments to the
|
|
C/C++ 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
|
|
#the 'val' variable holds the return value
|
|
%}
|
|
|
|
|
|
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
|
|
#the 'val' variable holds the return value
|
|
%}
|
|
|
|
|
|
class Foo {
|
|
public:
|
|
int bar(int x);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> Note that when the underlying C++ method is overloaded, there is
|
|
only one proxy Python method for multiple C++ methods. In this case,
|
|
only one of parsed methods is examined for the feature. You are better
|
|
off specifying the feature without the argument list to ensure it will
|
|
get used, as it will then get attached to all the overloaded C++
|
|
methods. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
// Add Python code to bar()
|
|
|
|
%pythonprepend Foo::bar %{
|
|
#do something before C++ call
|
|
%}
|
|
|
|
%pythonappend Foo::bar %{
|
|
#do something after C++ call
|
|
%}
|
|
|
|
|
|
class Foo {
|
|
public:
|
|
int bar(int x);
|
|
int bar();
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The same applies for overloaded constructors.</p>
|
|
<h3><a name="Python_nn43">33.6.3 Class extension with %extend</a></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">33.6.4 Exception handling with %exception</a></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");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
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());
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
</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()));
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
|
|
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 followed by <tt>SWIG_fail</tt>
|
|
. 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> <tt>SWIG_fail</tt> is a C macro which when called within the context
|
|
of SWIG wrapper function, will jump to the error handler code. This
|
|
will call any cleanup code (freeing any temp variables) and then return
|
|
from the wrapper function so that the Python interpreter can raise the
|
|
Python exception. This macro should always be called after setting a
|
|
Python error in code snippets, such as typemaps and <tt>%exception</tt>
|
|
, that are ultimately generated into the wrapper function.</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.</p>
|
|
<h3><a name="Python_optimization">33.6.5 Optimization options</a></h3>
|
|
<h4><a name="Python_fastproxy">33.6.5.1 -fastproxy</a></h4>
|
|
<p> The <tt>-fastproxy</tt> command line option enables faster method
|
|
calling as the call is made directly into the C/C++ layer rather than
|
|
going through a method wrapper.</p>
|
|
<p> Consider wrapping a C++ class:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct Go {
|
|
void callme0() {}
|
|
void callme4(int a, int b, int c, int d) {}
|
|
void callme8(double a, double b, double c, double d, double e, double f, double g, double i) {}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The default generated proxy class is:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class Go(object):
|
|
def callme0(self):
|
|
return _example.Go_callme0(self)
|
|
|
|
def callme4(self, a, b, c, d):
|
|
return _example.Go_callme4(self, a, b, c, d)
|
|
|
|
def callme8(self, a, b, c, d, e, f, g, i):
|
|
return _example.Go_callme8(self, a, b, c, d, e, f, g, i)
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> Each method in the Python class contains a Python proxy method which
|
|
passes the arguments on to the underlying function in the low-level
|
|
C/C++ module (_example in this case). The generated proxy class when
|
|
using <tt>-fastproxy</tt> is:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
%module example
|
|
class Go(object):
|
|
callme0 = _swig_new_instance_method(_example.Go_callme0)
|
|
callme4 = _swig_new_instance_method(_example.Go_callme4)
|
|
callme8 = _swig_new_instance_method(_example.Go_callme8)
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> where <tt>_swig_new_instance_method</tt> adds the method to the
|
|
proxy class via C API calls for direct access to the underlying
|
|
function in the low-level C/C++ module. Note that for some methods it
|
|
is not possible to generate the direct access call and so <tt>
|
|
-fastproxy</tt> is ignored. This happens, for example, when adding <a href="#Python_nn42">
|
|
additional code</a> to Python proxy methods, such as using <tt>
|
|
%pythonprepend</tt>.</p>
|
|
<p> The overhead calling into C/C++ from Python is reduced slightly
|
|
using <tt>-fastproxy</tt>. Below are some timings in microseconds
|
|
calling the 3 functions in the example above. Also included in the
|
|
table for comparison is using the <tt>-builtin</tt> option covered in
|
|
the <a href="#Python_builtin_types">Built-in Types</a>.</p>
|
|
<table summary="Python fastproxy performance">
|
|
<tr><th>Method name</th><th>Default</th><th>-fastproxy</th><th>-builtin</th>
|
|
</tr>
|
|
<tr><td>callme0</td><td>0.15</td><td>0.09</td><td>0.07</td></tr>
|
|
<tr><td>callme4</td><td>0.26</td><td>0.16</td><td>0.14</td></tr>
|
|
<tr><td>callme8</td><td>0.32</td><td>0.20</td><td>0.17</td></tr>
|
|
</table>
|
|
<p> Although the <tt>-fastproxy</tt> option results in faster code over
|
|
the default, the generated proxy code is not as user-friendly as
|
|
docstring/doxygen comments, <a href="#Python_annotations">Python
|
|
annotations</a> and functions with default values are not visible in
|
|
the generated Python proxy class. The <tt>-olddefs</tt> option can
|
|
rectify this.</p>
|
|
<p> The generated proxy class for the example above when using <tt>
|
|
-fastproxy -olddefs</tt> is:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class Go(object):
|
|
def callme0(self):
|
|
return _example.Go_callme0(self)
|
|
callme0 = _swig_new_instance_method(_example.Go_callme0)
|
|
|
|
def callme4(self, a, b, c, d):
|
|
return _example.Go_callme4(self, a, b, c, d)
|
|
callme4 = _swig_new_instance_method(_example.Go_callme4)
|
|
|
|
def callme8(self, a, b, c, d, e, f, g, i):
|
|
return _example.Go_callme8(self, a, b, c, d, e, f, g, i)
|
|
callme8 = _swig_new_instance_method(_example.Go_callme8)
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> The class defines each method in two different ways. The first
|
|
definition is replaced by the second definition and so the second
|
|
definition is the one used when the method is called. While this
|
|
possibly provides the best of both worlds, the time to import the
|
|
module will be slightly slower when the class is defined due to the
|
|
additional method definitions.</p>
|
|
<p> The command line options mentioned above also apply to wrapped C/C++
|
|
global functions, not just class methods.</p>
|
|
<h3><a name="Python_stable_abi">33.6.6 Stable ABI</a></h3>
|
|
<p> By default, the version of Python used to compile the wrappers needs
|
|
to be the same as that used during runtime. Alternatvely, the <a href="https://docs.python.org/3/c-api/stable.html">
|
|
Python Stable ABI</a> enables a single compiled binary to be used by
|
|
different versions of Python. This is enabled by defining <tt>
|
|
Py_LIMITED_API</tt> during the compilation of the C/C++ wrapper code and
|
|
setting this macro to a particular minimum version of Python that one
|
|
wants to support.</p>
|
|
<p> SWIG supports the stable ABI, but only version 3.4 of Python and
|
|
later is supported. There are two recommended approaches for using SWIG
|
|
and the stable ABI and both require setting the <tt>Py_LIMITED_API</tt>
|
|
macro to be set to <tt>0x03040000</tt> as a minimum value (Python 3.4).
|
|
Either set this using <tt>%begin</tt> by adding the following into your
|
|
interface file so that this macro appears at the beginning of the
|
|
generated C/C++ code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%begin %{
|
|
#define Py_LIMITED_API 0x03040000
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> or simply define the macro using your C/C++ compiler's <tt>-D</tt>
|
|
command line option, for example, <tt>-DPy_LIMITED_API=0x03040000</tt>.</p>
|
|
<p> The default SWIG command line options generate code that enable the
|
|
limited API/stable ABI. Some options, such as <tt>-builtin</tt>, <tt>
|
|
-fast</tt> (used by <tt>-O</tt>) do not use the limited API and hence
|
|
when <tt>Py_LIMITED_API</tt> is defined there will be missing symbols
|
|
during compilation. Compatibility of user's custom typemaps is of
|
|
course dependent on the Python APIs used in the typemaps.</p>
|
|
<p> As discussed in the official <a href="https://docs.python.org/3/c-api/stable.html">
|
|
Python Stable ABI</a> documentation, there is no guarantee that code
|
|
conforms to the Limited API or Stable ABI when defining <tt>
|
|
Py_LIMITED_API</tt>. There are a number of recommendations and caveats
|
|
detailed there which are worth studying. The Stable ABI is also
|
|
evolving and being modified with each Python release. In fact there is
|
|
a Python C API working group, <a href="https://github.com/capi-workgroup/">
|
|
capi-workgroup</a>, which was setup in the first half of 2023. The <a href="https://github.com/capi-workgroup/problems/issues">
|
|
capi-workgroup/problems issues</a> is very enlightening reading for
|
|
anyone using the Stable ABI. <a href="https://peps.python.org/pep-0733/">
|
|
PEP 733</a> came out of the working group and is an evaluation of
|
|
Python's C API.</p>
|
|
<p> There is a lot of information to digest in this space, but a simple
|
|
approach would be to follow the offical recommendation of testing an
|
|
extension with all minor Python versions you want to support, and to
|
|
build with the lowest supported version. SWIG supports at least Python
|
|
3.4 for the Stable ABI so this would be a good version to compile a
|
|
SWIG extension against. There is also a useful tool <a href="https://github.com/trailofbits/abi3audit/">
|
|
abi3audit</a> which can be used to check the compiled extension for
|
|
Stable ABI conformance. It can be easily installed with pip and then
|
|
used to check a SWIG generated shared object or wheel even. Note that
|
|
if you are using it to check a shared object, the shared object must be
|
|
renamed to have abi3 in the name. For example, below is the output on
|
|
Linux for the class example shipped with SWIG, if <tt>Py_LIMITED_API</tt>
|
|
is set as described earlier:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
~/swig/Examples/python/class $ mv _example.so _example.abi3.so
|
|
~/swig/Examples/python/class $ abi3audit --assume-minimum-abi3 3.4 _example.abi3.so
|
|
[22:12:18] WARNING no wheel to infer abi3 version from; assuming (3.4)
|
|
[22:12:18] _example.abi3.so: 1 extensions scanned; 0 ABI version mismatches and 0 ABI violations found
|
|
</pre>
|
|
</div>
|
|
<p> If <tt>Py_LIMITED_API</tt> is not set, the check fails, but this
|
|
should be expected:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
~/swig/Examples/python/class $ mv _example.so _example.abi3.so
|
|
~/swig/Examples/python/class $ abi3audit --report --assume-minimum-abi3 3.4 _example.abi3.so
|
|
[22:22:27] WARNING no wheel to infer abi3 version from; assuming (3.4)
|
|
[22:22:27] _example.abi3.so: 1 extensions scanned; 1 ABI version mismatches and 0 ABI violations found
|
|
{"specs": {"_example.abi3.so": {"kind": "object", "object": {"name": "_example.abi3.so",
|
|
"result": {"is_abi3": true, "is_abi3_baseline_compatible": false, "baseline": "3.4", "computed": "3.10",
|
|
"non_abi3_symbols": [], "future_abi3_objects": {"PyUnicode_AsUTF8AndSize": "3.10"}}}}}}
|
|
</pre>
|
|
</div>
|
|
<p> Note that ABI conformance as measured by <tt>abi3audit</tt> is far
|
|
from simple and can depend on function inlining. There are functions in
|
|
Python.h, which if inlined, become ABI compliant. Your chances of your
|
|
C or C++ compiler inlining functions is greater with higher compiler
|
|
optimisation levels. So merely by changing your compiler optimisation
|
|
level may switch your Python extension from being identified as ABI
|
|
compliant or not.</p>
|
|
<p><b> Compatibility Note:</b> Support for the stable ABI was added in
|
|
SWIG-4.2.0.</p>
|
|
<h2><a name="Python_nn45">33.7 Tips and techniques</a></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">33.7.1 Input and output parameters</a></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 *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">33.7.2 Simple pointers</a></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">33.7.3 Unbounded C Arrays</a></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">33.7.4 String handling</a></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, size_t LENGTH) { (char *data, size_t size) };
|
|
...
|
|
int parity(char *data, size_t 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_default_args">33.7.5 Default arguments</a></h3>
|
|
<p> C++ default argument code generation is documented in the main <a href="#SWIGPlus_default_args">
|
|
Default arguments</a> section. There is also an optional Python specific
|
|
feature that can be used called the <tt>python:cdefaultargs</tt> <a href="#Customization_feature_flags">
|
|
feature flag</a>. By default, SWIG attempts to convert C++ default
|
|
argument values into Python values and generates code into the Python
|
|
layer containing these values. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct CDA {
|
|
int fff(int a = 1, bool b = false);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> From Python this can be called as follows:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> CDA().fff() # C++ layer receives a=1 and b=false
|
|
>>> CDA().fff(2) # C++ layer receives a=2 and b=false
|
|
>>> CDA().fff(3, True) # C++ layer receives a=3 and b=true
|
|
</pre>
|
|
</div>
|
|
<p> The default code generation in the Python layer is:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class CDA(object):
|
|
...
|
|
def fff(self, a=1, b=False):
|
|
return _default_args.CDA_fff(self, a, b)
|
|
</pre>
|
|
</div>
|
|
<p> Adding the feature:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("python:cdefaultargs") CDA::fff;
|
|
struct CDA {
|
|
int fff(int a = 1, bool b = false);
|
|
</pre>
|
|
</div>
|
|
<p> results in identical behaviour when called from Python, however, it
|
|
results in different code generation:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class CDA(object):
|
|
...
|
|
def fff(self, *args):
|
|
return _default_args.CDA_fff(self, *args)
|
|
</pre>
|
|
</div>
|
|
<p> The default arguments are obtained in the C++ wrapper layer instead
|
|
of the Python layer. Some code generation modes are quite different, eg
|
|
<tt>-builtin</tt> and <tt>-fastproxy</tt>, and are unaffected by <tt>
|
|
python:cdefaultargs</tt> as the default values are always obtained from
|
|
the C++ layer.</p>
|
|
<p> Note that not all default arguments can be converted into a Python
|
|
equivalent. When SWIG does not convert them, it will generate code to
|
|
obtain them from the C++ layer as if <tt>python:cdefaultargs</tt> was
|
|
specified. This will happen if just one argument cannot be converted
|
|
into a Python equivalent. This occurs typically when the argument is
|
|
not fully numeric, such as <tt>int(1)</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
struct CDA {
|
|
int fff(int a = int(1), bool b = false);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility Note:</b> SWIG-3.0.6 introduced the <tt>
|
|
python:cdefaultargs</tt> feature. Versions of SWIG prior to this varied
|
|
in their ability to convert C++ default values into equivalent Python
|
|
default argument values.</p>
|
|
<h2><a name="Python_nn53">33.8 Typemaps</a></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">33.8.1 What is a typemap?</a></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.");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
%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">33.8.2 Python typemaps</a></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">33.8.3 Typemap variables</a></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">33.8.4 Useful Python Functions</a></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">33.9 Typemap Examples</a></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">33.9.1 Converting a Python list to a char **</a>
|
|
</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. SWIG provides typemaps which allow passing a Python list or
|
|
tuple - see <a href="#Library_argcargv">argcargv.i</a>.</p>
|
|
<h3><a name="Python_nn60">33.9.2 Expanding a Python object into multiple
|
|
arguments</a></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");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
$2[i] = 0;
|
|
} else {
|
|
PyErr_SetString(PyExc_TypeError, "not a list");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
|
|
%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>
|
|
<p> If your function is overloaded in C++, for example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int foo(int argc, char **argv);
|
|
int foo();
|
|
</pre>
|
|
</div>
|
|
<p> don't forget to also provide a suitable <a href="#Typemaps_overloading">
|
|
typecheck typemap for overloading</a> such as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typecheck(SWIG_TYPECHECK_STRING_ARRAY) (int argc, char **argv) {
|
|
$1 = PyList_Check($input) ? 1 : 0;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> If you don't you'll get an error message along the lines of:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
Traceback (most recent call last):
|
|
File "runme.py", line 3, in >module<
|
|
example.foo(["foo", "bar", "spam", "1"])
|
|
TypeError: Wrong number or type of arguments for overloaded function 'foo'.
|
|
Possible C/C++ prototypes are:
|
|
foo(int, char **)
|
|
foo()
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Python_nn61">33.9.3 Using typemaps to return arguments</a></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($result, 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">33.9.4 Mapping Python tuples into small arrays</a>
|
|
</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");
|
|
SWIG_fail;
|
|
}
|
|
$1 = &temp[0];
|
|
} else {
|
|
PyErr_SetString(PyExc_TypeError, "expected a tuple.");
|
|
SWIG_fail;
|
|
}
|
|
}
|
|
|
|
</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">33.9.5 Mapping sequences to C arrays</a></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");
|
|
SWIG_fail;
|
|
}
|
|
if (PyObject_Length($input) != $1_dim0) {
|
|
PyErr_SetString(PyExc_ValueError, "Expecting a sequence with $1_dim0 elements");
|
|
SWIG_fail;
|
|
}
|
|
for (i =0; i < $1_dim0; i++) {
|
|
PyObject *o = PySequence_GetItem($input, i);
|
|
if (!PyFloat_Check(o)) {
|
|
Py_DecRef(o);
|
|
PyErr_SetString(PyExc_ValueError, "Expecting a sequence of floats");
|
|
SWIG_fail;
|
|
}
|
|
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_DecRef(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)) {
|
|
SWIG_fail;
|
|
}
|
|
$1 = &temp[0];
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Python_nn64">33.9.6 Pointer handling</a></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_DISOWN</tt> (which steals ownership of the
|
|
object) and <tt>SWIG_POINTER_NO_NULL</tt> (which makes the conversion
|
|
fail if the C pointer would be <tt>NULL</tt>). 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_IsOK(SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
|
|
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_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
}
|
|
</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_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
}
|
|
</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>
|
|
<h3><a name="Python_memory_management_member_variables">33.9.7 Memory
|
|
management when returning references to member variables</a></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>
|
|
#include <iostream>
|
|
struct Wheel {
|
|
int size;
|
|
Wheel(int sz = 0) : size(sz) {}
|
|
~Wheel() { std::cout << "~Wheel" << std::endl; }
|
|
};
|
|
|
|
class Bike {
|
|
Wheel wheel;
|
|
public:
|
|
Bike(int val) : wheel(val) {}
|
|
Wheel& getWheel() { return wheel; }
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> and the following usage from Python after running the code through
|
|
SWIG:</p>
|
|
<div class="code">
|
|
<pre>
|
|
bike = Bike(10)
|
|
wheel = bike.getWheel()
|
|
print("wheel size: {}".format(wheel.size))
|
|
|
|
del bike # Allow bike to be garbage collected
|
|
print("wheel size: {}".format(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
|
|
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.</p>
|
|
<p> You can do this by adding the reference when the <tt>getWheel()</tt>
|
|
method is called using one of three approaches:</p>
|
|
<p> The easier, but less optimized, way is to use the <tt>%pythonappend</tt>
|
|
directive (see <a href="#Python_nn42">Adding additional Python code</a>
|
|
):</p>
|
|
<div class="code">
|
|
<pre>
|
|
%pythonappend getWheel %{
|
|
# val is the Wheel proxy, self is the Bike instance
|
|
val.__bike_reference = self
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> The code gets appended to the Python code generated for the <tt>
|
|
Bike::getWheel</tt> wrapper function, where we store the <tt>Bike</tt>
|
|
proxy instance onto the <tt>Wheel</tt> proxy instance before it is
|
|
returned to the caller as follows.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class Bike(object):
|
|
...
|
|
def getWheel(self):
|
|
val = _example.Bike_getWheel(self)
|
|
|
|
# val is the Wheel proxy, self is the Bike instance
|
|
val.__bike_reference = self
|
|
|
|
return val
|
|
</pre>
|
|
</div>
|
|
<p> The second option, which performs better and is required if you use
|
|
the <tt>-builtin</tt> option, is to set the reference in the CPython
|
|
implementation:<div class="code">
|
|
<pre>
|
|
%extend Wheel {
|
|
// A reference to the parent class is added to ensure the underlying C++
|
|
// object is not deleted while the item is in use
|
|
%typemap(ret) Wheel& getWheel {
|
|
PyObject *bike_reference_string = SWIG_Python_str_FromChar("__bike_reference");
|
|
PyObject_SetAttr($result, bike_reference_string, $self);
|
|
Py_DecRef(bike_reference_string);
|
|
}
|
|
}
|
|
</pre>
|
|
</div></p>
|
|
<p> The third approach, shown below, is an optimization of the above
|
|
approach and creates the "__bike_reference" Python string object just
|
|
once. While this looks more complex, it is just a small variation on
|
|
the above typemap plus a support function <tt>bike_reference()</tt> in
|
|
a fragment called <tt>bike_reference_function</tt>. The <tt>
|
|
bike_reference_init</tt> typemap generates code into the "init" section
|
|
for an initial call to <tt>bike_reference()</tt> when the module is
|
|
initialized and is done to create the "__bike_reference" Python string
|
|
singleton in a thread-safe manner.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%fragment("bike_reference_init", "init") {
|
|
// Thread-safe initialization - initialize during Python module initialization
|
|
bike_reference();
|
|
}
|
|
|
|
%fragment("bike_reference_function", "header", fragment="bike_reference_init") {
|
|
|
|
static PyObject *bike_reference() {
|
|
static PyObject *bike_reference_string = SWIG_Python_str_FromChar("__bike_reference");
|
|
return bike_reference_string;
|
|
}
|
|
|
|
}
|
|
|
|
%extend Wheel {
|
|
// A reference to the parent class is added to ensure the underlying C++
|
|
// object is not deleted while the item is in use
|
|
%typemap(ret, fragment="bike_reference_function") Wheel& getWheel %{
|
|
PyObject_SetAttr($result, bike_reference(), $self);
|
|
%}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Python_nn65">33.10 Docstring Features</a></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">33.10.1 Module docstring</a></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">33.10.2 %feature("autodoc")</a></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
|
|
four levels for autodoc controlled by the value given to the feature, <tt>
|
|
%feature("autodoc", "<i>level</i>")</tt>. The four values for<i> level</i>
|
|
are covered in the following sub-sections.</p>
|
|
<h4><a name="Python_nn68">33.10.2.1 %feature("autodoc", "0")</a></h4>
|
|
<p> When level "0" is used 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">33.10.2.2 %feature("autodoc", "1")</a></h4>
|
|
<p> When level "1" 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 if the associated type is
|
|
has an associated Python type (<tt>%rename</tt>'s are thus shown
|
|
correctly). This works most of the time, otherwise a C/C++ type will be
|
|
used. See the next section for the "docstring" feature for tweaking the
|
|
docstrings to your liking. Given the example above, then turning on the
|
|
parameter types with level "1" 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_autodoc2">33.10.2.3 %feature("autodoc", "2")</a></h4>
|
|
<p> Level "2" results in the function prototype as per level "0". In
|
|
addition, a line of documentation is generated for each parameter using
|
|
<a href="https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt">
|
|
numpydoc</a> style. Using the previous example, the generated code will
|
|
be:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
def function_name(*args, **kwargs):
|
|
"""
|
|
function_name(x, y, foo=None, bar=None) -> bool
|
|
|
|
Parameters
|
|
----------
|
|
x: int
|
|
y: int
|
|
foo: Foo *
|
|
bar: Bar *
|
|
|
|
"""
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> Note that the documentation for each parameter is sourced from the
|
|
"doc" typemap which by default shows the C/C++ type rather than the
|
|
simplified Python type name described earlier for level "1". Typemaps
|
|
can of course change the output for any particular type, for example
|
|
the <tt>int x</tt> parameter:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("autodoc", "2");
|
|
%typemap("doc") int x "$1_name (C++ type: $1_type) -- Input $1_name dimension"
|
|
bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL);
|
|
</pre>
|
|
</div>
|
|
<p> resulting in</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
def function_name(*args, **kwargs):
|
|
"""
|
|
function_name(x, y, foo=None, bar=None) -> bool
|
|
|
|
Parameters
|
|
----------
|
|
x (C++ type: int) -- Input x dimension
|
|
y: int
|
|
foo: Foo *
|
|
bar: Bar *
|
|
|
|
"""
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Python_autodoc3">33.10.2.4 %feature("autodoc", "3")</a></h4>
|
|
<p> Level "3" results in the function prototype as per level "1" but
|
|
also contains the same additional line of documentation for each
|
|
parameter as per level "2". Using our earlier example again, the
|
|
generated code will be:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
def function_name(*args, **kwargs):
|
|
"""
|
|
function_name(int x, int y, Foo foo=None, Bar bar=None) -> bool
|
|
|
|
Parameters
|
|
----------
|
|
x: int
|
|
y: int
|
|
foo: Foo *
|
|
bar: Bar *
|
|
|
|
"""
|
|
...
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Python_nn70">33.10.2.5 %feature("autodoc", "docstring")</a></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">33.10.3 %feature("docstring")</a></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>
|
|
<h3><a name="Python_doxygen_docstrings">33.10.4 Doxygen comments</a></h3>
|
|
<p> Please see the separate <a href="#Doxygen">Doxygen</a> chapter for
|
|
information on making use of C++ Doxygen comments and translating them
|
|
into Python docstring comments.</p>
|
|
<p> Note that when generating docstrings and Doxygen comments have also
|
|
been turned on, the <a href="#Python_nn71">docstring feature</a> will
|
|
take precedence over a Doxygen comment. If the <a href="#Python_nn67">
|
|
autodoc feature</a> is also turned on, then it will be used in
|
|
conjunction with the docstring feature. However, if there is no
|
|
docstring feature present and there is a Doxygen comment, then the
|
|
autodoc docstring will not be generated. The Doxygen comment alone will
|
|
be used.</p>
|
|
<p> This way, if the autodoc feature is specified globally it will fill
|
|
in any missing Doxygen documentation comments. Doxygen comments can be
|
|
overridden by using the docstring feature.</p>
|
|
<h2><a name="Python_nn72">33.11 Python Packages</a></h2>
|
|
<p>Python has concepts of modules and packages. Modules are separate
|
|
units of code and may be grouped together to form a package. Packages
|
|
may be nested, that is they may contain subpackages. This leads to
|
|
tree-like hierarchy, with packages as intermediate nodes and modules as
|
|
leaf nodes.</p>
|
|
<p>The hierarchy of Python packages/modules follows the hierarchy of <tt>
|
|
*.py</tt> files found in a source tree (or, more generally, in the
|
|
Python path). Normally, the developer creates new module by placing a <tt>
|
|
*.py</tt> file somewhere under Python path; the module is then named
|
|
after that <tt>*.py</tt> file. A package is created by placing an <tt>
|
|
__init__.py</tt> file within a directory; the package is then named
|
|
after that directory. For example, the following source tree:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
mod1.py
|
|
pkg1/__init__.py
|
|
pkg1/mod2.py
|
|
pkg1/pkg2/__init__.py
|
|
pkg1/pkg2/mod3.py
|
|
</pre>
|
|
</div>
|
|
<p> defines the following Python packages and modules:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
pkg1 # package
|
|
pkg1.pkg2 # package
|
|
mod1 # module
|
|
pkg1.mod2 # module
|
|
pkg1.pkg2.mod3 # module
|
|
</pre>
|
|
</div>
|
|
<p> The purpose of an <tt>__init__.py</tt> file is two-fold. First, the
|
|
existence of <tt>__init__.py</tt> in a directory informs the Python
|
|
interpreter that this directory contains a Python package. Second, the
|
|
code in <tt>__init__.py</tt> is loaded/executed automatically when the
|
|
package is initialized (when it or its submodule/subpackage gets <tt>
|
|
import</tt>'ed). By default, SWIG generates proxy Python code – one <tt>
|
|
*.py</tt> file for each <tt>*.i</tt> interface. The <tt>__init__.py</tt>
|
|
files, however, are not generated by SWIG. They should be created by
|
|
other means. Both files (module <tt>*.py</tt> and <tt>__init__.py</tt>)
|
|
should be installed in appropriate destination directories in order to
|
|
obtain a desirable package/module hierarchy.</p>
|
|
<p> Python3 adds another option for packages with <a href="https://www.python.org/dev/peps/pep-0420/">
|
|
PEP 0420</a> (implicit namespace packages). Implicit namespace packages
|
|
no longer use __init__.py files. SWIG generated Python modules support
|
|
implicit namespace packages. See <a href="#Python_implicit_namespace_packages">
|
|
Implicit namespace packages</a> for more information.</p>
|
|
<p> You can place a SWIG generated module into a Python package or keep
|
|
as a global module, details are covered a little later in <a href="#Python_package_search">
|
|
Location of modules</a>.</p>
|
|
<p>The way Python defines its modules and packages impacts SWIG users.
|
|
Some users may need to use special features such as the <tt>package</tt>
|
|
option in the <tt>%module</tt> directive or import related command line
|
|
options. These are explained in the following sections.</p>
|
|
<h3><a name="Python_modulepackage">33.11.1 Setting the Python package</a>
|
|
</h3>
|
|
<p> Using the <tt>package</tt> option in the <tt>%module</tt> directive
|
|
allows you to specify a Python package that the module will be 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 this 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 in base class declarations,
|
|
etc..</p>
|
|
<p>SWIG assumes that the <tt>package</tt> option provided to <tt>%module</tt>
|
|
together with the <tt>module</tt> name (that is, <tt>wx.xrc</tt> in the
|
|
above example) forms a fully qualified (absolute) name of a module (in
|
|
Python terms). This is important especially for Python 3, where
|
|
absolute imports are used by default. It's up to you to place the
|
|
generated module files (<tt>.py</tt>, <tt>.so</tt>) in appropriate
|
|
subdirectories. For example, if you have an interface file <tt>foo.i</tt>
|
|
with:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(package="pkg1.pkg2") foo
|
|
</pre>
|
|
</div>
|
|
<p> then the resulting directory layout should be</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
pkg1/
|
|
pkg1/__init__.py
|
|
pkg1/pkg2/__init__.py
|
|
pkg1/pkg2/foo.py # (generated by SWIG)
|
|
pkg1/pkg2/_foo.so # (shared library built from C/C++ code generated by SWIG)
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Python_absrelimports">33.11.2 Absolute and relative imports</a>
|
|
</h3>
|
|
<p>Suppose, we have the following hierarchy of files:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
pkg1/
|
|
pkg1/__init__.py
|
|
pkg1/mod2.py
|
|
pkg1/pkg2/__init__.py
|
|
pkg1/pkg2/mod3.py
|
|
</pre>
|
|
</div>
|
|
<p>Let the contents of <tt>pkg1/pkg2/mod3.py</tt> be</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class M3: pass
|
|
</pre>
|
|
</div>
|
|
<p> We edit <tt>pkg1/mod2.py</tt> and want to import module <tt>
|
|
pkg1/pkg2/mod3.py</tt> in order to derive from class <tt>M3</tt>. We can
|
|
write appropriate Python code in several ways, for example:</p>
|
|
<ol>
|
|
<li>
|
|
<p>Using "<tt>import <></tt>" syntax with absolute package name:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
# pkg1/mod2.py
|
|
import pkg1.pkg2.mod3
|
|
class M2(pkg1.pkg2.mod3.M3): pass
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>Using "<tt>import <></tt>" syntax with package name relative to <tt>
|
|
pkg1</tt> (only in Python 2.7 and earlier):</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
# pkg1/mod2.py
|
|
import pkg2.mod3
|
|
class M2(pkg2.mod3.M3): pass
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>Using "<tt>from <> import <></tt>" syntax (relative import syntax,
|
|
only in Python 2.5 and later):</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
# pkg1/mod2.py
|
|
from .pkg2 import mod3
|
|
class M2(mod3.M3): pass
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>Other variants, for example the following construction in order to
|
|
have the <tt>pkg2.mod3.M3</tt> symbol available in <tt>mod2</tt> as in
|
|
point 2 above (but now under Python 3):</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
# pkg1/mod2.py
|
|
from . import pkg2
|
|
from .pkg2 import mod3
|
|
class M2(pkg2.mod3.M3): pass
|
|
</pre>
|
|
</div></li>
|
|
</ol>
|
|
<p>Now suppose we have <tt>mod2.i</tt> with</p>
|
|
<div class="code">
|
|
<pre>
|
|
// mod2.i
|
|
%module (package="pkg1") mod2
|
|
%import "mod3.i"
|
|
// ...
|
|
</pre>
|
|
</div>
|
|
<p>and <tt>mod3.i</tt> with</p>
|
|
<div class="code">
|
|
<pre>
|
|
// mod3.i
|
|
%module (package="pkg1.pkg2") mod3
|
|
// ...
|
|
</pre>
|
|
</div>
|
|
<p>By default, SWIG will generate <tt>mod2.py</tt> proxy file with <tt>
|
|
import</tt> directive as in point 1. This can be changed with the <tt>
|
|
-relativeimport</tt> command line option. The <tt>-relativeimport</tt>
|
|
instructs SWIG to organize imports as in point 4 for Python 2.7.0 and
|
|
newer.</p>
|
|
<p><b> Compatibility Note:</b> Versions of SWIG prior to SWIG-4.0.0
|
|
supported Python < 2.7.0 and would organize the imports as in point 2
|
|
if an older version of Python was detected at runtime.</p>
|
|
<p> In short, if you have <tt>mod2.i</tt> and <tt>mod3.i</tt> as above,
|
|
then without <tt>-relativeimport</tt> SWIG will write</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
import pkg1.pkg2.mod3
|
|
</pre>
|
|
</div>
|
|
<p>to <tt>mod2.py</tt> proxy file, and with <tt>-relativeimport</tt> it
|
|
will write</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from . import pkg2
|
|
from .pkg2 import mod3
|
|
</pre>
|
|
</div>
|
|
<p>You should avoid using relative imports and use absolute ones
|
|
whenever possible. There are some cases, however, when relative imports
|
|
may be necessary. The first example is, when some (legacy) Python code
|
|
refers entities imported by proxy files generated by SWIG, and it
|
|
assumes that the proxy file uses relative imports. Second case is, when
|
|
one puts import directives in <tt>__init__.py</tt> to import symbols
|
|
from submodules or subpackages and the submodule depends on other
|
|
submodules (discussed later).</p>
|
|
<h3><a name="Python_absimport">33.11.3 Enforcing absolute import
|
|
semantics</a></h3>
|
|
<p>As you may know, there is an incompatibility in import semantics (for
|
|
the <tt>import <></tt> syntax) between Python 2 and 3. In Python 2.4
|
|
and earlier it is not clear whether</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
import foo
|
|
</pre>
|
|
</div>
|
|
<p>refers to a top-level module or to another module inside the current
|
|
package. In Python 3 it always refers to a top-level module (see <a href="https://www.python.org/dev/peps/pep-0328/">
|
|
PEP 328</a>). To instruct Python 2.5 through 2.7 to use new semantics
|
|
(that is <tt>import foo</tt> is interpreted as absolute import), one
|
|
has to put the following line</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from __future__ import absolute_import
|
|
</pre>
|
|
</div>
|
|
<p>at the very beginning of your proxy <tt>*.py</tt> file. In SWIG, it
|
|
may be accomplished with <tt>%pythonbegin</tt> directive as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%pythonbegin %{
|
|
from __future__ import absolute_import
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Python_importfrominit">33.11.4 Importing from __init__.py</a>
|
|
</h3>
|
|
<p>Imports in <tt>__init__.py</tt> are handy when you want to populate a
|
|
package's namespace with names imported from other modules. In SWIG
|
|
based projects this approach may also be used to split large pieces of
|
|
code into smaller modules, compile them in parallel and then
|
|
re-assemble everything at runtime by importing submodules' contents in <tt>
|
|
__init__.py</tt>, for example.</p>
|
|
<p>Unfortunately import directives in <tt>__init__.py</tt> may cause
|
|
problems, especially if they refer to a package's submodules. This is
|
|
caused by the way Python initializes packages. If you spot problems
|
|
with imports from <tt>__init__.py</tt> try using <tt>-relativeimport</tt>
|
|
option. Below we explain in detail one issue, for which the <tt>
|
|
-relativeimport</tt> workaround may be helpful.</p>
|
|
<p>Consider the following example (Python 3):</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
pkg1/__init__.py # (empty)
|
|
pkg1/pkg2/__init__.py # (imports something from bar.py)
|
|
pkg1/pkg2/foo.py
|
|
pkg1/pkg2/bar.py # (imports foo.py)
|
|
</pre>
|
|
</div>
|
|
<p>If the file contents are:</p>
|
|
<ul>
|
|
<li>
|
|
<p><tt>pkg1/pkg2/__init__.py:</tt></p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
# pkg1/pkg2/__init__.py
|
|
from .bar import Bar
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p><tt>pkg1/pkg2/foo.py:</tt></p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
# pkg1/pkg2/foo.py
|
|
class Foo: pass
|
|
</pre>
|
|
</div></li>
|
|
<li>
|
|
<p><tt>pkg1/pkg2/bar.py:</tt></p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
# pkg1/pkg2/bar.py
|
|
import pkg1.pkg2.foo
|
|
class Bar(pkg1.pkg2.foo.Foo): pass
|
|
</pre>
|
|
</div></li>
|
|
</ul>
|
|
<p>Now if one simply used <tt>import pkg1.pkg2</tt>, it will usually
|
|
fail:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
>>> import pkg1.pkg2
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in <module>
|
|
File "./pkg1/pkg2/__init__.py", line 2, in <module>
|
|
from .bar import Bar
|
|
File "./pkg1/pkg2/bar.py", line 3, in <module>
|
|
class Bar(pkg1.pkg2.foo.Foo): pass
|
|
AttributeError: 'module' object has no attribute 'pkg2'
|
|
</pre>
|
|
</div>
|
|
<p>Surprisingly, if we execute the <tt>import pkg1.pkg2</tt> directive
|
|
for the second time, it succeeds. The reason seems to be following:
|
|
when Python spots the <tt>from .bar import Bar</tt> directive in <tt>
|
|
pkg1/pkg2/__init__.py</tt> it starts loading <tt>pkg1/pkg2/bar.py</tt>.
|
|
This module imports <tt>pkg1.pkg2.foo</tt> in turn and tries to use <tt>
|
|
pkg1.pkg2.foo.Foo</tt>, but the package <tt>pkg1</tt> is not fully
|
|
initialized yet (the initialization procedure is actually in progress)
|
|
and it seems like the effect of the already seen <tt>import
|
|
pkg1.pkg2.pkg3.foo</tt> is "delayed" or ignored. Exactly the same may
|
|
happen to a proxy module generated by SWIG.</p>
|
|
<p>One workaround for this case is to use a relative import in <tt>
|
|
pkg1/pkg2/bar.py</tt>. If we change <tt>bar.py</tt> to be:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from .pkg3 import foo
|
|
class Bar(foo.Foo): pass
|
|
</pre>
|
|
</div>
|
|
<p>or</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from . import pkg3
|
|
from .pkg3 import foo
|
|
class Bar(pkg3.foo.Foo): pass
|
|
</pre>
|
|
</div>
|
|
<p>then the example works again. With SWIG, you need to enable the <tt>
|
|
-relativeimport</tt> option in order to have the above workaround in
|
|
effect (note, that the Python 2 case also needs the <tt>-relativeimport</tt>
|
|
workaround).</p>
|
|
<h3><a name="Python_implicit_namespace_packages">33.11.5 Implicit
|
|
namespace packages</a></h3>
|
|
<p> Python 3.3 introduced <a href="https://www.python.org/dev/peps/pep-0420/">
|
|
PEP 0420</a> which implements implicit namespace packages. In a
|
|
nutshell, implicit namespace packages remove the requirement of an
|
|
__init__.py file and allow packages to be split across multiple PATH
|
|
elements. For example:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
/fragment1/pkg1/mod1.py
|
|
/fragment2/pkg1/mod2.py
|
|
/fragment3/pkg1/mod3.py
|
|
</pre>
|
|
</div>
|
|
<p>If PYTHONPATH is set to "/fragment1:/fragment2:/fragment3", then
|
|
mod1, mod2 and mod3 will be part of pkg1. This allows for splitting of
|
|
packages into separate pieces. This can be useful for SWIG generated
|
|
wrappers in the following way.</p>
|
|
<p> Suppose you create a SWIG wrapper for a module called robin. The
|
|
SWIG generated code consists of two files robin.py and _robin.so. You
|
|
wish to make these modules part of a subpackage (brave.sir). With
|
|
implicit namespace packages you can place these files in the following
|
|
configurations:</p>
|
|
<p>Using PYTHONPATH="/some/path"</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
/some/path/brave/sir/robin.py
|
|
/some/path/brave/sir/_robin.so
|
|
</pre>
|
|
</div>
|
|
<p>Using PYTHONPATH="/some/path:/some/other/path"<div class="diagram">
|
|
<pre>
|
|
/some/path/brave/sir/robin.py
|
|
/some/other/path/brave/sir/_robin.so
|
|
</pre>
|
|
</div></p>
|
|
<p> Finally suppose that your pure Python code is stored in a .zip file
|
|
or some other way (database, web service connection, etc). Python can
|
|
load the robin.py module using a custom importer. But the _robin.so
|
|
module will need to be located on a file system. Implicit namespace
|
|
packages make this possible. For example, using
|
|
PYTHONPATH="/some/path/foo.zip:/some/other/path"</p>
|
|
<p> Contents of foo.zip</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
brave/
|
|
brave/sir/
|
|
brave/sir/robin.py
|
|
</pre>
|
|
</div>
|
|
<p> File system contents</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
/some/other/path/brave/sir/_robin.so
|
|
</pre>
|
|
</div>
|
|
<p>Support for implicit namespace packages was added to python-3.3. The
|
|
zipimporter requires python-3.5.1 or newer to work with subpackages.</p>
|
|
<p><b> Compatibility Note:</b> Support for implicit namespace packages
|
|
was added in SWIG-3.0.9.</p>
|
|
<h3><a name="Python_package_search">33.11.6 Location of modules</a></h3>
|
|
<p> When SWIG creates wrappers from an interface file, say foo.i, two
|
|
Python modules are created. There is a pure Python module (foo.py) and
|
|
C/C++ code which is compiled and linked into a dynamically (or
|
|
statically) loaded low-level module _foo (see the <a href="#Python_nn3">
|
|
Preliminaries section</a> for details). So, the interface file really
|
|
defines two Python modules. How these two modules are loaded is covered
|
|
next.</p>
|
|
<p> The pure Python module needs to load the C/C++ module in order to
|
|
call the wrapped C/C++ methods. To do this it must make some
|
|
assumptions about the location of the C/C++ module. There are two
|
|
configurations that are supported by default.</p>
|
|
<ol>
|
|
<li>
|
|
<p>Both modules in the same package</p>
|
|
</li>
|
|
<li>
|
|
<p>Both modules are global</p>
|
|
</li>
|
|
</ol>
|
|
<p> Additional configurations are supported but require custom import
|
|
code.</p>
|
|
<p> The following sub-sections look more closely at the two default
|
|
configurations as well as some customized configurations. An input
|
|
interface file, foo.i, results in the two modules foo.py and _foo.so
|
|
for each of the configurations.</p>
|
|
<h4><a name="Python_package_search_both_package_modules">33.11.6.1 Both
|
|
modules in the same package</a></h4>
|
|
<p> In this configuration, the pure Python module, foo.py, tries to load
|
|
the C/C++ module, _foo, from the same package foo.py is located in. The
|
|
package name is determined from the <tt>__package__</tt> attribute if
|
|
available, see <a href="https://www.python.org/dev/peps/pep-0366/">PEP
|
|
366</a>. Otherwise it is derived from the <tt>__name__</tt> attribute
|
|
given to foo.py by the Python loader that imported foo.py. The
|
|
interface file for this configuration would contain:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(package="mypackage") foo
|
|
</pre>
|
|
</div>
|
|
<p>The location of the files could be as follows:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
/dir/mypackage/foo.py
|
|
/dir/mypackage/__init__.py
|
|
/dir/mypackage/_foo.so
|
|
</pre>
|
|
</div>
|
|
<p>Assuming /dir/ is in PYTHONPATH, the module can be imported using</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from mypackage import foo
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Python_package_search_both_global_modules">33.11.6.2 Both
|
|
modules are global</a></h4>
|
|
<p> In this configuration, there are no packages. If foo.py is not in a
|
|
package, that is, it is a global module, then _foo is loaded as a
|
|
global module. The interface file for this configuration would contain:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module foo
|
|
</pre>
|
|
</div>
|
|
<p>The location of the files could be as follows:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
/dir/foo.py
|
|
/dir/_foo.so
|
|
</pre>
|
|
</div>
|
|
<p>Assuming /dir/ is in PYTHONPATH, the module can be imported using</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
import foo
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Python_package_search_wrapper_split">33.11.6.3 Split
|
|
modules custom configuration</a></h4>
|
|
<p>In this non-standard 'split module' configuration, the pure Python
|
|
module is in a package and the low level C/C++ module is global. This
|
|
configuration is not generally recommended and is not supported by
|
|
default as it needs a custom configuration. The module import code
|
|
customization required is via the <tt>moduleimport</tt> attribute in
|
|
the <tt>%module</tt> directive. The next sub-section elaborates further
|
|
on this. The interface file for this split module configuration would
|
|
contain:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(package="mypackage", moduleimport="import _foo") foo
|
|
</pre>
|
|
</div>
|
|
<p> When using <tt>-builtin</tt>, use the following instead (the reasons
|
|
are also covered shortly in the next sub-section):</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(package="mypackage", moduleimport="from _foo import *") foo
|
|
</pre>
|
|
</div>
|
|
<p>The location of the files could be as follows:</p>
|
|
<div class="diagram">
|
|
<pre>
|
|
/dir/mypackage/foo.py
|
|
/dir/mypackage/__init__.py
|
|
/dir/_foo.so
|
|
</pre>
|
|
</div>
|
|
<p>Assuming /dir/ is in PYTHONPATH, the module can be imported using</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
from mypackage import foo
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility Note:</b> Versions of SWIG prior to SWIG-4.0.0
|
|
supported split modules without the above customization. However, this
|
|
had to be removed as the default import code often led to confusion due
|
|
to obfuscation of genuine Python <tt>ImportError</tt> problems. Using
|
|
one of the two default configurations is the recommended approach now.</p>
|
|
<h4><a name="Python_custom_module_import">33.11.6.4 More on customizing
|
|
the module import code</a></h4>
|
|
<p> The Python code implementing the default import logic is shown
|
|
below. It supports the two configurations described earlier, that is,
|
|
either both modules are in a package or loading both as global modules.
|
|
The code is generated into the pure Python module, foo.py, and merely
|
|
imports the low-level _foo module.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
if __package__ or '.' in __name__:
|
|
from . import _foo
|
|
else:
|
|
import _foo
|
|
</pre>
|
|
</div>
|
|
<p> This import code implementation is non-trivial but it can be
|
|
replaced with custom code providing opportunities to make it simpler
|
|
and/or more flexible. This is not normally recommended though unless
|
|
you have a good understanding of the intricacies of importing Python
|
|
modules. The custom code can be specified by setting the <tt>
|
|
moduleimport</tt> option of the <tt>%module</tt> directive with the
|
|
appropriate import code. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(moduleimport="import _foo") foo
|
|
</pre>
|
|
</div>
|
|
<p> This will replace the default import logic above and generate the
|
|
following into the pure Python module, foo.py:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
import _foo
|
|
</pre>
|
|
</div>
|
|
<p> In fact the above is a simplification customization for the
|
|
configuration where both modules are global; it removes the logic for
|
|
also handling the modules being in a package.</p>
|
|
<p> There is a special variable, <tt>$module</tt>, which is expanded
|
|
into the low-level C/C++ module name, <tt>_foo</tt> in the case above.
|
|
The identical output would be generated if instead the following had
|
|
been used:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module(moduleimport="import $module") foo
|
|
</pre>
|
|
</div>
|
|
<p> When you have many lines you can retain the easy readability of the <tt>
|
|
%module</tt> directive by using a macro. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%define MODULEIMPORT
|
|
"
|
|
print('Loading low-level module $module')
|
|
import $module
|
|
print('Module has loaded')
|
|
"
|
|
%enddef
|
|
|
|
%module(moduleimport=MODULEIMPORT) foo
|
|
</pre>
|
|
</div>
|
|
<p> This will of course generate the following into the pure Python
|
|
module:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
print('Loading low-level module $module')
|
|
import _foo
|
|
print('Module has loaded')
|
|
</pre>
|
|
</div>
|
|
<p> When using the <tt>-builtin</tt> option, the link between the pure
|
|
Python module and the low-level C/C++ module is slightly different as
|
|
all the objects from the low-level module are imported directly into
|
|
the pure Python module. The default import loading code is thus
|
|
different:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
if __package__ or '.' in __name__:
|
|
from ._foo import *
|
|
else:
|
|
from _foo import *
|
|
</pre>
|
|
</div>
|
|
<p> Any customizations must import the code in a similar manner. The
|
|
best way to support both with and without <tt>-builtin</tt> is to make
|
|
use of the <tt>SWIGPYTHON_BUILTIN</tt> macro which is defined when <tt>
|
|
-builtin</tt> is specified. The following will do this for the <a href="#Python_package_search_wrapper_split">
|
|
split modules</a> case above.</p>
|
|
<div class="code">
|
|
<pre>
|
|
#if defined(SWIGPYTHON_BUILTIN) /* defined when using -builtin */
|
|
%module(package="mypackage", moduleimport="from $module import *") foo
|
|
#else
|
|
%module(package="mypackage", moduleimport="import $module") foo
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Python_package_search_static">33.11.6.5 Statically linked C
|
|
modules</a></h4>
|
|
<p>It is strongly recommended to use dynamically linked modules for the
|
|
C portion of your pair of Python modules. If for some reason you still
|
|
need to link the C module of the pair of Python modules generated by
|
|
SWIG into your interpreter, then this section provides some details on
|
|
how this impacts the pure Python modules ability to locate the other
|
|
part of the pair. Please also see the <a href="#Python_nn8">Static
|
|
Linking</a> section.</p>
|
|
<p>When Python is extended with C code the Python interpreter needs to
|
|
be informed about details of the new C functions that have been linked
|
|
into the executable. The code to do this is created by SWIG and is
|
|
automatically called in the correct way when the module is dynamically
|
|
loaded. However when the code is not dynamically loaded (because it is
|
|
statically linked) Then the initialization method for the module
|
|
created by SWIG is not called automatically and the Python interpreter
|
|
has no idea that the new SWIG C module exists.</p>
|
|
<p>Before Python 3, one could simply call the init method created by
|
|
SWIG which would have normally been called when the shared object was
|
|
dynamically loaded. The specific name of this method is not given here
|
|
because statically linked modules are not encouraged with SWIG (<a href="#Python_nn8">
|
|
Static Linking</a>). However one can find this init function in the C
|
|
file generated by SWIG.</p>
|
|
<p>If you are really keen on static linking there are two ways to
|
|
initialize the SWIG generated C module with the init method. Which way
|
|
you use depends on what version of Python your module is being linked
|
|
with. Python 2 and Python 3 treat this init function differently. And
|
|
the way they treat it affects how the pure Python module will be able
|
|
to locate the C module.</p>
|
|
<p>The details concerning this are covered completely in the
|
|
documentation for Python itself. Links to the relevant sections follow:</p>
|
|
<ul>
|
|
<li><a href="https://docs.python.org/2/extending/extending.html#methodtable">
|
|
Extending in python2</a></li>
|
|
<li><a href="https://docs.python.org/3.6/extending/extending.html#the-module-s-method-table-and-initialization-function">
|
|
Extending in python3</a></li>
|
|
</ul>
|
|
<p>There are two keys things to understand. The first is that in Python
|
|
2 the init() function returns void. In Python 3 the init() function
|
|
returns a <tt>PyObject *</tt> which points to the new module. Secondly,
|
|
when you call the init() method manually, you are the Python importer.
|
|
So, you determine which package the C module will be located in.</p>
|
|
<p>So, if you are using Python 3 it is important that you follow what is
|
|
described in the Python documentation linked above. In particular, you
|
|
can't simply call the init() function generated by SWIG and cast the <tt>
|
|
PyObject</tt> pointer it returns over the side. If you do then Python 3
|
|
will have no idea that your C module exists and the pure Python half of
|
|
your wrapper will not be able to find it. You need to register your
|
|
module with the Python interpreter as described in the Python docs.</p>
|
|
<p>With Python 2 things are somewhat more simple. In this case the
|
|
init() function returns void. Calling it will register your new C
|
|
module as a<b> global</b> module. The pure Python part of the SWIG
|
|
wrapper will be able to find it because it tries both the pure Python
|
|
module it is part of and the global module. If you wish not to have the
|
|
statically linked module be a global module then you will either need
|
|
to refer to the Python documentation on how to do this (remember you
|
|
are now the Python importer) or use dynamic linking.</p>
|
|
<h2><a name="Python_python3support">33.12 Python 3 Support</a></h2>
|
|
<p> SWIG is able to support Python 3.x. The wrapper code generated by
|
|
SWIG can be compiled with both Python 2.x or 3.x.</p>
|
|
<p> The list of known-to-be-broken features around Python 3 are:</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 new features that are currently supported
|
|
by SWIG.</p>
|
|
<h3><a name="Python_annotations">33.12.1 Python function annotations and
|
|
variable annotations</a></h3>
|
|
<p> Python 3 supports function annotations as defined in <a href="https://www.python.org/dev/peps/pep-3107/">
|
|
PEP 3107</a>. Python 3.6 and later additionally support variable
|
|
annotations as defined in <a href="https://www.python.org/dev/peps/pep-526/">
|
|
PEP 526</a>. Note that currently there is no annotations support in SWIG
|
|
for the <tt>-builtin</tt> nor the <tt>-fastproxy</tt> option.
|
|
Annotations are added via the <tt>python:annotations</tt> <a href="#Customization_features">
|
|
%feature directives</a>. SWIG currently supports one type of function
|
|
annotation.</p>
|
|
<h4><a name="Python_annotations_c">33.12.1.1 C/C++ annotation types</a></h4>
|
|
<p> The <tt>%feature("python:annotations", "c")</tt> directive generates
|
|
annotations containing C/C++ types. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("python:annotations", "c") global_ints;
|
|
int *global_ints(int &ri);
|
|
</pre>
|
|
</div>
|
|
<p> The generated code then contains function annotations containing the
|
|
C++ types:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
def global_ints(ri: "int &") -> "int *":
|
|
return _example.global_ints(ri)
|
|
</pre>
|
|
</div>
|
|
<p> There are some limitations with function annotations support, for
|
|
example, overloaded functions use <tt>*args</tt> or <tt>**kwargs</tt>
|
|
when keyword arguments are enabled. The parameter names and types are
|
|
then not shown. For example, with input:</p>
|
|
<div class="code">
|
|
<pre>
|
|
int *global_overloaded(int &ri);
|
|
int *global_overloaded();
|
|
</pre>
|
|
</div>
|
|
<p> The generated Python function including annotations is shown below.
|
|
Only the return type is annotated.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
def global_overloaded(*args) -> "int *":
|
|
return _example.global_overloaded(*args)
|
|
</pre>
|
|
</div>
|
|
<p> Below is an example demonstrating variable annotations.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("python:annotations", "c");
|
|
|
|
struct V {
|
|
float val;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The generated code contains a variable annotation containing the C <tt>
|
|
float</tt> type:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class V(object):
|
|
val: "float" = property(_example.V_val_get, _example.V_val_set)
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p> Variable annotations are only supported from Python 3.6. If you need
|
|
to support earlier versions of Python, you'll need to turn variable
|
|
annotations off via the <tt>python:annotations:novar</tt> feature flag.
|
|
It is quite easy to support function annotations but turn off variable
|
|
annotations. The next example shows how to do this for all variables.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%feature("python:annotations", "c"); // Turn on function annotations and variable annotations globally
|
|
%feature("python:annotations:novar"); // Turn off variable annotations globally
|
|
|
|
struct V {
|
|
float val;
|
|
void vv(float *v) const;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The resulting code will work with versions older than Python 3.6 as
|
|
the variable annotations are turned off:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class V(object):
|
|
val = property(_example.V_val_get, _example.V_val_set)
|
|
|
|
def vv(self, v: "float *") -> "void":
|
|
return _example.V_vv(self, v)
|
|
...
|
|
</pre>
|
|
</div>
|
|
<p><b> Compatibility Note:</b> SWIG-4.1.0 changed the way that function
|
|
annotations are generated. Prior versions required the (now removed) <tt>
|
|
-py3</tt> option to generate function annotation support containing
|
|
C/C++ types instead of supporting <tt>%feature("python:annotations",
|
|
"c")</tt>. Variable annotations were also added in SWIG-4.1.0.</p>
|
|
<h3><a name="Python_nn75">33.12.2 Buffer interface</a></h3>
|
|
<p> SWIG has a series of 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 2 and 3, since the <tt>bytearray</tt> type was
|
|
backported to 2.6.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <pybuffer.i>
|
|
%pybuffer_mutable_string(char *str);
|
|
void get_path(char *str);
|
|
</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> can 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">33.12.3 Abstract base classes</a></h3>
|
|
<p> By including <tt>pyabc.i</tt> in your interface file, the proxy
|
|
classes of the STL containers will automatically gain an appropriate
|
|
abstract base class from the <tt>collections.abc</tt> module for Python
|
|
3.3 and later, otherwise from the <tt>collections</tt> module. 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.abc.MutableMap</tt> for Python 3.3 and later, or <tt>
|
|
collections.MutableMap</tt> for earlier versions and a proxy class <tt>
|
|
IntList</tt> inheriting from <tt>collections.abc.MutableSequence</tt>
|
|
for Python 3.3 or later, or <tt>collections.MutableSequence</tt> for
|
|
earlier versions.</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.abc.MutableSet); # Python 3.3 and later
|
|
%pythonabc(MySet, collections.MutableSet); # Prior to Python 3.3
|
|
%pythonabc(MySet, "collections.abc.MutableSet if _swig_python_version_info >= (3, 3) else collections.MutableSet"); # All Python versions
|
|
</pre>
|
|
</div>
|
|
<p> For details of abstract base class, please see <a href="https://www.python.org/dev/peps/pep-3119/">
|
|
PEP 3119</a>.</p>
|
|
<p><b> Compatibility Note:</b> SWIG-4.0.0 changed the base classes to
|
|
use the <tt>collections.abc</tt> module instead of <tt>collections</tt>
|
|
due to the deprecation of the classes in the <tt>collections</tt>
|
|
module in Python 3.7. The <tt>collections.abc</tt> module was
|
|
introduced in Python 3.3 and hence this feature requires Python 3.3 or
|
|
later. SWIG-4.1.0 introduced the flexibility of using either the <tt>
|
|
collections.abc</tt> module for Python 3.3 and later or the <tt>
|
|
collections</tt> module for earlier Python versions.</p>
|
|
<h3><a name="Python_nn77">33.12.4 Byte string output conversion</a></h3>
|
|
<p> By default, any byte string (<tt>char*</tt> or <tt>std::string</tt>)
|
|
returned from C or C++ code is decoded to text as UTF-8. This decoding
|
|
uses the <tt>surrogateescape</tt> error handler under Python 3.1 or
|
|
higher -- this error handler decodes invalid byte sequences to high
|
|
surrogate characters in the range U+DC80 to U+DCFF. As an example,
|
|
consider the following SWIG interface, which exposes a byte string that
|
|
cannot be completely decoded as UTF-8:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
|
|
const char * non_utf8_c_str(void) {
|
|
return "h\xe9llo w\xc3\xb6rld";
|
|
}
|
|
|
|
void instring(const char *s) {
|
|
...
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> Note that "\xe9" is an invalid UTF-8 encoding, but "\xc3\xb6" is
|
|
valid. When this method is called from Python 3, the return value is
|
|
the following text string:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> s = example.non_utf8_c_str()
|
|
>>> s
|
|
'h\udce9llo wörld'
|
|
</pre>
|
|
</div>
|
|
<p> Since the C string contains bytes that cannot be decoded as UTF-8,
|
|
those raw bytes are represented as high surrogate characters that can
|
|
be used to obtain the original byte sequence:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> b = s.encode('utf-8', errors='surrogateescape')
|
|
>>> b
|
|
b'h\xe9llo w\xc3\xb6rld'
|
|
</pre>
|
|
</div>
|
|
<p> One can then attempt a different encoding, if desired (or simply
|
|
leave the byte string as a raw sequence of bytes for use in binary
|
|
protocols):</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> b.decode('latin-1')
|
|
'héllo wörld'
|
|
</pre>
|
|
</div>
|
|
<p> Note, however, that text strings containing surrogate characters are
|
|
rejected with the default <tt>strict</tt> codec error handler. For
|
|
example:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> with open('test', 'w') as f:
|
|
... print(s, file=f)
|
|
...
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 2, in <module>
|
|
UnicodeEncodeError: 'utf-8' codec can't encode character '\udce9' in position 1: surrogates not allowed
|
|
</pre>
|
|
</div>
|
|
<p> This requires the user to check most strings returned by SWIG
|
|
bindings, but the alternative is for a non-UTF8 byte string to be
|
|
completely inaccessible in Python 3 code.</p>
|
|
<p> For more details about the <tt>surrogateescape</tt> error handler,
|
|
please see <a href="https://www.python.org/dev/peps/pep-0383/">PEP 383</a>
|
|
.</p>
|
|
<p> When Python 3 strings are passed to the C/C++ layer, they are
|
|
expected to be valid UTF8 Unicode strings too. For example, when the <tt>
|
|
instring</tt> method above is wrapped and called, any invalid UTF8
|
|
Unicode code strings will result in a TypeError because the attempted
|
|
conversion fails:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> example.instring('h\xe9llo')
|
|
>>> example.instring('h\udce9llo')
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in <module>
|
|
TypeError: in method 'instring', argument 1 of type 'char const *'
|
|
</pre>
|
|
</div>
|
|
<p> In some cases, users may wish to instead handle all byte strings as
|
|
bytes objects in Python 3. This can be accomplished by adding <tt>
|
|
SWIG_PYTHON_STRICT_BYTE_CHAR</tt> to the generated code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module char_to_bytes
|
|
%begin %{
|
|
#define SWIG_PYTHON_STRICT_BYTE_CHAR
|
|
%}
|
|
|
|
char *charstring(char *s) {
|
|
return s;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> This will modify the behavior so that only Python 3 bytes objects
|
|
will be accepted and converted to a C/C++ string, and any string
|
|
returned from C/C++ will be converted to a bytes object in Python 3:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> from char_to_bytes import *
|
|
>>> charstring(b"hi") # Byte string
|
|
b'hi'
|
|
>>> charstring("hi") # Unicode string
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
TypeError: in method 'charstring', argument 1 of type 'char *'
|
|
</pre>
|
|
</div>
|
|
<p> Note that in Python 2, defining <tt>SWIG_PYTHON_STRICT_BYTE_CHAR</tt>
|
|
has no effect, since strings in Python 2 are equivalent to Python 3
|
|
bytes objects. However, there is a similar capability to force
|
|
unicode-only handling for wide characters C/C++ strings (<tt>wchar_t *</tt>
|
|
or <tt>std::wstring</tt> types) in Python 2. By default, in Python 2
|
|
both strings and unicode strings are converted to C/C++ wide strings,
|
|
and returned wide strings are converted to a Python unicode string. To
|
|
instead only convert unicode strings to wide strings, users can add <tt>
|
|
SWIG_PYTHON_STRICT_UNICODE_WCHAR</tt> to the generated code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module wchar_to_unicode
|
|
%begin %{
|
|
#define SWIG_PYTHON_STRICT_UNICODE_WCHAR
|
|
%}
|
|
|
|
wchar_t *wcharstring(wchar_t *s) {
|
|
return s;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> This ensures that only unicode strings are accepted by wcharstring
|
|
in both Python 2 and Python 3:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> from wchar_to_unicode import *
|
|
>>> wcharstring(u"hi") # Unicode string
|
|
u'hi'
|
|
>>> wcharstring(b"hi") # Byte string
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
TypeError: in method 'charstring', argument 1 of type 'wchar_t *'
|
|
</pre>
|
|
</div>
|
|
<p> By defining both <tt>SWIG_PYTHON_STRICT_BYTE_CHAR</tt> and <tt>
|
|
SWIG_PYTHON_STRICT_UNICODE_WCHAR</tt>, Python wrapper code can support
|
|
overloads taking both std::string (as Python bytes) and std::wstring
|
|
(as Python unicode).</p>
|
|
<h3><a name="Python_2_unicode">33.12.5 Python 2 Unicode</a></h3>
|
|
<p> A Python 3 string is a Unicode string so by default a Python 3
|
|
string that contains Unicode characters passed to C/C++ will be
|
|
accepted and converted to a C/C++ string (<tt>char *</tt> or <tt>
|
|
std::string</tt> types). A Python 2 string is not a unicode string by
|
|
default and should a Unicode string be passed to C/C++ it will fail to
|
|
convert to a C/C++ string (<tt>char *</tt> or <tt>std::string</tt>
|
|
types). The Python 2 behavior can be made more like Python 3 by
|
|
defining <tt>SWIG_PYTHON_2_UNICODE</tt> when compiling the generated
|
|
C/C++ code. By default when the following is wrapped:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module unicode_strings
|
|
char *charstring(char *s) {
|
|
return s;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> An error will occur when using Unicode strings in Python 2:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> from unicode_strings import *
|
|
>>> charstring("hi")
|
|
'hi'
|
|
>>> charstring(u"hi")
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
TypeError: in method 'charstring', argument 1 of type 'char *'
|
|
</pre>
|
|
</div>
|
|
<p> When the <tt>SWIG_PYTHON_2_UNICODE</tt> macro is added to the
|
|
generated code:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module unicode_strings
|
|
%begin %{
|
|
#define SWIG_PYTHON_2_UNICODE
|
|
%}
|
|
|
|
char *charstring(char *s) {
|
|
return s;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Unicode strings will be successfully accepted and converted from
|
|
UTF-8, but note that they are returned as a normal Python 2 string:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> from unicode_strings import *
|
|
>>> charstring("hi")
|
|
'hi'
|
|
>>> charstring(u"hi")
|
|
'hi'
|
|
>>>
|
|
</pre>
|
|
</div>
|
|
<p> Note that defining both <tt>SWIG_PYTHON_2_UNICODE</tt> and <tt>
|
|
SWIG_PYTHON_STRICT_BYTE_CHAR</tt> at the same time is not allowed, since
|
|
the first is allowing unicode conversion and the second is explicitly
|
|
prohibiting it.</p>
|
|
<h2><a name="Python_multithreaded">33.13 Support for Multithreaded
|
|
Applications</a></h2>
|
|
<p>By default, SWIG does not enable support for multithreaded Python
|
|
applications. More specifically, the Python wrappers generated by SWIG
|
|
will not release the Python's interpreter's Global Interpreter Lock
|
|
(GIL) when wrapped C/C++ code is entered. Hence, while any of the
|
|
wrapped C/C++ code is executing, the Python interpreter will not be
|
|
able to run any other threads, even if the wrapped C/C++ code is
|
|
waiting in a blocking call for something like network or disk IO.
|
|
Fortunately, SWIG does have the ability to enable multithreaded support
|
|
and automatic release of the GIL either for all wrapped code in a
|
|
module or on a more selective basis. The user interface for this is
|
|
described in the next section.</p>
|
|
<h3><a name="Python_thread_UI">33.13.1 UI for Enabling Multithreading
|
|
Support</a></h3>
|
|
<p>The user interface is as follows:</p>
|
|
<ol>
|
|
<li>
|
|
<p>Module thread support can be enabled in two ways:</p>
|
|
<ul>
|
|
<li>
|
|
<p> The <tt>-threads</tt> SWIG Python option at the command line (or in <tt>
|
|
setup.py</tt>):</p>
|
|
<div class="shell">
|
|
<pre>$ swig -python -threads example.i</pre>
|
|
</div></li>
|
|
<li>
|
|
<p> The <tt>threads</tt> module option in the *.i template file:</p>
|
|
<div class="code">
|
|
<pre>%module(threads="1")</pre>
|
|
</div></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>You can disable thread support for a given method:</p>
|
|
<div class="code">
|
|
<pre>%feature("nothread") method;</pre>
|
|
</div> or<div class="code">
|
|
<pre>%nothread method;</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>You can partially disable thread support for a given method:</p>
|
|
<ul>
|
|
<li>
|
|
<p>To disable the C++/Python thread protection:</p>
|
|
<div class="code">
|
|
<pre>%feature("nothreadblock") method;</pre>
|
|
</div> or<div class="code">
|
|
<pre>%nothreadblock method;</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>To disable the Python/C++ thread protection</p>
|
|
<div class="code">
|
|
<pre>%feature("nothreadallow") method;</pre>
|
|
</div> or<div class="code">
|
|
<pre>%nothreadallow method;</pre>
|
|
</div></li>
|
|
</ul>
|
|
</li>
|
|
</ol>
|
|
<h3><a name="Python_thread_performance">33.13.2 Multithread Performance</a>
|
|
</h3>
|
|
<p> For the curious about performance, here are some numbers for the
|
|
profiletest.i test, which is used to check the speed of the wrapped
|
|
code:</p>
|
|
<table summary="Python multithread performance">
|
|
<tr><th>Thread Mode</th><th>Execution Time (sec)</th><th>Comment</th></tr>
|
|
<tr><td>Single Threaded</td><td>9.6</td><td>no "-threads" option given</td>
|
|
</tr>
|
|
<tr><td>Fully Multithreaded</td><td>15.5</td><td>"-threads" option =
|
|
'allow' + 'block'</td></tr>
|
|
<tr><td>No Thread block</td><td>12.2</td><td>only 'allow'</td></tr>
|
|
<tr><td>No Thread Allow</td><td>13.6</td><td>only block'</td></tr>
|
|
</table>
|
|
<p> Fully threaded code decreases the wrapping performance by around
|
|
60%. If that is important to your application, you can tune each method
|
|
using the different 'nothread', 'nothreadblock' or 'nothreadallow'
|
|
features as needed. Note that for some methods deactivating the 'thread
|
|
block' or 'thread allow' code is not an option, so, be careful.</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="R">34 SWIG and R</a></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>
|
|
<ul>
|
|
<li><a href="#R_class_examples">Examples</a></li>
|
|
</ul>
|
|
</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="https://www.r-project.org/">
|
|
www.r-project.org</a>.</p>
|
|
<p> 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. They are also used to create the SimpleITK R package, which
|
|
runs on Linux and MacOS. SWIG is used to create all wrapper interfaces
|
|
to <a href="https://www.simpleitk.org/">SimpleITK</a>. The R bindings
|
|
also work on Microsoft Windows using Visual C++.</p>
|
|
<h2><a name="R_nn2">34.1 Bugs</a></h2>
|
|
<p> Currently the following features are not implemented or broken:</p>
|
|
<ul>
|
|
<li>Garbage collection of some created objects. Finalizers are available
|
|
for wrapped C++ classes and are called by the garbage collection
|
|
system.</li>
|
|
<li>C Array wrappings</li>
|
|
</ul>
|
|
<h2><a name="R_nn3">34.2 Using R and SWIG</a></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
|
|
R CMD SHLIB example_wrap.c example.c
|
|
</pre>
|
|
</div>
|
|
<p> The corresponding options for C++ mode are</p>
|
|
<div class="shell">
|
|
<pre>
|
|
swig -c++ -r -o example_wrap.cpp example.i
|
|
R CMD SHLIB example_wrap.cpp example.cpp
|
|
</pre>
|
|
</div>
|
|
<p> Note that R is sensitive to the names of the files. The name of the
|
|
wrapper file must be the name of the library unless you use the -o
|
|
option to R when building the library, for example:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
swig -c++ -r -o example_wrap.cpp example.i
|
|
R CMD SHLIB -o example.so example_wrap.cpp example.cpp
|
|
</pre>
|
|
</div>
|
|
<p> R is also sensitive to the name of the file extension in C and C++
|
|
mode. In C++ mode, the file extension must be .cpp rather than .cxx for
|
|
the R compile command to recognize it. If your C++ code is in a file
|
|
using something other than a .cpp extension, then it may still work
|
|
using PKG_LIBS:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
swig -c++ -r -o example_wrap.cpp example.i
|
|
PKG_LIBS="example.cxx" R CMD SHLIB -o example example_wrap.cpp
|
|
</pre>
|
|
</div>
|
|
<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>
|
|
<p> The cacheMetaData(1) will cause R to refresh its object tables.
|
|
Without it, inheritance of wrapped objects may fail. These two files
|
|
can be loaded in any order.</p>
|
|
<p> If you are compiling code yourself (not using R itself), there are a
|
|
few things to watch out for:</p>
|
|
<ul>
|
|
<li>The output shared library name (to the left of the file extension)
|
|
MUST match the module name, or alternatively, you can also set the
|
|
-package NAME command line argument. See swig -r -help for more
|
|
information</li>
|
|
<li>If you do not set the output file name appropriately, you might see
|
|
errors like<div class="shell">
|
|
<pre>
|
|
> fact(4)
|
|
Error in .Call("R_swig_fact", s_arg1, as.logical(.copy), PACKAGE = "example") :
|
|
"R_swig_fact" not available for .Call() for package "example"
|
|
</pre>
|
|
</div></li>
|
|
<li>Make sure the architecture of the shared library(x64 for instance),
|
|
matches the architecture of the R program you want to load your shared
|
|
library into</li>
|
|
</ul>
|
|
<h2><a name="R_nn4">34.3 Precompiling large R files</a></h2>
|
|
<p> 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</p>
|
|
<div class="code">
|
|
<pre>
|
|
source('BigFile.R')
|
|
save(list=ls(all=TRUE), file="BigFile.RData", compress=TRUE)
|
|
q(save="no")
|
|
</pre>
|
|
</div>
|
|
<p> This will generate a compiled R file called BigFile.RData that will
|
|
save a large amount of loading time.</p>
|
|
<p> There is no need to precompile large R files if the SWIG-generated
|
|
code is being included in an R package. The package infrastructure
|
|
provides this service during package installation.</p>
|
|
<h2><a name="R_nn5">34.4 General policy</a></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">34.5 Language conventions</a></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>
|
|
<h2><a name="R_nn6">34.6 C++ classes</a></h2>
|
|
<p> Wrapping of C++ classes for R works quite well. R has a special
|
|
type, known as an external reference, that can be used as a pointer to
|
|
arbitrary things, including C++ classes. The proxy layers generated for
|
|
other classes are not required.</p>
|
|
<p> SWIG currently creates a custom hierarchy of R classes derived from
|
|
the external reference type and implements type checking and function
|
|
overloading in the R code it generates. In the future we hope to
|
|
utilise the built in R6 class structures.</p>
|
|
<p> The R interface has the following capabilities:</p>
|
|
<ul>
|
|
<li> Destructor methods are registered and called automatically by the R
|
|
garbage collector.</li>
|
|
<li> A range of std::vector types are converted automatically to R
|
|
equivalents via the std_vector.i library.</li>
|
|
<li> The $ operator is used for method access.</li>
|
|
<li> Variable accessors are automatically generated and called via the
|
|
$, [, [[, $<-, [<-, [[<- operators.</li>
|
|
</ul>
|
|
<h3><a name="R_class_examples">34.6.1 Examples</a></h3>
|
|
<p> Consider the following simple example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
class Vehicle {
|
|
private:
|
|
int m_axles;
|
|
|
|
public:
|
|
int Axles() {
|
|
return(m_axles);
|
|
}
|
|
|
|
bool Available;
|
|
|
|
Vehicle() {
|
|
Available=false;
|
|
m_axles=2;
|
|
}
|
|
|
|
Vehicle(int ax) {
|
|
Available=false;
|
|
m_axles=ax;
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> The following options are available in R:</p>
|
|
<div class="code">
|
|
<pre>
|
|
v1 <- Vehicle()
|
|
v2 <- Vehicle(4)
|
|
# access members
|
|
v1$Axles()
|
|
[1] 2
|
|
v2$Axles
|
|
[1] 4
|
|
v1$Available
|
|
[1] FALSE
|
|
# Set availability
|
|
v1$Available <- TRUE
|
|
v1$Available
|
|
[1] TRUE
|
|
</pre>
|
|
</div>
|
|
<p> A useful trick to determine the methods that are available is to
|
|
query the R method definition as follows:</p>
|
|
<div class="code">
|
|
<pre>
|
|
# display the methods for the class
|
|
getMethod("$", class(v1))
|
|
|
|
Method Definition:
|
|
|
|
function (x, name)
|
|
{
|
|
accessorFuns = list(Axles = Vehicle_Axles, Available = Vehicle_Available_get)
|
|
vaccessors = c("Available")
|
|
idx = pmatch(name, names(accessorFuns))
|
|
if (is.na(idx))
|
|
return(callNextMethod(x, name))
|
|
f = accessorFuns[[idx]]
|
|
if (is.na(match(name, vaccessors)))
|
|
function(...) {
|
|
f(x, ...)
|
|
}
|
|
else f(x)
|
|
}
|
|
|
|
Signatures:
|
|
x
|
|
target "_p_Vehicle"
|
|
defined "_p_Vehicle"
|
|
|
|
</pre>
|
|
</div>
|
|
<p> The names in the <tt>accessorFuns</tt> list correspond to class
|
|
methods while names in the <tt>vaccessors</tt> section correspond to
|
|
variables that may be modified.</p>
|
|
<h2><a name="R_nn7">34.7 Enumerations</a></h2>
|
|
<p> R doesn't have a native enumeration type. Enumerations are
|
|
represented as character strings in R, with calls to R functions that
|
|
convert back and forth between integers.</p>
|
|
<p> The details of enumeration names and contents are stored in hidden R
|
|
environments, which are named according to the enumeration name - for
|
|
example, an enumeration colour:</p>
|
|
<div class="code">
|
|
<pre>
|
|
enum colour { red=-1, blue, green = 10 };
|
|
</pre>
|
|
</div>
|
|
<p> will be initialized by the following call in R:</p>
|
|
<div class="code">
|
|
<pre>
|
|
defineEnumeration("_colour",
|
|
.values=c("red" = .Call('R_swig_colour_red_get',FALSE, PACKAGE='enum_thorough'),
|
|
"blue" = .Call('R_swig_colour_blue_get',FALSE, PACKAGE='enum_thorough'),
|
|
"green" = .Call('R_swig_colour_green_get',FALSE, PACKAGE='enum_thorough')))
|
|
</pre>
|
|
</div>
|
|
<p> which will create an environment named <tt>.__E___colour</tt>. The
|
|
enumeration values are initialised via calls to C/C++ code, allowing
|
|
complex values for enumerations to be used. Calls to the C/C++ code
|
|
require the compiled library to be loaded, so a <tt>delayedAssign</tt>
|
|
is employed within <tt>defineEnumeration</tt> in order to allow the
|
|
code to be easily used in R packages.</p>
|
|
<p> The user typically does not need to access the enumeration lookup
|
|
functions or know the name of the enumeration type used by R.
|
|
Attributes containing the type information are attached by swig to
|
|
functions requiring enumeration arguments or returning enumeration
|
|
values, and those attributes are used to identify and access the
|
|
appropriate environments and thus translate between characters and
|
|
integers.</p>
|
|
<p> The relevant functions, for debugging purposes, are <tt>
|
|
enumToInteger</tt> and <tt>enumFromInteger</tt>.</p>
|
|
<p> Anonymous enumerations are ignored by the binding generation
|
|
process, leaving no way of accessing the value of anonymous
|
|
enumerations from R code.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Ruby">35 SWIG and Ruby</a></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="#Ruby_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>
|
|
<ul>
|
|
<li><a href="#Ruby_smart_pointers_shared_ptr">The shared_ptr Smart
|
|
Pointer</a></li>
|
|
<li><a href="#Ruby_smart_pointers_generic">Generic Smart Pointers</a></li>
|
|
</ul>
|
|
</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_operator_overloading">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">35.1 Preliminaries</a></h2>
|
|
<p> SWIG 4.2 is known to work with Ruby versions 2.0 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">35.1.1 Running SWIG</a></h3>
|
|
<p> To build a Ruby module, run SWIG using the <tt>-ruby</tt> option:</p>
|
|
<div class="code shell">
|
|
<pre>$ swig -ruby example.i
|
|
</pre>
|
|
</div>
|
|
<p> If building a C++ extension, add the <tt>-c++</tt> option:</p>
|
|
<div class="code shell">
|
|
<pre>$ swig -c++ -ruby example.i
|
|
</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">35.1.2 Getting the right header files</a></h3>
|
|
<p> In order to compile the wrapper code, the compiler needs the <tt>
|
|
ruby.h</tt> header file and its dependencies, notably <tt>ruby/config.h</tt>
|
|
which is found in a different, architecture-dependent, directory. The
|
|
best way to find the compiler options needed to compile the code is to
|
|
ask Ruby itself:</p>
|
|
<div class="code shell">
|
|
<pre>$ ruby -rrbconfig -e 'puts "-I#{RbConfig::CONFIG[%q{rubyhdrdir}]} -I#{RbConfig::CONFIG[%q{rubyarchhdrdir}]}"'
|
|
-I/usr/include/ruby-2.1.0 -I/usr/include/x86_64-linux-gnu/ruby-2.1.0
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn5">35.1.3 Compiling a dynamic module</a></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'
|
|
create_makefile('example')</pre>
|
|
</div></li>
|
|
<li>
|
|
<p>Type the following to build the extension:</p>
|
|
<div class="code shell">
|
|
<pre>
|
|
$ ruby extconf.rb
|
|
$ make
|
|
$ make install
|
|
</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|
|
|
puts <<EOM
|
|
# Your make rules go here
|
|
EOM
|
|
}
|
|
</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,
|
|
assuming you have code you need to link to in a file called <tt>
|
|
example.c</tt>, a typical sequence of commands for the Linux operating
|
|
system would look something like this:</p>
|
|
<div class="code shell">
|
|
<pre>$ swig -ruby example.i
|
|
$ gcc -O2 -fPIC -c example.c
|
|
$ gcc -O2 -fPIC -c example_wrap.c -I/usr/include/ruby-2.1.0
|
|
$ gcc -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> 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="https://github.com/swig/swig/wiki">
|
|
SWIG Wiki</a> for additional information.</p>
|
|
<h3><a name="Ruby_nn6">35.1.4 Using your module</a></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...
|
|
require 'etc'
|
|
|
|
# ... but the module name begins with an uppercase letter
|
|
puts "Your login name: #{Etc.getlogin}"
|
|
</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</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">35.1.5 Static linking</a></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">35.1.6 Compilation of C++ extensions</a></h3>
|
|
<p> On most machines, C++ extension modules should be linked using the
|
|
C++ compiler. For example:</p>
|
|
<div class="code shell">
|
|
<pre>
|
|
$ swig -c++ -ruby example.i
|
|
$ g++ -fPIC -c example.cxx
|
|
$ g++ -fPIC -c example_wrap.cxx -I/usr/include/ruby-2.1.0
|
|
$ g++ -shared example.o example_wrap.o -o example.so
|
|
</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'
|
|
$libs = append_library($libs, "supc++")
|
|
create_makefile('example')</pre>
|
|
</div>
|
|
<h2><a name="Ruby_nn9">35.2 Building Ruby Extensions under Windows 95/NT</a>
|
|
</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> ruby extconf.rb
|
|
C:\swigtest> nmake
|
|
C:\swigtest> nmake install
|
|
</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">35.2.1 Running SWIG from Developer Studio</a></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
|
|
require 'Example'
|
|
|
|
# Call a c function
|
|
print "Foo = ", Example.Foo, "\n"</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> ruby run.rb
|
|
Foo = 3.0
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Ruby_nn11">35.3 The Ruby-to-C/C++ Mapping</a></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">35.3.1 Modules</a></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
|
|
<tt>-prefix</tt> option on the SWIG command line. The prefix that you
|
|
specify with this option will be prepended to the module name specified
|
|
with the <tt>%module</tt> directive in your SWIG interface file. So for
|
|
example, this declaration at the top of your SWIG interface file:</p>
|
|
<div class="code">
|
|
<pre>%module "foo::bar::spam"</pre>
|
|
</div>
|
|
<p> will result in a nested module name of <tt>Foo::Bar::Spam</tt>, but
|
|
you can achieve the <span style="font-style: italic;">same</span>
|
|
effect by specifying:</p>
|
|
<div class="code">
|
|
<pre>%module spam</pre>
|
|
</div>
|
|
<p> and then running SWIG with the <tt>-prefix</tt> command line option:</p>
|
|
<div class="code shell">
|
|
<pre>
|
|
$ swig -ruby -prefix "foo::bar::" example.i
|
|
</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>
|
|
$ swig -ruby -globalmodule example.i
|
|
</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">35.3.2 Functions</a></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
|
|
|
|
int fact(int n);</pre>
|
|
</div>
|
|
<p> and C source file <tt>example.c</tt>:</p>
|
|
<div class="code">
|
|
<pre>int fact(int n) {
|
|
if (n == 0)
|
|
return 1;
|
|
return (n * fact(n-1));
|
|
}</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>
|
|
irb(main):001:0> <b>require 'example'</b>
|
|
true
|
|
irb(main):002:0> <b>Example.fact(4)</b>
|
|
24</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn14">35.3.3 Variable Linking</a></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
|
|
%module example
|
|
...
|
|
%inline %{
|
|
extern int variable1;
|
|
extern double Variable2;
|
|
%}
|
|
...</pre>
|
|
</div>
|
|
<p> Now look at the Ruby interface:</p>
|
|
<div class="code targetlang">
|
|
<pre>$ <b>irb</b>
|
|
irb(main):001:0> <b>require 'Example'</b>
|
|
true
|
|
irb(main):002:0> <b>Example.variable1 = 2</b>
|
|
2
|
|
irb(main):003:0> <b>Example.Variable2 = 4 * 10.3</b>
|
|
41.2
|
|
irb(main):004:0> <b>Example.Variable2</b>
|
|
41.2</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>
|
|
TypeError: no implicit conversion to float from string
|
|
from (irb):5:in `Variable2='
|
|
from (irb):5</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;
|
|
%inline %{
|
|
extern char *path;
|
|
%}
|
|
%mutable;</pre>
|
|
</div>
|
|
<p> The <tt>%immutable</tt> directive stays in effect until it is
|
|
explicitly disabled using <tt>%mutable</tt>.</p>
|
|
<p>Note: When SWIG is invoked with the <tt>-globalmodule</tt> option in
|
|
effect, the C/C++ global variables will be translated into Ruby global
|
|
variables. Type-checking and the optional read-only characteristic are
|
|
available in the same way as described above. However the example would
|
|
then have to be modified and executed in the following way:<div class="code targetlang">
|
|
<pre>$ <b>irb</b>
|
|
irb(main):001:0> <b>require 'Example'</b>
|
|
true
|
|
irb(main):002:0> <b>$variable1 = 2</b>
|
|
2
|
|
irb(main):003:0> <b>$Variable2 = 4 * 10.3</b>
|
|
41.2
|
|
irb(main):004:0> <b>$Variable2</b>
|
|
41.2</pre>
|
|
</div></p>
|
|
<h3><a name="Ruby_nn15">35.3.4 Constants</a></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
|
|
#define VERSION "1.0"
|
|
|
|
%constant int FOO = 42;
|
|
%constant const char *path = "/usr/local";
|
|
|
|
const int BAR = 32;</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>
|
|
irb(main):001:0> <b>require 'Example'</b>
|
|
true
|
|
irb(main):002:0> <b>Example::PI</b>
|
|
3.14159</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn16">35.3.5 Pointers</a></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();
|
|
void set_foo(Foo *foo);</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>
|
|
#<SWIG::TYPE_p_Foo:0x402b1654></pre>
|
|
</div>
|
|
<p> A <tt>NULL</tt> pointer is always represented by the Ruby <tt>nil</tt>
|
|
object.</p>
|
|
<h3><a name="Ruby_nn17">35.3.6 Structures</a></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 {
|
|
double x, y;
|
|
};</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>
|
|
irb(main):001:0> <b>require 'Example'</b>
|
|
true
|
|
irb(main):002:0> <b>f = Example::Vector.new</b>
|
|
#<Example::Vector:0x4020b268>
|
|
irb(main):003:0> <b>f.x = 10</b>
|
|
nil
|
|
irb(main):004:0> <b>f.x</b>
|
|
10.0</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 {
|
|
...
|
|
%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 <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 {
|
|
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 in the <a href="#Ruby_memberin_typemap">
|
|
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 {
|
|
...
|
|
};
|
|
|
|
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="Ruby_nn18">35.3.7 C++ classes</a></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 {
|
|
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> 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'
|
|
|
|
l = Example::List.new
|
|
|
|
l.insert("Ale")
|
|
l.insert("Stout")
|
|
l.insert("Lager")
|
|
Example.print(l)
|
|
l.length()
|
|
----- produces the following output
|
|
Lager
|
|
Stout
|
|
Ale
|
|
3</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn19">35.3.8 C++ Inheritance</a></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 {
|
|
...
|
|
};
|
|
|
|
class Child : public Parent {
|
|
...
|
|
};</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>
|
|
#<Bar:0x4016efd4>
|
|
irb(main):002:0> <b>c.instance_of? Child</b>
|
|
true
|
|
irb(main):003:0> <b>b.instance_of? Parent</b>
|
|
false
|
|
irb(main):004:0> <b>b.is_a? Child</b>
|
|
true
|
|
irb(main):005:0> <b>b.is_a? Parent</b>
|
|
true
|
|
irb(main):006:0> <b>Child < Parent</b>
|
|
true
|
|
irb(main):007:0> <b>Child > Parent</b>
|
|
false</pre>
|
|
</div>
|
|
<p> Furthermore, if you have a function like this:</p>
|
|
<div class="code">
|
|
<pre>void spam(Parent *f);</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
|
|
{
|
|
...
|
|
};</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.
|
|
Multiple inheritance is not supported in Ruby.</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>
|
|
$ swig -c++ -ruby -minherit example.i
|
|
</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
|
|
{
|
|
...
|
|
};</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
|
|
module Impl
|
|
# Define Base1 methods here
|
|
end
|
|
include Impl
|
|
end
|
|
|
|
class Base2
|
|
module Impl
|
|
# Define Base2 methods here
|
|
end
|
|
include Impl
|
|
end
|
|
|
|
class Derived
|
|
module Impl
|
|
include Base1::Impl
|
|
include Base2::Impl
|
|
# Define Derived methods here
|
|
end
|
|
include Impl
|
|
end</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
|
|
obj.is_a? Base1 # this will return false...
|
|
obj.is_a? Base2 # ... and so will this</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">35.3.9 C++ Overloaded Functions</a></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 Ruby in a straightforward manner:</p>
|
|
<div class="code targetlang">
|
|
<pre>irb(main):001:0> <b>foo(3)</b> # foo(int)
|
|
irb(main):002:0> <b>foo("Hello")</b> # 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 Ruby code like this:</p>
|
|
<div class="code targetlang">
|
|
<pre>irb(main):001:0> <b>f = Foo.new</b> # Create a Foo
|
|
irb(main):002:0> <b>g = Foo.new(f)</b> # 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 shell">
|
|
<pre>
|
|
example.i:12: Warning 509: Overloaded method spam(short) effectively ignored,
|
|
example.i:11: Warning 509: as it is shadowed by spam(int).
|
|
</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 <a href="#SWIGPlus">"SWIG and C++"</a> chapter
|
|
for more information about overloading.</p>
|
|
<h3><a name="Ruby_nn21">35.3.10 C++ Operators</a></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 {
|
|
...
|
|
Complex operator+(Complex &);
|
|
...
|
|
};</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 &);
|
|
...
|
|
Complex operator+(Complex &, Complex &);</pre>
|
|
</div>
|
|
<p>Now, in Ruby, you can do this:</p>
|
|
<div class="code targetlang">
|
|
<pre>a = Example::Complex.new(2, 3)
|
|
b = Example::Complex.new(4, -1)
|
|
c = Example.add_complex(a, b)</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">35.3.11 C++ namespaces</a></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 Ruby as follows:</p>
|
|
<div class="code targetlang">
|
|
<pre>irb(main):001:0> <b>require 'example'</b>
|
|
true
|
|
irb(main):002:0> <b>Example.fact(3)</b>
|
|
6
|
|
irb(main):003:0> <b>v = Example::Vector.new</b>
|
|
#<Example::Vector:0x4016f4d4>
|
|
irb(main):004:0> <b>v.x = 3.4</b>
|
|
3.4
|
|
irb(main):004:0> <b>v.y</b>
|
|
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="Ruby_nn23">35.3.12 C++ templates</a></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 Ruby:</p>
|
|
<div class="code targetlang">
|
|
<pre>irb(main):001:0> <b>require 'example'</b>
|
|
true
|
|
irb(main):002:0> <b>p = Example::Pairii.new(3, 4)</b>
|
|
#<Example:Pairii:0x4016f4df>
|
|
irb(main):003:0> <b>p.first</b>
|
|
3
|
|
irb(main):004:0> <b>p.second</b>
|
|
4</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn23_1">35.3.13 C++ Standard Template Library (STL)</a>
|
|
</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
|
|
|
|
float sum(const std::vector<float>& values);</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
|
|
|
|
%include std_vector.i
|
|
float sum(const std::vector<float>& values);</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
|
|
v << 2
|
|
v << 3
|
|
v << 4
|
|
v.each { |x| puts x }
|
|
|
|
=> 2
|
|
3
|
|
4
|
|
v.delete_if { |x| x == 3 }
|
|
=> [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">
|
|
<pre>
|
|
%module nativevector
|
|
|
|
%{
|
|
std::vector< swig::GC_VALUE > NativeVector;
|
|
%}
|
|
|
|
%template(NativeVector) std::vector< swig::GC_VALUE >;
|
|
</pre>
|
|
</div>
|
|
<p>This vector can then contain any Ruby object, making them almost
|
|
identical to Ruby's own Array class.</p>
|
|
<div class="targetlang">
|
|
<pre>require 'nativevector'
|
|
include NativeVector
|
|
|
|
v = NativeVector.new
|
|
v << 1
|
|
v << [1, 2]
|
|
v << 'hello'
|
|
|
|
class A; end
|
|
|
|
v << A.new
|
|
|
|
puts v
|
|
=> [1, [1, 2], 'hello', #<A:0x245325>]
|
|
</pre>
|
|
</div>
|
|
<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="Ruby_C_STL_Functors">35.3.14 C++ STL Functors</a></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 <tt>operator()</tt> 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 <tt>std::set</tt>, <tt>set::map</tt>, <tt>std::multiset</tt>
|
|
and <tt>std::multimap</tt>.</p>
|
|
<p>The functors in swig are called <tt>swig::UnaryFunction</tt> and <tt>
|
|
swig::BinaryFunction</tt>. For C++ predicates (ie. functors that must
|
|
return bool as a result) <tt>swig::UnaryPredicate</tt> and <tt>
|
|
swig::BinaryPredicate</tt> are provided.</p>
|
|
<p>As an example, if given this swig file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module intset;
|
|
|
|
%include <std_set.i>
|
|
|
|
%template(IntSet) std::set< int, swig::BinaryPredicate >;
|
|
</pre>
|
|
</div>
|
|
<p>You can then use the set from Ruby with or without a proc object as a
|
|
predicate:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
require 'intset'
|
|
include Intset
|
|
|
|
# Default sorting behavior defined in C++
|
|
a = IntSet.new
|
|
a << 1
|
|
a << 2
|
|
a << 3
|
|
a
|
|
<b>=> [1, 2, 3]</b>
|
|
|
|
# Custom sorting behavior defined by a Ruby proc
|
|
b = IntSet.new( proc { |a, b| a > b } )
|
|
b << 1
|
|
b << 2
|
|
b << 3
|
|
b
|
|
<b>=> [3, 2, 1]</b>
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Ruby_C_Iterators">35.3.15 C++ STL Iterators</a></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 <tt>swig::Iterator</tt> or <tt>
|
|
swig::ConstIterator</tt>. 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 <tt>make_const_iterator</tt>
|
|
and <tt>make_nonconst_iterator</tt> are provided.</p>
|
|
<p>These can be used either like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
make_const_iterator( iterator, rubyclass );
|
|
make_const_iterator( iterator, iterator_begin, iterator_end, rubyclass );
|
|
</pre>
|
|
</div>
|
|
<p>The iterators support a <tt>next()</tt> and <tt>previous()</tt>
|
|
member function to just change the iterator without returning anything.
|
|
<tt>previous()</tt> should obviously only be used for bidirectional
|
|
iterators. You can also advance the iterator multiple steps by using
|
|
standard math operations like <tt>+=</tt>.</p>
|
|
<p>The value the iterator points at can be accessed with <tt>value()</tt>
|
|
-- this is equivalent to dereferencing it with <tt>*i</tt>. For
|
|
non-const iterators, a <tt>value=()</tt> 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 <tt>
|
|
*i = something</tt>.</p>
|
|
<p>Thus, given say a vector class of doubles defined as:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module doublevector
|
|
|
|
%include std_vector.i
|
|
|
|
%template(DoubleVector) std::vector<double>;
|
|
</pre>
|
|
</div>
|
|
<p>Its iterator can then be used from Ruby like:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
require 'doublevector'
|
|
include Doublevector
|
|
|
|
v = DoubleVector.new
|
|
v << 1
|
|
v << 2
|
|
v << 3
|
|
|
|
#
|
|
# an elaborate and less efficient way of doing v.map! { |x| x+2 }
|
|
#
|
|
i = v.begin
|
|
e = v.end
|
|
while i != e
|
|
val = i.value
|
|
val += 2
|
|
i.value = val
|
|
i.next
|
|
end
|
|
i
|
|
<b>>> [3, 4, 5 ]</b>
|
|
</pre>
|
|
</div>
|
|
<p>If you'd rather have STL classes without any iterators, you should
|
|
define <tt>-DSWIG_NO_EXPORT_ITERATOR_METHODS</tt> when running swig.</p>
|
|
<h3><a name="Ruby_nn24">35.3.16 C++ Smart Pointers</a></h3>
|
|
<h4><a name="Ruby_smart_pointers_shared_ptr">35.3.16.1 The shared_ptr
|
|
Smart Pointer</a></h4>
|
|
<p> The C++11 standard provides <tt>std::shared_ptr</tt> which was
|
|
derived from the Boost implementation, <tt>boost::shared_ptr</tt>. Both
|
|
of these are available for Ruby in the SWIG library and usage is
|
|
outlined in the <a href="#Library_std_shared_ptr">shared_ptr smart
|
|
pointer</a> library section.</p>
|
|
<h4><a name="Ruby_smart_pointers_generic">35.3.16.2 Generic Smart
|
|
Pointers</a></h4>
|
|
<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 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
|
|
...
|
|
%template(SmartPtrFoo) SmartPtr<Foo>;
|
|
...</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
|
|
#<Example::SmartPtrFoo:0x4016f4df>
|
|
irb(main):002:0> <b>p.x = 3</b> # Foo::x
|
|
3
|
|
irb(main):003:0> <b>p.bar()</b> # 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 targetlang">
|
|
<pre>irb(main):004:0> <b>f = p.__deref__()</b> # Returns underlying Foo *</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn25">35.3.17 Cross-Language Polymorphism</a></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="#Python">
|
|
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">35.3.17.1 Exception Unrolling</a></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") {
|
|
throw Swig::DirectorMethodException($error);
|
|
}</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">35.4 Naming</a></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>$ swig -ruby -autorename example.i
|
|
</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">35.4.1 Defining Aliases</a></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 {
|
|
public:
|
|
// Construct an empty array
|
|
MyArray();
|
|
|
|
// Return the size of this array
|
|
size_t length() const;
|
|
};
|
|
|
|
%extend MyArray {
|
|
// MyArray#size is an alias for MyArray#length
|
|
size_t size() const {
|
|
return $self->length();
|
|
}
|
|
}
|
|
</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
|
|
%alias MyArray::length "size";
|
|
|
|
class MyArray {
|
|
public:
|
|
// Construct an empty array
|
|
MyArray();
|
|
|
|
// Return the size of this array
|
|
size_t length() const;
|
|
};</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">35.4.2 Predicate Methods</a></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();
|
|
|
|
%typemap(out) int is_it_safe "$result = ($1 != 0) ? Qtrue : Qfalse;"
|
|
|
|
int is_it_safe();</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();
|
|
|
|
int is_it_safe();</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>
|
|
true</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">35.4.3 Bang Methods</a></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(int arr[]);
|
|
|
|
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">35.4.4 Getters and Setters</a></h3>
|
|
<p> Often times a C++ library will expose properties through getter and
|
|
setter methods. For example:</p>
|
|
<div class="code">
|
|
<pre>class Foo {
|
|
Foo() {}
|
|
int getValue() { return value_; }
|
|
void setValue(int value) { value_ = value; }
|
|
|
|
private:
|
|
int value_;
|
|
};</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>
|
|
irb(main):002:0> <b>foo.value = 5</b>
|
|
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();
|
|
%rename("value=") Foo::setValue(int value);</pre>
|
|
</div>
|
|
<h2><a name="Ruby_nn32">35.5 Input and output parameters</a></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</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 Ruby, this allows you to pass simple values. For example:</p>
|
|
<div class="code targetlang">
|
|
<pre>a = Example.add(3, 4)
|
|
puts a
|
|
7
|
|
b = Example.sub(7, 4)
|
|
puts 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 Ruby, a mutated parameter shows up as a return value. For example:</p>
|
|
<div class="code targetlang">
|
|
<pre>a = Example.negate(3)
|
|
print 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, success code, and error_code */
|
|
int send_message(char *text, int *success, int *error_code);</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"
|
|
...
|
|
int send_message(char *, int *OUTPUT, int *OUTPUT);</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")
|
|
if not success
|
|
print "error #{error_code} : in send_message"
|
|
else
|
|
print "Sent", bytes
|
|
end</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
|
|
%include "typemaps.i"
|
|
%apply int *OUTPUT { int *rows, int *columns };
|
|
...
|
|
void get_dimensions(Matrix *m, int *rows, int*columns);</pre>
|
|
</div>
|
|
<p>In Ruby:</p>
|
|
<div class="code targetlang">
|
|
<pre>r, c = Example.get_dimensions(m)</pre>
|
|
</div>
|
|
<h2><a name="Ruby_nn33">35.6 Exception handling</a></h2>
|
|
<h3><a name="Ruby_nn34">35.6.1 Using the %exception directive</a></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 {
|
|
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 array item and perform bounds checking.
|
|
double getitem(int i) {
|
|
if ((i >= 0) && (i < n))
|
|
return ptr[i];
|
|
else
|
|
throw RangeError();
|
|
}
|
|
|
|
// Set an array item 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 Ruby
|
|
extension by writing the following in an interface file:</p>
|
|
<div class="code">
|
|
<pre>%exception {
|
|
try {
|
|
$action
|
|
}
|
|
catch (const RangeError&) {
|
|
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
|
|
rb_raise(cpperror, "Range error.");
|
|
}
|
|
}
|
|
|
|
class DoubleArray {
|
|
...
|
|
};</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 {
|
|
try {
|
|
$action
|
|
} catch (const RangeError&) {
|
|
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
|
|
rb_raise(cpperror, "Range error in getitem.");
|
|
}
|
|
}
|
|
|
|
%exception setitem {
|
|
try {
|
|
$action
|
|
} catch (const RangeError&) {
|
|
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
|
|
rb_raise(cpperror, "Range error in setitem.");
|
|
}
|
|
}</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">35.6.2 Handling Ruby Blocks</a></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:</p>
|
|
<div class="code">
|
|
<pre>class Window
|
|
{
|
|
public:
|
|
Window(int x, int y, int w, int h);
|
|
// .... other methods here ....
|
|
};
|
|
|
|
// Add support for yielding self in the Class' constructor.
|
|
%exception Window::Window {
|
|
$action
|
|
if (rb_block_given_p()) {
|
|
rb_yield(self);
|
|
}
|
|
}</pre>
|
|
</div>
|
|
<p> Then, in ruby, it can be used like:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Window.new(0, 0, 360, 480) { |w|
|
|
w.color = Fltk::RED
|
|
w.border = false
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p>For other methods, you can usually use a dummy parameter with a
|
|
special in typemap, like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
//
|
|
// original function was:
|
|
//
|
|
// void func(int x);
|
|
|
|
%typemap(in, numinputs=0) int RUBY_YIELD_SELF {
|
|
if ( !rb_block_given_p() )
|
|
rb_raise("No block given");
|
|
return rb_yield(self);
|
|
}
|
|
|
|
%extend {
|
|
void func(int x, int RUBY_YIELD_SELF );
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p>For more information on typemaps, see <a href="#Ruby_nn37">Typemaps</a>
|
|
.</p>
|
|
<h3><a name="Ruby_nn35">35.6.3 Raising exceptions</a></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>
|
|
<tr><td class="diagram"><div>SWIG_MemoryError</div></td><td><div>
|
|
rb_eNoMemError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_IOError</div></td><td><div>rb_eIOError</div>
|
|
</td></tr>
|
|
<tr><td class="diagram"><div>SWIG_RuntimeError</div></td><td><div>
|
|
rb_eRuntimeError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_IndexError</div></td><td><div>
|
|
rb_eIndexError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_TypeError</div></td><td><div>
|
|
rb_eTypeError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_DivisionByZero</div></td><td><div>
|
|
rb_eZeroDivError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_OverflowError</div></td><td><div>
|
|
rb_eRangeError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_SyntaxError</div></td><td><div>
|
|
rb_eSyntaxError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_ValueError</div></td><td><div>
|
|
rb_eArgError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_SystemError</div></td><td><div>
|
|
rb_eFatal</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_AttributeError</div></td><td><div>
|
|
rb_eRuntimeError</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_NullReferenceError</div></td><td><div>
|
|
rb_eNullReferenceError*</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_ObjectPreviouslyDeletedError</div></td><td>
|
|
<div>rb_eObjectPreviouslyDeleted*</div></td></tr>
|
|
<tr><td class="diagram"><div>SWIG_UnknownError</div></td><td><div>
|
|
rb_eRuntimeError</div></td></tr>
|
|
<tr class="diagram"><td colspan="2"><div>* These error classes are
|
|
created by SWIG and are not built-in Ruby exception classes</div></td></tr>
|
|
</tbody></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">
|
|
<pre>
|
|
%raise(SWIG_NewPointerObj(e, SWIGTYPE_p_AssertionFailedException, 0), ":AssertionFailedException", SWIGTYPE_p_AssertionFailedException);
|
|
</pre>
|
|
</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">35.6.4 Exception classes</a></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;
|
|
|
|
%inline %{
|
|
class CustomError { };
|
|
|
|
class Foo {
|
|
public:
|
|
void test() { throw CustomError; }
|
|
};
|
|
%}</pre>
|
|
</div>
|
|
<p>From Ruby you can now call this method like this:</p>
|
|
<div class="code targetlang">
|
|
<pre>foo = Foo.new
|
|
begin
|
|
foo.test()
|
|
rescue CustomError => e
|
|
puts "Caught custom error"
|
|
end </pre>
|
|
</div>
|
|
<p>For another example look at swig/Examples/ruby/exception_class.</p>
|
|
<h2><a name="Ruby_nn37">35.7 Typemaps</a></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">35.7.1 What is a typemap?</a></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">
|
|
<pre>
|
|
%typemap( method [, modifiers...] ) typelist code;
|
|
</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> (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, ... ] ;
|
|
|
|
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 C code used in the typemap. It can take
|
|
any one of the following forms:</p>
|
|
<div class="diagram">
|
|
<pre>code : { ... }
|
|
| " ... "
|
|
| %{ ... %}</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
|
|
|
|
%typemap(in) int {
|
|
$1 = (int) NUM2INT($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 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'
|
|
|
|
puts Example.fact(6)</pre>
|
|
</div>
|
|
<p>prints the result:</p>
|
|
<div class="code shell">
|
|
<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 n {
|
|
$1 = (int) NUM2INT($input);
|
|
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 {
|
|
$1 = (int) NUM2INT($input);
|
|
printf("n = %d\n", $1);
|
|
}
|
|
|
|
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 = StringValuePtr($input);
|
|
$2 = (int) RSTRING($input)->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 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')
|
|
2</pre>
|
|
</div>
|
|
<h3><a name="Ruby_Typemap_scope">35.7.2 Typemap scope</a></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="Ruby_Copying_a_typemap">35.7.3 Copying a typemap</a></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="Ruby_Deleting_a_typemap">35.7.4 Deleting a typemap</a></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="Ruby_Placement_of_typemaps">35.7.5 Placement of typemaps</a>
|
|
</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>
|
|
<h3><a name="Ruby_nn39">35.7.6 Ruby typemaps</a></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">35.7.6.1 "in" typemap</a></h4>
|
|
<p>Converts Ruby objects to input function arguments. For example:</p>
|
|
<div class="code">
|
|
<pre>%typemap(in) int {
|
|
$1 = NUM2INT($input);
|
|
}</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>
|
|
<tr><td>$input</td><td> Input object holding value to be converted.</td></tr>
|
|
<tr><td>$symname</td><td> Name of function/method being wrapped</td></tr>
|
|
<tr><td>$1...n</td><td> Argument being sent to the function</td></tr>
|
|
<tr><td>$1_name</td><td> Name of the argument (if provided)</td></tr>
|
|
<tr><td>$1_type</td><td> The actual C datatype matched by the typemap.</td>
|
|
</tr>
|
|
<tr><td>$1_ltype</td><td> The assignable version of the C datatype
|
|
matched by the typemap.</td></tr>
|
|
</tbody></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.
|
|
%typemap(in, numinputs=0) int *out (int temp) {
|
|
$1 = &temp;
|
|
}</pre>
|
|
</div>
|
|
<p> At this time, only zero or one arguments may be converted.</p>
|
|
<h4><a name="Ruby_typecheck_typemap">35.7.6.2 "typecheck" typemap</a></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 {
|
|
$1 = FIXNUM_P($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>
|
|
<h4><a name="Ruby_out_typemap">35.7.6.3 "out" typemap</a></h4>
|
|
<p>Converts return value of a C function to a Ruby object.</p>
|
|
<div class="code">
|
|
<pre>%typemap(out) int {
|
|
$result = INT2NUM( $1 );
|
|
}
|
|
</pre>
|
|
</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>
|
|
<tr><td>$result</td><td> Result object returned to target language.</td></tr>
|
|
<tr><td>$symname</td><td> Name of function/method being wrapped</td></tr>
|
|
<tr><td>$1...n</td><td> Argument being wrapped</td></tr>
|
|
<tr><td>$1_name</td><td> Name of the argument (if provided)</td></tr>
|
|
<tr><td>$1_type</td><td> The actual C datatype matched by the typemap.</td>
|
|
</tr>
|
|
<tr><td>$1_ltype</td><td> The assignable version of the C datatype
|
|
matched by the typemap.</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h4><a name="Ruby_arginit_typemap">35.7.6.4 "arginit" typemap</a></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
|
|
%typemap(arginit) int *data {
|
|
$1 = NULL;
|
|
}</pre>
|
|
</div>
|
|
<h4><a name="Ruby_default_typemap">35.7.6.5 "default" typemap</a></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 {
|
|
$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>
|
|
<h4><a name="Ruby_check_typemap">35.7.6.6 "check" typemap</a></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 {
|
|
if ($1 <= 0) {
|
|
SWIG_exception(SWIG_ValueError, "Expected positive value.");
|
|
}
|
|
}</pre>
|
|
</div>
|
|
<h4><a name="Ruby_argout_typemap_">35.7.6.7 "argout" typemap</a></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 */
|
|
%typemap(in, numinputs=0) int *out (int temp) {
|
|
$1 = &temp;
|
|
}
|
|
|
|
%typemap(argout) int *out {
|
|
// Append output value $1 to $result (assuming a single integer in this case)
|
|
$result = SWIG_AppendOutput( $result, INT2NUM(*$1) );
|
|
}</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>
|
|
<tr><td>$result</td><td> Result object returned to target language.</td></tr>
|
|
<tr><td>$input</td><td> The original input object passed.</td></tr>
|
|
<tr><td>$symname</td><td> Name of function/method being wrapped.</td></tr>
|
|
</tbody></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_">35.7.6.8 "freearg" typemap</a></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
|
|
%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>
|
|
<h4><a name="Ruby_newfree_typemap">35.7.6.9 "newfree" typemap</a></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 * {
|
|
delete $1;
|
|
}
|
|
%typemap(out) string * {
|
|
$result = PyString_FromString($1->c_str());
|
|
}
|
|
...
|
|
|
|
%newobject foo;
|
|
...
|
|
string *foo();</pre>
|
|
</div>
|
|
<p> See <a href="#Customization_ownership">Object ownership and
|
|
%newobject</a> for further details.</p>
|
|
<h4><a name="Ruby_memberin_typemap">35.7.6.10 "memberin" typemap</a></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] {
|
|
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>
|
|
<h4><a name="Ruby_varin_typemap">35.7.6.11 "varin" typemap</a></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_">35.7.6.12 "varout" typemap</a></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">35.7.6.13 "throws" typemap</a></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 * %{
|
|
rb_raise(rb_eRuntimeError, $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) {
|
|
rb_raise(rb_eRuntimeError, _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="#Customization_exception">
|
|
Exception handling with %exception</a> section.</p>
|
|
<h4><a name="Ruby_directorin_typemap">35.7.6.14 directorin typemap</a></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">
|
|
<pre>
|
|
%typemap(directorin) int {
|
|
$result = INT2NUM($1);
|
|
}
|
|
</pre>
|
|
</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>
|
|
<tr><td>$result</td><td> Result object returned to target language.</td></tr>
|
|
<tr><td>$symname</td><td> Name of function/method being wrapped</td></tr>
|
|
<tr><td>$1...n</td><td> Argument being wrapped</td></tr>
|
|
<tr><td>$1_name</td><td> Name of the argument (if provided)</td></tr>
|
|
<tr><td>$1_type</td><td> The actual C datatype matched by the typemap.</td>
|
|
</tr>
|
|
<tr><td>$1_ltype</td><td> The assignable version of the C datatype
|
|
matched by the typemap.</td></tr>
|
|
<tr><td>this</td><td> C++ this, referring to the class itself.</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h4><a name="Ruby_directorout_typemap">35.7.6.15 directorout typemap</a></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">
|
|
<pre>
|
|
%typemap(directorout) int {
|
|
$result = NUM2INT($1);
|
|
}
|
|
</pre>
|
|
</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>
|
|
<tr><td>$input</td><td>Ruby object being sent to the function</td></tr>
|
|
<tr><td>$symname</td><td>Name of function/method being wrapped</td></tr>
|
|
<tr><td>$1...n</td><td>Argument being sent to the function</td></tr>
|
|
<tr><td>$1_name</td><td> Name of the argument (if provided)</td></tr>
|
|
<tr><td>$1_type</td><td> The actual C datatype matched by the typemap.</td>
|
|
</tr>
|
|
<tr><td>$1_ltype</td><td> The assignable version of the C datatype
|
|
matched by the typemap.</td></tr>
|
|
<tr><td>this</td><td> C++ this, referring to the class itself.</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<p>Currently, the directorout nor the out typemap support the option <tt>
|
|
numoutputs</tt>, 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">
|
|
<pre>
|
|
%feature("numoutputs", "0") MyClass::function;
|
|
</pre>
|
|
</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.</p>
|
|
<h4><a name="Ruby_directorargout_typemap">35.7.6.16 directorargout
|
|
typemap</a></h4>
|
|
<p>Output argument processing in director member functions.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(directorargout) int {
|
|
$result = SWIG_AppendOutput( $result, NUM2INT($1) );
|
|
}
|
|
</pre>
|
|
</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>
|
|
<tr><td>$result</td><td>Result that the director function returns</td></tr>
|
|
<tr><td>$input</td><td>Ruby object being sent to the function</td></tr>
|
|
<tr><td>$symname</td><td>name of the function/method being wrapped</td></tr>
|
|
<tr><td>$1...n</td><td>Argument being sent to the function</td></tr>
|
|
<tr><td>$1_name</td><td>Name of the argument (if provided)</td></tr>
|
|
<tr><td>$1_type</td><td>The actual C datatype matched by the typemap</td>
|
|
</tr>
|
|
<tr><td>$1_ltype</td><td>The assignable version of the C datatype
|
|
matched by the typemap</td></tr>
|
|
<tr><td>this</td><td>C++ this, referring to the instance of the class
|
|
itself</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h4><a name="Ruby_ret_typemap">35.7.6.17 ret typemap</a></h4>
|
|
<p>Cleanup of function return values</p>
|
|
<h4><a name="Ruby_globalin_typemap">35.7.6.18 globalin typemap</a></h4>
|
|
<p>Setting of C global variables</p>
|
|
<h3><a name="Ruby_nn40">35.7.7 Typemap variables</a></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">35.7.8 Useful Functions</a></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<em> Programming Ruby</em>
|
|
book, 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">35.7.8.1 C Datatypes to Ruby Objects</a></h4>
|
|
<div class="diagram">
|
|
<table border="1" cellpadding="2" cellspacing="2" style="width: 100%;" summary="Datatypes">
|
|
<tbody>
|
|
<tr><th><b>RUBY</b></th><th><b>SWIG</b></th><td></td></tr>
|
|
<tr><td>INT2NUM(long or int)</td><td>SWIG_From_int(int x)</td><td> int
|
|
to Fixnum or Bignum</td></tr>
|
|
<tr><td>INT2FIX(long or int)</td><td></td><td> int to Fixnum (faster
|
|
than INT2NUM)</td></tr>
|
|
<tr><td>CHR2FIX(char)</td><td>SWIG_From_char(char x)</td><td> char to
|
|
Fixnum</td></tr>
|
|
<tr><td>rb_str_new2(char*)</td><td>SWIG_FromCharPtrAndSize(char*,
|
|
size_t)</td><td> char* to String</td></tr>
|
|
<tr><td>rb_float_new(double)</td><td>SWIG_From_double(double),
|
|
<br> SWIG_From_float(float)</td><td>float/double to Float</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h4><a name="Ruby_nn43">35.7.8.2 Ruby Objects to C Datatypes</a></h4>
|
|
<p>Here, while the Ruby versions return the value directly, the SWIG
|
|
versions do not, but return a status value to indicate success (<tt>
|
|
SWIG_OK</tt>). While more awkward to use, this allows you to write
|
|
typemaps that report more helpful error messages, like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) size_t (int ok)
|
|
ok = SWIG_AsVal_size_t($input, &$1);
|
|
if (!SWIG_IsOK(ok)) {
|
|
SWIG_exception_fail(SWIG_ArgError(ok), Ruby_Format_TypeError( "$1_name", "$1_type", "$symname", $argnum, $input));
|
|
}
|
|
}
|
|
</pre>
|
|
</div><div class="diagram">
|
|
<table border="1" cellpadding="2" cellspacing="2" summary="Ruby objects" width="100%">
|
|
<tbody>
|
|
<tr><td>int NUM2INT(Numeric)</td><td>SWIG_AsVal_int(VALUE, int*)</td></tr>
|
|
<tr><td>int FIX2INT(Numeric)</td><td>SWIG_AsVal_int(VALUE, int*)</td></tr>
|
|
<tr><td>unsigned int NUM2UINT(Numeric)</td><td>
|
|
SWIG_AsVal_unsigned_SS_int(VALUE, int*)</td></tr>
|
|
<tr><td>unsigned int FIX2UINT(Numeric)</td><td>
|
|
SWIG_AsVal_unsigned_SS_int(VALUE, int*)</td></tr>
|
|
<tr><td>long NUM2LONG(Numeric)</td><td>SWIG_AsVal_long(VALUE, long*)</td>
|
|
</tr>
|
|
<tr><td>long FIX2LONG(Numeric)</td><td>SWIG_AsVal_long(VALUE, long*)</td>
|
|
</tr>
|
|
<tr><td>unsigned long FIX2ULONG(Numeric)</td><td>
|
|
SWIG_AsVal_unsigned_SS_long(VALUE, unsigned long*)</td></tr>
|
|
<tr><td>char NUM2CHR(Numeric or String)</td><td>SWIG_AsVal_char(VALUE,
|
|
int*)</td></tr>
|
|
<tr><td>char * StringValuePtr(String)</td><td>
|
|
SWIG_AsCharPtrAndSize(VALUE, char**, size_t*, int* alloc)</td></tr>
|
|
<tr><td>char * rb_str2cstr(String, int*length)</td><td></td></tr>
|
|
<tr><td>double NUM2DBL(Numeric)</td><td>(double) SWIG_AsVal_int(VALUE)
|
|
or similar</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h4><a name="Ruby_nn44">35.7.8.3 Macros for VALUE</a></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">35.7.8.4 Exceptions</a></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">35.7.8.5 Iterators</a></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">35.7.9 Typemap Examples</a></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">35.7.10 Converting a Ruby array to a char **</a></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
|
|
|
|
// This tells SWIG to treat char ** as a special case
|
|
%typemap(in) char ** {
|
|
/* Get the length of the array */
|
|
int size = RARRAY($input)->len;
|
|
int i;
|
|
$1 = (char **) malloc((size+1)*sizeof(char *));
|
|
/* Get the first element in memory */
|
|
VALUE *ptr = RARRAY($input)->ptr;
|
|
for (i=0; i < size; i++, ptr++) {
|
|
/* Convert Ruby Object String to char* */
|
|
$1[i]= StringValuePtr(*ptr);
|
|
}
|
|
$1[i]=NULL; /* End of list */
|
|
}
|
|
|
|
// This cleans up the char ** array created 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="code targetlang">
|
|
<pre>require 'Argv'
|
|
Argv.print_args(["Dave", "Mike", "Mary", "Jane", "John"])
|
|
argv[0] = Dave
|
|
argv[1] = Mike
|
|
argv[2] = Mary
|
|
argv[3] = Jane
|
|
argv[4] = John</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">35.7.11 Collecting arguments in a hash</a></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);</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",
|
|
'weight' => 270,
|
|
'age' => 42
|
|
)</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)
|
|
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
|
}
|
|
</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)
|
|
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
|
<b>Check_Type($input, T_HASH);</b>
|
|
}</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)
|
|
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
|
Check_Type($input, T_HASH);
|
|
<b>$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));</b>
|
|
}</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)
|
|
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
|
Check_Type($input, T_HASH);
|
|
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
|
<b>$2 = NULL;
|
|
$3 = NULL;
|
|
if ($1 > 0) {
|
|
$2 = (char **) malloc($1*sizeof(char *));
|
|
$3 = (int *) malloc($1*sizeof(int));
|
|
}</b>
|
|
}</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)
|
|
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
|
Check_Type($input, T_HASH);
|
|
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
|
$2 = NULL;
|
|
$3 = NULL;
|
|
if ($1 > 0) {
|
|
$2 = (char **) malloc($1*sizeof(char *));
|
|
$3 = (int *) malloc($1*sizeof(int));
|
|
<b>keys_arr = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
|
for (i = 0; i < $1; i++) {
|
|
}</b>
|
|
}
|
|
}</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)
|
|
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
|
Check_Type($input, T_HASH);
|
|
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
|
$2 = NULL;
|
|
$3 = NULL;
|
|
if ($1 > 0) {
|
|
$2 = (char **) malloc($1*sizeof(char *));
|
|
$3 = (int *) malloc($1*sizeof(int));
|
|
keys_arr = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
|
for (i = 0; i < $1; i++) {
|
|
<b>key = rb_ary_entry(keys_arr, i);
|
|
val = rb_hash_aref($input, key);</b>
|
|
}
|
|
}
|
|
}</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)
|
|
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
|
Check_Type($input, T_HASH);
|
|
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
|
$2 = NULL;
|
|
$3 = NULL;
|
|
if ($1 > 0) {
|
|
$2 = (char **) malloc($1*sizeof(char *));
|
|
$3 = (int *) malloc($1*sizeof(int));
|
|
keys_arr = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
|
for (i = 0; i < $1; i++) {
|
|
key = rb_ary_entry(keys_arr, i);
|
|
val = rb_hash_aref($input, key);
|
|
<b>Check_Type(key, T_STRING);
|
|
Check_Type(val, T_FIXNUM);</b>
|
|
}
|
|
}
|
|
}</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)
|
|
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
|
Check_Type($input, T_HASH);
|
|
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
|
$2 = NULL;
|
|
$3 = NULL;
|
|
if ($1 > 0) {
|
|
$2 = (char **) malloc($1*sizeof(char *));
|
|
$3 = (int *) malloc($1*sizeof(int));
|
|
keys_arr = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
|
for (i = 0; i < $1; i++) {
|
|
key = rb_ary_entry(keys_arr, i);
|
|
val = rb_hash_aref($input, key);
|
|
Check_Type(key, T_STRING);
|
|
Check_Type(val, T_FIXNUM);
|
|
<b>$2[i] = StringValuePtr(key);
|
|
$3[i] = NUM2INT(val);</b>
|
|
}
|
|
}
|
|
}</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) {
|
|
free((void *) $2);
|
|
free((void *) $3);
|
|
}</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">35.7.12 Pointer handling</a></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;
|
|
SWIG_ConvertPtr($input, (void **) &foo, SWIGTYPE_p_Foo, 1);
|
|
|
|
VALUE 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 code">
|
|
<pre>%typemap(in) Foo * {
|
|
SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);
|
|
}</pre>
|
|
</div>
|
|
<h4><a name="Ruby_nn51">35.7.12.1 Ruby Datatype Wrapping</a></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">35.7.13 Example: STL Vector to Ruby Array</a></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)
|
|
%typemap(out) vectorclassname &, const vectorclassname & {
|
|
VALUE arr = rb_ary_new2($1->size());
|
|
vectorclassname::iterator i = $1->begin(), iend = $1->end();
|
|
for ( ; i!=iend; i++ )
|
|
rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));
|
|
$result = arr;
|
|
}
|
|
%typemap(out) vectorclassname, const vectorclassname {
|
|
VALUE arr = rb_ary_new2($1.size());
|
|
vectorclassname::iterator i = $1.begin(), iend = $1.end();
|
|
for ( ; i!=iend; i++ )
|
|
rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));
|
|
$result = arr;
|
|
}
|
|
%enddef</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)</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)
|
|
%typemap(in) vectorclassname &, const vectorclassname & {
|
|
Check_Type($input, T_ARRAY);
|
|
vectorclassname *vec = new vectorclassname;
|
|
int len = RARRAY($input)->len;
|
|
for (int i=0; i!=len; i++) {
|
|
VALUE inst = rb_ary_entry($input, i);
|
|
//The following _should_ work but doesn't on HPUX
|
|
// Check_Type(inst, T_DATA);
|
|
classname *element = NULL;
|
|
Data_Get_Struct(inst, classname, element);
|
|
vec->push_back(element);
|
|
}
|
|
$1 = vec;
|
|
}
|
|
|
|
%typemap(freearg) vectorclassname &, const vectorclassname & {
|
|
delete $1;
|
|
}
|
|
%enddef</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)
|
|
%typemap(out) vectorclassname &, const vectorclassname & {
|
|
VALUE arr = rb_ary_new2($1->size());
|
|
vectorclassname::iterator i = $1->begin(), iend = $1->end();
|
|
for ( ; i!=iend; i++ )
|
|
rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i)));
|
|
$result = arr;
|
|
}
|
|
%typemap(out) vectorclassname, const vectorclassname {
|
|
VALUE arr = rb_ary_new2($1.size());
|
|
vectorclassname::iterator i = $1.begin(), iend = $1.end();
|
|
for ( ; i!=iend; i++ )
|
|
rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i)));
|
|
$result = arr;
|
|
}
|
|
%enddef</pre>
|
|
</div> 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>.
|
|
<h2><a name="Ruby_nn65">35.8 Docstring Features</a></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">
|
|
<pre>
|
|
$ rdoc -E cxx=c -f html file_wrap.cxx
|
|
</pre>
|
|
</div>
|
|
<p>To generate ri documentation from a c wrap file, you could do:</p>
|
|
<div class="code shell">
|
|
<pre>
|
|
$ rdoc -r file_wrap.c
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn66">35.8.1 Module docstring</a></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</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="Ruby_nn67">35.8.2 %feature("autodoc")</a></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">35.8.2.1 %feature("autodoc", "0")</a></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 Ruby code like this will be generated:</p>
|
|
<div class="targetlang">
|
|
<pre>function_name(x, y, foo=nil, bar=nil) -> bool
|
|
...</pre>
|
|
</div>
|
|
<h4><a name="Ruby_autodoc1">35.8.2.2 %feature("autodoc", "1")</a></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
|
|
...</pre>
|
|
</div>
|
|
<h4><a name="Ruby_autodoc2">35.8.2.3 %feature("autodoc", "2")</a></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">35.8.2.4 %feature("autodoc", "3")</a>
|
|
</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
|
|
|
|
Parameters:
|
|
x - int
|
|
y - int
|
|
foo - Foo
|
|
bar - Bar</pre>
|
|
</div>
|
|
<h4><a name="Ruby_nn70">35.8.2.5 %feature("autodoc", "docstring")</a></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;
|
|
void GetPosition(int* OUTPUT, int* OUTPUT);</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn71">35.8.3 %feature("docstring")</a></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">35.9 Advanced Topics</a></h2>
|
|
<h3><a name="Ruby_operator_overloading">35.9.1 Operator overloading</a></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>
|
|
<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>
|
|
</tbody></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">35.9.2 Creating Multi-Module Packages</a></h3>
|
|
<p> The chapter on <a href="#Modules">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
|
|
|
|
%{
|
|
#include "Shape.h"
|
|
%}
|
|
|
|
class Shape {
|
|
protected:
|
|
double xpos;
|
|
double ypos;
|
|
protected:
|
|
Shape(double x, double y);
|
|
public:
|
|
double getX() const;
|
|
double getY() const;
|
|
};</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
|
|
|
|
%{
|
|
#include "Shape.h"
|
|
#include "Circle.h"
|
|
%}
|
|
|
|
// Import the base class definition from Shape module
|
|
%import shape.i
|
|
|
|
class Circle : public Shape {
|
|
protected:
|
|
double radius;
|
|
public:
|
|
Circle(double x, double y, double r);
|
|
double getRadius() const;
|
|
};</pre>
|
|
</div>
|
|
<p> We'll start by building the<b> Shape</b> extension module:</p>
|
|
<div class="code shell">
|
|
<pre>$ swig -c++ -ruby shape.i
|
|
</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'
|
|
|
|
# Since the SWIG runtime support library for Ruby
|
|
# depends on the Ruby library, make sure it's in the list
|
|
# of libraries.
|
|
$libs = append_library($libs, Config::CONFIG['RUBY_INSTALL_NAME'])
|
|
|
|
# Create the makefile
|
|
create_makefile('shape')</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>
|
|
creating Makefile
|
|
$ <b>make</b>
|
|
g++ -fPIC -g -O2 -I. -I/usr/include/ruby-2.1.0 \
|
|
-I. -c shape_wrap.cxx
|
|
gcc -shared -L/usr/local/lib -o shape.so shape_wrap.o -L. \
|
|
-lruby -lruby -lc</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>
|
|
irb(main):001:0> <b>require 'shape'</b>
|
|
true
|
|
irb(main):002:0> <b>require 'circle'</b>
|
|
true
|
|
irb(main):003:0> <b>c = Circle::Circle.new(5, 5, 20)</b>
|
|
#<Circle::Circle:0xa097208>
|
|
irb(main):004:0> <b>c.kind_of? Shape::Shape</b>
|
|
true
|
|
irb(main):005:0> <b>c.getX()</b>
|
|
5.0</pre>
|
|
</div>
|
|
<h3><a name="Ruby_nn56">35.9.3 Specifying Mixin Modules</a></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
|
|
def initialize
|
|
@members = []
|
|
end
|
|
|
|
def each
|
|
@members.each { |m| yield m }
|
|
end
|
|
end</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
|
|
<b>include Enumerable</b>
|
|
def initialize
|
|
@members = []
|
|
end
|
|
def each
|
|
@members.each { |m| yield m }
|
|
end
|
|
end</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";
|
|
|
|
class Set {
|
|
public:
|
|
// Constructor
|
|
Set();
|
|
|
|
// Iterates through set members
|
|
void each();
|
|
};</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">35.10 Memory Management</a></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">35.10.1 Mark and Sweep Garbage Collector</a></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.</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">35.10.2 Object Ownership</a></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" */
|
|
|
|
class Foo
|
|
{
|
|
public:
|
|
Foo() {}
|
|
~Foo() {}
|
|
};
|
|
|
|
class Bar
|
|
{
|
|
Foo *foo_;
|
|
public:
|
|
Bar(): foo_(new Foo) {}
|
|
~Bar() { delete foo_; }
|
|
Foo* get_foo() { return foo_; }
|
|
Foo* get_new_foo() { return new Foo; }
|
|
void set_foo(Foo *foo) { delete foo_; foo_ = foo; }
|
|
};</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</tt>'s destructor.</p>
|
|
<p>Next, consider this code:</p>
|
|
<div class="code targetlang">
|
|
<pre>bar = Bar.new
|
|
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
|
|
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="#Customization_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
|
|
bar = Bar.new
|
|
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 */
|
|
|
|
%module RubyOwnershipExample
|
|
|
|
%{
|
|
#include "RubyOwnershipExample.h"
|
|
%}
|
|
|
|
class Foo
|
|
{
|
|
public:
|
|
Foo();
|
|
~Foo();
|
|
};
|
|
|
|
class Bar
|
|
{
|
|
Foo *foo_;
|
|
public:
|
|
Bar();
|
|
~Bar();
|
|
Foo* get_foo();
|
|
|
|
<b> %newobject get_new_foo;</b>
|
|
Foo* get_new_foo();
|
|
|
|
<b> %apply SWIGTYPE *DISOWN {Foo *foo};</b>
|
|
void set_foo(Foo *foo);
|
|
<b> %clear Foo *foo;</b>
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> This code can be seen in swig/examples/ruby/tracking.</p>
|
|
<h3><a name="Ruby_nn60">35.10.3 Object Tracking</a></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
|
|
|
|
%{
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "zoo.h"
|
|
%}
|
|
|
|
class Animal
|
|
{
|
|
private:
|
|
typedef std::vector<Animal*> AnimalsType;
|
|
typedef AnimalsType::iterator IterType;
|
|
protected:
|
|
AnimalsType animals;
|
|
protected:
|
|
std::string name_;
|
|
public:
|
|
// Construct an animal with this name
|
|
Animal(const char* name) : name_(name) {}
|
|
|
|
// Return the animal's name
|
|
const char* get_name() const { return name.c_str(); }
|
|
};
|
|
|
|
class Zoo
|
|
{
|
|
protected:
|
|
std::vector<Animal *> animals;
|
|
|
|
public:
|
|
// Construct an empty zoo
|
|
Zoo() {}
|
|
|
|
/* Create a new animal. */
|
|
static Animal* Zoo::create_animal(const char* name) {
|
|
return new Animal(name);
|
|
}
|
|
|
|
// Add a new animal to the zoo
|
|
void add_animal(Animal* animal) {
|
|
animals.push_back(animal);
|
|
}
|
|
|
|
Animal* remove_animal(size_t i) {
|
|
Animal* result = this->animals[i];
|
|
IterType iter = this->animals.begin();
|
|
std::advance(iter, i);
|
|
this->animals.erase(iter);
|
|
|
|
return result;
|
|
}
|
|
|
|
// Return the number of animals in the zoo
|
|
size_t get_num_animals() const {
|
|
return animals.size();
|
|
}
|
|
|
|
// Return a pointer to the ith animal
|
|
Animal* get_animal(size_t i) const {
|
|
return animals[i];
|
|
}
|
|
};</pre>
|
|
</div>
|
|
<p>Let's say you SWIG this code and then run IRB:</p>
|
|
<div class="code targetlang">
|
|
<pre>$ <b>irb</b>
|
|
irb(main):001:0> <b>require 'example'</b>
|
|
=> true
|
|
|
|
irb(main):002:0> <b>tiger1 = Example::Animal.new("tiger1")</b>
|
|
=> #<Example::Animal:0x2be3820>
|
|
|
|
irb(main):004:0> <b>tiger1.get_name()</b>
|
|
=> "tiger1"
|
|
|
|
irb(main):003:0> <b>zoo = Example::Zoo.new()</b>
|
|
=> #<Example::Zoo:0x2be0a60>
|
|
|
|
irb(main):006:0> <b>zoo.add_animal(tiger)</b>
|
|
=> nil
|
|
|
|
irb(main):007:0> <b>zoo.get_num_animals()</b>
|
|
=> 1
|
|
|
|
irb(main):007:0> <b>tiger2 = zoo.remove_animal(0)</b>
|
|
=> #<Example::Animal:0x2bd4a18>
|
|
|
|
irb(main):008:0> <b>tiger2.get_name()</b>
|
|
=> "tiger1"
|
|
|
|
irb(main):009:0> <b>tiger1.equal?(tiger2)</b>
|
|
=> false
|
|
</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:</p>
|
|
<div class="code targetlang">
|
|
<pre>irb(main):010:0> <b>tiger1 = nil</b>
|
|
=> nil
|
|
|
|
irb(main):011:0> <b>GC.start</b>
|
|
=> nil
|
|
|
|
irb(main):012:0> <b>tiger2.get_name()</b>
|
|
(irb):12: [BUG] Segmentation fault
|
|
</pre>
|
|
</div>
|
|
<p>After 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>
|
|
<div class="code">
|
|
<pre>%module example
|
|
|
|
%{
|
|
#include "example.h"
|
|
%}
|
|
|
|
<b>/* Tell SWIG that create_animal creates a new object */</b>
|
|
<b>%newobject Zoo::create_animal;</b>
|
|
|
|
<b>/* Tell SWIG to keep track of mappings between C/C++ structs/classes. */</b>
|
|
<b>%trackobjects;</b>
|
|
|
|
%include "example.h"</pre>
|
|
</div>
|
|
<p>When this code runs we see:</p>
|
|
<div class="code targetlang">
|
|
<pre>$ <b>irb</b>
|
|
irb(main):001:0> <b>require 'example'</b>
|
|
=> true
|
|
|
|
irb(main):002:0> <b>tiger1 = Example::Animal.new("tiger1")</b>
|
|
=> #<Example::Animal:0x2be37d8>
|
|
|
|
irb(main):003:0> <b>zoo = Example::Zoo.new()</b>
|
|
=> #<Example::Zoo:0x2be0a18>
|
|
|
|
irb(main):004:0> <b>zoo.add_animal(tiger1)</b>
|
|
=> nil
|
|
|
|
irb(main):006:0> <b>tiger2 = zoo.remove_animal(0)</b>
|
|
=> #<Example::Animal:0x2be37d8>
|
|
|
|
irb(main):007:0> <b>tiger1.equal?(tiger2)</b>
|
|
=> true
|
|
|
|
irb(main):008:0> <b>tiger1 = nil</b>
|
|
=> nil
|
|
|
|
irb(main):009:0> <b>GC.start</b>
|
|
=> nil
|
|
|
|
irb(main):010:0> <b>tiger.get_name()</b>
|
|
=> "tiger1"
|
|
irb(main):011:0></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:</p>
|
|
<div class="code">
|
|
<pre>static void SWIG_RubyAddTracking(void* ptr, VALUE object);
|
|
static VALUE SWIG_RubyInstanceFor(void* ptr) ;
|
|
static void SWIG_RubyRemoveTracking(void* ptr);
|
|
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">35.10.4 Mark Functions</a></h3>
|
|
<p>With a bit more testing, we see that our class library still has
|
|
problems. For example:</p>
|
|
<div class="targetlang">
|
|
<pre>$ <b>irb</b>
|
|
irb(main):001:0> <b>require 'example'</b>
|
|
=> true
|
|
|
|
irb(main):002:0> tiger1 = <b>Example::Animal.new("tiger1")</b>
|
|
=> #<Example::Animal:0x2bea6a8>
|
|
|
|
irb(main):003:0> zoo = <b>Example::Zoo.new()</b>
|
|
=> #<Example::Zoo:0x2be7960>
|
|
|
|
irb(main):004:0> <b>zoo.add_animal(tiger1)</b>
|
|
=> nil
|
|
|
|
irb(main):007:0> <b>tiger1 = nil</b>
|
|
=> nil
|
|
|
|
irb(main):007:0> <b>GC.start</b>
|
|
=> nil
|
|
|
|
irb(main):005:0> <b>tiger2 = zoo.get_animal(0)</b>
|
|
(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
|
|
<tt>tiger1</tt> 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
|
|
|
|
%{
|
|
#include "example.h"
|
|
%}
|
|
|
|
/* Keep track of mappings between C/C++ structs/classes
|
|
and Ruby objects so we can implement a mark function. */
|
|
<b>%trackobjects;</b>
|
|
|
|
/* Specify the mark function */
|
|
<b>%markfunc Zoo "mark_Zoo";</b>
|
|
|
|
%include "example.h"
|
|
|
|
%header %{
|
|
|
|
static void mark_Zoo(void* ptr) {
|
|
Zoo* zoo = (Zoo*) ptr;
|
|
|
|
/* Loop over each object and tell the garbage collector
|
|
that we are holding a reference to them. */
|
|
int count = zoo->get_num_animals();
|
|
|
|
for(int i = 0; i < count; ++i) {
|
|
Animal* animal = zoo->get_animal(i);
|
|
VALUE object = SWIG_RubyInstanceFor(animal);
|
|
|
|
if (object != Qnil) {
|
|
rb_gc_mark(object);
|
|
}
|
|
}
|
|
}
|
|
%}</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
|
|
ruby_track_objects.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
|
|
</b>irb(main):002:0> <b>tiger1=Example::Animal.new("tiger1")</b>
|
|
=> #<Example::Animal:0x2be3bf8>
|
|
|
|
irb(main):003:0> <b>Example::Zoo.new()</b>
|
|
=> #<Example::Zoo:0x2be1780>
|
|
|
|
irb(main):004:0> <b>zoo = Example::Zoo.new()</b>
|
|
=> #<Example::Zoo:0x2bde9c0>
|
|
|
|
irb(main):005:0> <b>zoo.add_animal(tiger1)</b>
|
|
=> nil
|
|
|
|
irb(main):009:0> <b>tiger1 = nil</b>
|
|
=> nil
|
|
|
|
irb(main):010:0> <b>GC.start</b>
|
|
=> nil
|
|
irb(main):014:0> <b>tiger2 = zoo.get_animal(0)</b>
|
|
=> #<Example::Animal:0x2be3bf8>
|
|
|
|
irb(main):015:0> <b>tiger2.get_name()</b>
|
|
=> "tiger1"
|
|
irb(main):016:0></pre>
|
|
</div>
|
|
<p>This code can be seen in swig/examples/ruby/mark_function.</p>
|
|
<h3><a name="Ruby_nn62">35.10.5 Free Functions</a></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 any animal that it contains. This means that the <tt>
|
|
Zoo::add_animal</tt> function should be marked with a <tt>DISOWN</tt>
|
|
typemap and the destructor should be updated as below:</p>
|
|
<div class="code">
|
|
<pre>
|
|
Zoo::~Zoo() {
|
|
IterType iter = this->animals.begin();
|
|
IterType end = this->animals.end();
|
|
|
|
for(iter; iter != end; ++iter) {
|
|
Animal* animal = *iter;
|
|
delete animal;
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p>When we use these objects in IRB we see:</p>
|
|
<div class="code targetlang">
|
|
<pre class="targetlang"><b>$irb</b>
|
|
irb(main):002:0> <b>require 'example'</b>
|
|
=> true
|
|
|
|
irb(main):003:0> <b>zoo = Example::Zoo.new()</b>
|
|
=> #<Example::Zoo:0x2be0fe8>
|
|
|
|
irb(main):005:0> <b>tiger1 = Example::Animal.new("tiger1")</b>
|
|
=> #<Example::Animal:0x2bda760>
|
|
|
|
irb(main):006:0> <b>zoo.add_animal(tiger1)</b>
|
|
=> nil
|
|
|
|
irb(main):007:0> <b>zoo = nil</b>
|
|
=> nil
|
|
|
|
irb(main):008:0> <b>GC.start</b>
|
|
=> nil
|
|
|
|
irb(main):009:0> <b>tiger1.get_name()</b>
|
|
(irb):12: [BUG] Segmentation fault
|
|
</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.</p>
|
|
<div class="code">
|
|
<pre>%module example
|
|
|
|
%{
|
|
#include "example.h"
|
|
%}
|
|
|
|
/* Specify that ownership is transferred to the zoo when calling add_animal */
|
|
%apply SWIGTYPE *DISOWN { Animal* animal };
|
|
|
|
/* Track objects */
|
|
%trackobjects;
|
|
|
|
/* Specify the mark function */
|
|
%freefunc Zoo "free_Zoo";
|
|
|
|
%include "example.h"
|
|
|
|
%header %{
|
|
static void free_Zoo(void* ptr) {
|
|
Zoo* zoo = (Zoo*) ptr;
|
|
|
|
/* Loop over each animal */
|
|
int count = zoo->get_num_animals();
|
|
|
|
for(int i = 0; i < count; ++i) {
|
|
/* Get an animal */
|
|
Animal* animal = zoo->get_animal(i);
|
|
|
|
/* Unlink the Ruby object from the C++ object */
|
|
SWIG_RubyUnlinkObjects(animal);
|
|
|
|
/* Now remove the tracking for this animal */
|
|
SWIG_RubyRemoveTracking(animal);
|
|
}
|
|
|
|
/* Now call SWIG_RubyRemoveTracking for the zoo */
|
|
SWIG_RubyRemoveTracking(ptr);
|
|
/* Now free the zoo which will free the animals it contains */
|
|
delete zoo;
|
|
}
|
|
%} </pre>
|
|
</div>
|
|
<p>Now when we use these objects in IRB we see:</p>
|
|
<div class="code targetlang">
|
|
<pre><b>$irb</b>
|
|
irb(main):002:0> <b>require 'example'</b>
|
|
=> true
|
|
|
|
irb(main):003:0> <b>zoo = Example::Zoo.new()</b>
|
|
=> #<Example::Zoo:0x2be0fe8>
|
|
|
|
irb(main):005:0> <b>tiger1 = Example::Animal.new("tiger1")</b>
|
|
=> #<Example::Animal:0x2bda760>
|
|
|
|
irb(main):006:0> <b>zoo.add_animal(tiger1)</b>
|
|
=> nil
|
|
|
|
irb(main):007:0> <b>zoo = nil</b>
|
|
=> nil
|
|
|
|
irb(main):008:0> <b>GC.start</b>
|
|
=> nil
|
|
|
|
irb(main):009:0> <b>tiger1.get_name()</b>
|
|
RuntimeError: This Animal * already released
|
|
from (irb):10:in `get_name'
|
|
from (irb):10
|
|
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">35.10.6 Embedded Ruby and the C++ Stack</a></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 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 reinitialize
|
|
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="code">
|
|
<pre>
|
|
%initstack Class::memberfunction; // only re-init the stack in this director method
|
|
%ignorestack Class::memberfunction; // do not re-init the stack in this director method
|
|
%initstack Class; // init the stack on all the methods of this class
|
|
%initstack; // all director functions will re-init the stack
|
|
</pre>
|
|
</div><HR NOSHADE>
|
|
<h1><a name="Scilab">36 SWIG and Scilab</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Scilab_preliminaries">Preliminaries</a></li>
|
|
<li><a href="#Scilab_running_swig">Running SWIG</a>
|
|
<ul>
|
|
<li><a href="#Scilab_running_swig_generating_module">Generating the
|
|
module</a></li>
|
|
<li><a href="#Scilab_running_swig_building_module">Building the module</a>
|
|
</li>
|
|
<li><a href="#Scilab_running_swig_loading_module">Loading the module</a></li>
|
|
<li><a href="#Scilab_running_swig_using_module">Using the module</a></li>
|
|
<li><a href="#Scilab_running_swig_options">Scilab command line options</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Scilab_wrapping">A basic tour of C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a href="#Scilab_wrapping_overview">Overview</a></li>
|
|
<li><a href="#Scilab_wrapping_identifiers">Identifiers</a></li>
|
|
<li><a href="#Scilab_wrapping_functions">Functions</a>
|
|
<ul>
|
|
<li><a href="#Scilab_nn13">Argument passing</a></li>
|
|
<li><a href="#Scilab_nn14">Multiple output arguments</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Scilab_wrapping_global_variables">Global variables</a></li>
|
|
<li><a href="#Scilab_wrapping_constants_and_enums">Constants and
|
|
enumerations</a>
|
|
<ul>
|
|
<li><a href="#Scilab_wrapping_constants">Constants</a></li>
|
|
<li><a href="#Scilab_wrapping_enums">Enumerations</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Scilab_wrapping_pointers">Pointers</a>
|
|
<ul>
|
|
<li><a href="#Scilab_wrapping_pointers_utility_functions">Utility
|
|
functions</a></li>
|
|
<li><a href="#Scilab_wrapping_pointers_null_pointers">Null pointers:</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Scilab_wrapping_structs">Structures</a></li>
|
|
<li><a href="#Scilab_wrapping_cpp_classes">C++ classes</a></li>
|
|
<li><a href="#Scilab_wrapping_cpp_inheritance">C++ inheritance</a></li>
|
|
<li><a href="#Scilab_wrapping_cpp_overloading">C++ overloading</a></li>
|
|
<li><a href="#Scilab_wrapping_pointers_references_values_arrays">
|
|
Pointers, references, values, and arrays</a></li>
|
|
<li><a href="#Scilab_wrapping_cpp_templates">C++ templates</a></li>
|
|
<li><a href="#Scilab_wrapping_cpp_operators">C++ operators</a></li>
|
|
<li><a href="#Scilab_wrapping_cpp_namespaces">C++ namespaces</a></li>
|
|
<li><a href="#Scilab_wrapping_cpp_exceptions">C++ exceptions</a></li>
|
|
<li><a href="#Scilab_wrapping_cpp_stl">C++ STL</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Scilab_typemaps">Type mappings and libraries</a>
|
|
<ul>
|
|
<li><a href="#Scilab_typemaps_primitive_types">Default primitive type
|
|
mappings</a></li>
|
|
<li><a href="#Scilab_typemaps_arrays">Arrays</a></li>
|
|
<li><a href="#Scilab_typemaps_pointer-to-pointers">Pointer-to-pointers</a>
|
|
</li>
|
|
<li><a href="#Scilab_typemaps_matrices">Matrices</a></li>
|
|
<li><a href="#Scilab_typemaps_stl">STL</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Scilab_module_initialization">Module initialization</a></li>
|
|
<li><a href="#Scilab_building_modes">Building modes</a>
|
|
<ul>
|
|
<li><a href="#Scilab_building_modes_nobuilder_mode">No-builder mode</a></li>
|
|
<li><a href="#Scilab_building_modes_builder_mode">Builder mode</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Scilab_generated_scripts">Generated scripts</a>
|
|
<ul>
|
|
<li><a href="#Scilab_generated_scripts_builder_script">Builder script</a>
|
|
</li>
|
|
<li><a href="#Scilab_generated_scripts_loader_script">Loader script</a></li>
|
|
<li><a href="#Scilab_generated_scripts_gateway">Gateway XML files</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Scilab_other_resources">Other resources</a></li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> Scilab is a scientific software package for numerical computations
|
|
providing a powerful open computing environment for engineering and
|
|
scientific applications that is mostly compatible with MATLAB. More
|
|
information can be found at <a href="https://www.scilab.org">
|
|
www.scilab.org</a>.</p>
|
|
<p> This chapter explains how to use SWIG for Scilab. After this
|
|
introduction, you should be able to generate with SWIG a Scilab
|
|
external module from a C/C++ library.</p>
|
|
<h2><a name="Scilab_preliminaries">36.1 Preliminaries</a></h2>
|
|
<p> SWIG for Scilab supports Linux. Other operating systems haven't been
|
|
tested.</p>
|
|
<p> Scilab is supported from version 5.5.2 onwards, the SWIG generated
|
|
code is supported on both Scilab 5, Scilab 6 and more recent versions.</p>
|
|
<p> SWIG for Scilab supports C language. C++ is partially supported. See
|
|
<a href="#Scilab_wrapping">A basic tour of C/C++ wrapping</a> for
|
|
further details.</p>
|
|
<h2><a name="Scilab_running_swig">36.2 Running SWIG</a></h2>
|
|
<p> Let's see how to use SWIG for Scilab on a small example.
|
|
<br> In this example we bind from C a function and a global variable
|
|
into Scilab. The SWIG interface (stored in a file named <tt>example.i</tt>
|
|
), is the following:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
double Foo = 3.0;
|
|
|
|
int fact(int n) {
|
|
if (n < 0) {
|
|
return 0;
|
|
}
|
|
else if (n == 0) {
|
|
return 1;
|
|
}
|
|
else {
|
|
return n * fact(n-1);
|
|
}
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> Note: a code in an <tt>%inline</tt> section is both parsed and
|
|
wrapped by SWIG, and inserted as is in the wrapper source file.</p>
|
|
<h3><a name="Scilab_running_swig_generating_module">36.2.1 Generating
|
|
the module</a></h3>
|
|
<p> The module is generated using the <tt>swig</tt> executable and its <tt>
|
|
-scilab</tt> option.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -scilab example.i
|
|
</pre>
|
|
</div>
|
|
<p> This command generates two files:</p>
|
|
<ul>
|
|
<li><tt>example_wrap.c</tt>: a C source file containing the wrapping
|
|
code and also here the wrapped code (the <tt>fact()</tt> and <tt>Foo</tt>
|
|
definitions)</li>
|
|
<li><tt>loader.sce</tt>: a Scilab script used to load the module into
|
|
Scilab</li>
|
|
</ul>
|
|
<p> Note: if the following error is returned:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
:1: Error: Unable to find 'swig.swg'
|
|
:3: Error: Unable to find 'scilab.swg'
|
|
</pre>
|
|
</div>
|
|
<p> it may be because the SWIG library is not found. Check the <tt>
|
|
SWIG_LIB</tt> environment variable or your SWIG installation.</p>
|
|
<p> Note: SWIG for Scilab can work in two modes related to the way the
|
|
module is built, see the <a href="#Scilab_building_modes">Building
|
|
modes</a> section for details. This example uses the <tt>builder</tt>
|
|
mode.</p>
|
|
<p> The <tt>swig</tt> executable has several other command line options
|
|
you can use. See <a href="#Scilab_running_swig_options">Scilab command
|
|
line options</a> for further details.</p>
|
|
<h3><a name="Scilab_running_swig_building_module">36.2.2 Building the
|
|
module</a></h3>
|
|
<p> To be loaded in Scilab, the wrapper has to be built into a dynamic
|
|
module (or shared library).</p>
|
|
<p> The commands to compile and link the wrapper (with <tt>gcc</tt>)
|
|
into the shared library <tt>libexample.so</tt> are:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ gcc -fPIC -c -I/usr/local/include/scilab example_wrap.c
|
|
$ gcc -shared example_wrap.o -o libexample.so
|
|
</pre>
|
|
</div>
|
|
<p> Note: we supposed in this example that the path to the Scilab
|
|
include directory is <tt>/usr/local/include/scilab</tt> (which is the
|
|
case in a Debian environment), this should be changed for another
|
|
environment.</p>
|
|
<h3><a name="Scilab_running_swig_loading_module">36.2.3 Loading the
|
|
module</a></h3>
|
|
<p> Loading a module is done by running the loader script in Scilab:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> exec loader.sce
|
|
</pre>
|
|
</div>
|
|
<p> Scilab should output the following messages:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Shared archive loaded.
|
|
Link done.
|
|
</pre>
|
|
</div>
|
|
<p> which means that Scilab has successfully loaded the shared library.
|
|
The module functions and other symbols are now available in Scilab.</p>
|
|
<h3><a name="Scilab_running_swig_using_module">36.2.4 Using the module</a>
|
|
</h3>
|
|
<p> In Scilab, the function <tt>fact()</tt> is simply called as
|
|
following:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> fact(5)
|
|
ans =
|
|
|
|
120.
|
|
</pre>
|
|
</div>
|
|
<p>For the <tt>Foo</tt> global variable, the accessors need to be used:<div
|
|
class="targetlang">
|
|
<pre>
|
|
--> Foo_get
|
|
ans =
|
|
|
|
3.
|
|
|
|
--> Foo_set(4);
|
|
|
|
--> Foo_get
|
|
ans =
|
|
|
|
4.
|
|
</pre>
|
|
</div></p>
|
|
<p> Note: for conciseness, we assume in the subsequent Scilab code
|
|
examples that the modules have been beforehand built and loaded in
|
|
Scilab.</p>
|
|
<h3><a name="Scilab_running_swig_options">36.2.5 Scilab command line
|
|
options</a></h3>
|
|
<p> The following table lists the Scilab specific command line options
|
|
in addition to the generic SWIG options:</p>
|
|
<table summary="Scilab specific options">
|
|
<tr><td><tt>-builder</tt></td><td>Generate the Scilab builder script</td>
|
|
</tr>
|
|
<tr><td><tt>-buildercflags <cflags></tt></td><td>Add <cflags> to the
|
|
builder compiler flags</td></tr>
|
|
<tr><td><tt>-builderldflags <ldflags></tt></td><td>Add <ldlags> to the
|
|
builder linker flags</td></tr>
|
|
<tr><td><tt>-buildersources <files></tt></td><td>Add the (comma
|
|
separated) files <files> to the builder sources</td></tr>
|
|
<tr><td><tt>-builderverbositylevel <level></tt></td><td>Set the build
|
|
verbosity level to <level> (default 0: off, 2: high)</td></tr>
|
|
<tr><td><tt>-builderflagscript <file></tt></td><td>Use the Scilab script
|
|
<file> to configure the compiler and linker flags</td></tr>
|
|
<tr><td><tt>-gatewayxml <gateway_id></tt></td><td>Generate the gateway
|
|
XML with the given <gateway_id></td></tr>
|
|
<tr><td><tt>-gatewayxml6</tt></td><td>Generate a gateway XML file
|
|
compatible with Scilab 6</td></tr>
|
|
</table>
|
|
<p> These options can be displayed with:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -scilab -help
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Scilab_wrapping">36.3 A basic tour of C/C++ wrapping</a></h2>
|
|
<h3><a name="Scilab_wrapping_overview">36.3.1 Overview</a></h3>
|
|
<p> SWIG for Scilab provides only a low-level C interface for Scilab
|
|
(see <a href="#Scripting">Scripting Languages</a> for the general
|
|
approach to wrapping). This means that functions, structs, classes,
|
|
variables, etc... are interfaced through C functions. These C functions
|
|
are mapped as Scilab functions. There are a few exceptions, such as
|
|
constants and enumerations, which can be wrapped directly as Scilab
|
|
variables.</p>
|
|
<h3><a name="Scilab_wrapping_identifiers">36.3.2 Identifiers</a></h3>
|
|
<p> In Scilab 5.x, identifier names are composed of 24 characters
|
|
maximum (this limitation disappears from Scilab 6.0 onwards).
|
|
<br> By default, variable, member, and function names longer than 24
|
|
characters are truncated, and a warning is produced for each
|
|
truncation.</p>
|
|
<p>This can cause ambiguities, especially when wrapping structs/classes,
|
|
for which the wrapped function name is composed of the struct/class
|
|
name and field names. In these cases, the <a href="#SWIG_rename_ignore">
|
|
%rename directive</a> can be used to choose a different Scilab name.</p>
|
|
<h3><a name="Scilab_wrapping_functions">36.3.3 Functions</a></h3>
|
|
<p> Functions are wrapped as new Scilab built-in functions. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
int fact(int n) {
|
|
if (n > 1)
|
|
return n * fact(n - 1);
|
|
else
|
|
return 1;
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> creates a built-in function <tt>fact(n)</tt> in Scilab:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> fact(4)
|
|
ans =
|
|
|
|
24.
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Scilab_nn13">36.3.3.1 Argument passing</a></h4>
|
|
<p> In the above example, the function parameter is a primitive type and
|
|
is marshalled by value. So this function is wrapped without any
|
|
additional customization. Argument values are converted between C types
|
|
and Scilab types through type mappings. There are several default type
|
|
mappings for primitive and complex types, described later in the <a href="#Scilab_typemaps">
|
|
Scilab typemaps</a> section.</p>
|
|
<p> When a parameter is not passed by value, such as a pointer or
|
|
reference, SWIG does not know if it is an input, output (or both)
|
|
parameter. The INPUT, OUTPUT, INOUT typemaps defined in the <tt>
|
|
typemaps.i</tt> library can be used to specify this.</p>
|
|
<p> Let's see this on two simple functions: <tt>sub()</tt> which has an
|
|
output parameter, and <tt>inc()</tt>, which as input/output parameter:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%include <typemaps.i>
|
|
|
|
extern void sub(int *INPUT, int *INPUT, int *OUTPUT);
|
|
extern void inc(int *INOUT, int *INPUT);
|
|
|
|
%{
|
|
void sub(int *x, int *y, int *result) {
|
|
*result = *x - *y;
|
|
}
|
|
void inc(int *x, int *delta) {
|
|
*x = *x + *delta;
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> In Scilab, parameters are passed by value. The output (and inout)
|
|
parameters are returned as the result of the functions:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> sub(5, 3)
|
|
ans =
|
|
|
|
2.
|
|
|
|
--> inc(4, 3)
|
|
ans =
|
|
|
|
7.
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Scilab_nn14">36.3.3.2 Multiple output arguments</a></h4>
|
|
<p> A C function can have several output parameters. They can all be
|
|
returned as results of the wrapped function as Scilab supports multiple
|
|
return values from a function when using the <tt>typemaps.i</tt>
|
|
library. If the C function itself returns a result, this is returned
|
|
first before the parameter outputs.</p>
|
|
<p> The example below shows this for a C function returning 2 values and
|
|
a result:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%include <typemaps.i>
|
|
|
|
int divide(int n, int d, int *OUTPUT, int *OUTPUT);
|
|
|
|
%{
|
|
int divide(int n, int d, int q*, int *r) {
|
|
if (d != 0) {
|
|
*q = n / d;
|
|
*r = n % d;
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> [ret, q, r] = divide(20, 6)
|
|
r =
|
|
|
|
2.
|
|
q =
|
|
|
|
3.
|
|
ret =
|
|
|
|
1.
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_global_variables">36.3.4 Global variables</a>
|
|
</h3>
|
|
<p> Global variables are manipulated through generated accessor
|
|
functions. For example, for a given <tt>Foo</tt> global variable, SWIG
|
|
actually generates two functions: <tt>Foo_get()</tt> to get the value
|
|
of <tt>Foo</tt>, and <tt>Foo_set()</tt> to set the value. These
|
|
functions are used as following:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> exec loader.sce;
|
|
--> c = Foo_get();
|
|
|
|
--> Foo_set(4);
|
|
|
|
--> c
|
|
c =
|
|
|
|
3.
|
|
|
|
--> Foo_get()
|
|
ans =
|
|
|
|
4.
|
|
</pre>
|
|
</div>
|
|
<p> It works for variables of primitive type, but also for non-primitive
|
|
types: arrays, and structs/classes which are described later. For now,
|
|
an example with two global primitive arrays x and y is shown:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
int x[10];
|
|
double y[7];
|
|
|
|
void initArrays()
|
|
{
|
|
int i;
|
|
for (i = 0; i < 10; i++)
|
|
x[i] = 1;
|
|
for (i = 0; i < 7; i++)
|
|
y[i] = 1.0f;
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> It works the same:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> exec loader.sce
|
|
|
|
--> initArrays();
|
|
--> x_get()
|
|
ans =
|
|
|
|
1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
|
|
|
|
--> y_set([0:6] / 10);
|
|
--> y_get()
|
|
ans =
|
|
|
|
0. 0.1 0.2 0.3 0.4 0.5 0.6
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_constants_and_enums">36.3.5 Constants and
|
|
enumerations</a></h3>
|
|
<h4><a name="Scilab_wrapping_constants">36.3.5.1 Constants</a></h4>
|
|
<p> There is not any constant in Scilab. By default, C/C++ constants are
|
|
wrapped as getter functions. For example, for the following constants:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
#define ICONST 42
|
|
#define FCONST 2.1828
|
|
#define CCONST 'x'
|
|
#define CCONST2 '\n'
|
|
#define SCONST "Hello World"
|
|
#define SCONST2 "\"Hello World\""
|
|
</pre>
|
|
</div>
|
|
<p> the following getter functions are generated:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> exec loader.sce;
|
|
--> ICONST_get();
|
|
ans =
|
|
|
|
42.
|
|
|
|
--> FCONST_get();
|
|
ans =
|
|
|
|
2.1828
|
|
|
|
--> CCONST_get();
|
|
ans =
|
|
|
|
x
|
|
|
|
--> CCONST2_get();
|
|
ans =
|
|
|
|
--> SCONST_get();
|
|
ans =
|
|
|
|
Hello World
|
|
|
|
--> SCONST2_get();
|
|
ans =
|
|
|
|
"Hello World"
|
|
|
|
--> EXPR_get();
|
|
ans =
|
|
|
|
48.5484
|
|
|
|
--> iconst_get();
|
|
ans =
|
|
|
|
37.
|
|
|
|
--> fconst_get();
|
|
ans =
|
|
|
|
3.14
|
|
</pre>
|
|
</div>
|
|
<p> There is another mode in which constants are wrapped as Scilab
|
|
variables. The variables are easier to use than functions, but the
|
|
drawback is that variables are not constant and so can be modified.</p>
|
|
<p> This mode can be enabled/disabled at any time in the interface file
|
|
with <tt>%scilabconst()</tt>, which works like all the other <a href="#Customization_features">
|
|
%feature directives</a>. Use the argument value "1" to enable and "0" to
|
|
disable this mode. For example in this mode the previous constants:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%scilabconst(1);
|
|
#define ICONST 42
|
|
#define FCONST 2.1828
|
|
#define CCONST 'x'
|
|
#define CCONST2 '\n'
|
|
#define SCONST "Hello World"
|
|
#define SCONST2 "\"Hello World\""
|
|
</pre>
|
|
</div>
|
|
<p> are mapped to Scilab variables, with the same name:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> exec loader.sce;
|
|
--> ICONST
|
|
ans =
|
|
|
|
42
|
|
|
|
--> FCONST
|
|
ans =
|
|
|
|
2.1828
|
|
|
|
--> CCONST
|
|
ans =
|
|
|
|
x
|
|
|
|
--> CCONST2
|
|
ans =
|
|
|
|
--> SCONST
|
|
ans =
|
|
|
|
Hello World
|
|
|
|
--> SCONST2
|
|
ans =
|
|
|
|
"Hello World"
|
|
|
|
--> EXPR
|
|
ans =
|
|
|
|
48.5484
|
|
|
|
--> iconst
|
|
ans =
|
|
|
|
37
|
|
|
|
--> fconst
|
|
ans =
|
|
|
|
3.14
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Scilab_wrapping_enums">36.3.5.2 Enumerations</a></h4>
|
|
<p> The wrapping of enums is the same as for constants. By default,
|
|
enums are wrapped as getter functions. For example, with the following
|
|
enumeration:</p>
|
|
<div class="code">
|
|
<pre>%module example
|
|
typedef enum { RED, BLUE, GREEN } color;
|
|
</pre>
|
|
</div>
|
|
<p> a getter function will be generated for each value of the
|
|
enumeration:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> exec loader.sce;
|
|
--> RED_get()
|
|
ans =
|
|
|
|
0.
|
|
|
|
--> BLUE_get()
|
|
ans =
|
|
|
|
1.
|
|
|
|
--> GREEN_get()
|
|
ans =
|
|
|
|
2.
|
|
</pre>
|
|
</div>
|
|
<p> The <tt>%scilabconst()</tt> feature is also available for
|
|
enumerations:</p>
|
|
<div class="code">
|
|
<pre>%module example
|
|
%scilabconst(1) color;
|
|
typedef enum { RED, BLUE, GREEN } color;
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> exec loader.sce;
|
|
--> RED
|
|
ans =
|
|
|
|
0.
|
|
|
|
--> BLUE
|
|
ans =
|
|
|
|
1.
|
|
|
|
--> GREEN
|
|
ans =
|
|
|
|
2.
|
|
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_pointers">36.3.6 Pointers</a></h3>
|
|
<p> Pointers are supported by SWIG. A pointer can be returned from a
|
|
wrapped C/C++ function, stored in a Scilab variable, and used in input
|
|
argument of another C/C++ function.</p>
|
|
<p> Also, thanks to the SWIG runtime which stores information about
|
|
types, pointer types are tracked between exchanges Scilab and the
|
|
native code. Indeed pointer types are stored alongside the pointer
|
|
address. A pointer is mapped to a Scilab structure (<a href="https://help.scilab.org/docs/5.5.2/en_US/tlist.html">
|
|
tlist</a>), which contains as fields the pointer address and the pointer
|
|
type (in fact a pointer to the type information structure in the SWIG
|
|
runtime).
|
|
<br> Why a native pointer is not mapped to a Scilab pointer (type name:
|
|
"pointer", type ID: 128) ? The big advantage of mapping to a <tt>tlist</tt>
|
|
is that it exposes a new type for the pointer in Scilab, type which can
|
|
be accessed in Scilab with the <a href="https://help.scilab.org/docs/5.5.2/en_US/typeof.html">
|
|
typeof</a> function, and manipulated using the <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">
|
|
overloading</a> mechanism.</p>
|
|
<p> Notes:</p>
|
|
<ul>
|
|
<li>type tracking needs the SWIG runtime to be first initialized with
|
|
the appropriate function (see the <a href="#Scilab_module_initialization">
|
|
Module initialization</a> section).</li>
|
|
<li>for any reason, if a wrapped pointer type is unknown (or if the SWIG
|
|
runtime is not initialized), SWIG maps it to a Scilab pointer. Also, a
|
|
Scilab pointer is always accepted as a pointer argument of a wrapped
|
|
function. The drawback is that pointer type is lost.</li>
|
|
</ul>
|
|
<p> Following is an example of the wrapping of the C <tt>FILE*</tt>
|
|
pointer:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%{
|
|
#include <stdio.h>
|
|
%}
|
|
|
|
FILE *fopen(const char *filename, const char *mode);
|
|
int fputs(const char *, FILE *);
|
|
int fclose(FILE *);
|
|
</pre>
|
|
</div>
|
|
<p> These functions can be used the same way as in C from Scilab:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> example_Init();
|
|
|
|
--> f = fopen("junk", "w");
|
|
--> typeof(f)
|
|
ans =
|
|
|
|
_p_FILE
|
|
|
|
--> fputs("Hello World", f);
|
|
--> fclose(f);
|
|
</pre>
|
|
</div>
|
|
<p> Note: the type name <tt>_p_FILE</tt> which means "pointer to FILE".</p>
|
|
<p> The user of a pointer is responsible for freeing it or, like in the
|
|
example, closing any resources associated with it (just as is required
|
|
in a C program).</p>
|
|
<h4><a name="Scilab_wrapping_pointers_utility_functions">36.3.6.1
|
|
Utility functions</a></h4>
|
|
<p> As a scripting language, Scilab does not provide functions to
|
|
manipulate pointers. However, in some cases it can be useful, such as
|
|
for testing or debugging.</p>
|
|
<p> SWIG comes with two pointer utility functions:</p>
|
|
<ul>
|
|
<li><tt>SWIG_this()</tt>: returns the address value of a pointer</li>
|
|
<li><tt>SWIG_ptr()</tt>: creates a pointer from an address value</li>
|
|
</ul>
|
|
<p> Note: a pointer created by <tt>SWIG_ptr()</tt> does not have any
|
|
type and is mapped as a Scilab pointer.</p>
|
|
<p>Following we use the utility functions on the previous example:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> f = fopen("junk", "w");
|
|
--> fputs("Hello", f);
|
|
--> addr = SWIG_this(f)
|
|
ans =
|
|
|
|
8219088.
|
|
|
|
--> p = SWIG_ptr(addr);
|
|
--> typeof(p)
|
|
ans =
|
|
|
|
pointer
|
|
|
|
--> fputs(" World", p);
|
|
--> fclose(f);
|
|
</pre>
|
|
</div>
|
|
<h4><a name="Scilab_wrapping_pointers_null_pointers">36.3.6.2 Null
|
|
pointers:</a></h4>
|
|
<p> Using the previous <tt>SWIG_this()</tt> and <tt>SWIG_ptr()</tt>, it
|
|
is possible to create and check null pointers:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> p = SWIG_ptr(0);
|
|
--> SWIG_this(p) == 0
|
|
ans =
|
|
|
|
T
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_structs">36.3.7 Structures</a></h3>
|
|
<p> Structs exist in Scilab, but C structs are not (at least in this
|
|
version of SWIG) mapped to Scilab structs. A C structure is wrapped
|
|
through low-level accessor functions, i.e. functions that give access
|
|
to the member variables of this structure. In Scilab, a structure is
|
|
manipulated through a pointer which is passed as an argument to the
|
|
accessor functions.</p>
|
|
<p> Let's see it on an example of a struct with two members:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
|
|
typedef struct {
|
|
int x;
|
|
int arr[4];
|
|
} Foo;
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> Several functions are generated:</p>
|
|
<ul>
|
|
<li>a constructor function <tt>new_Foo()</tt> which returns a pointer to
|
|
a newly created struct <tt>Foo</tt>.</li>
|
|
<li>two member getter functions <tt>Foo_x_get()</tt>, <tt>Foo_arr_get()</tt>
|
|
, to get the values of <tt>x</tt> and <tt>y</tt> for the struct pointer
|
|
(provided as the first parameter to these functions)</li>
|
|
<li>two member setter functions <tt>Foo_x_set()</tt>, <tt>Foo_arr_set()</tt>
|
|
, to set the values of <tt>x</tt> and <tt>y</tt> for the struct pointer
|
|
(provided as the first parameter to these functions).</li>
|
|
<li>a destructor function <tt>delete_Foo()</tt> to release the struct
|
|
pointer.</li>
|
|
</ul>
|
|
<p> Usage example:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> f = new_Foo();
|
|
--> Foo_x_set(f, 100);
|
|
--> Foo_x_get(f)
|
|
ans =
|
|
|
|
100.
|
|
|
|
--> Foo_arr_set(f, [0:3]);
|
|
--> Foo_arr_get(f)
|
|
ans =
|
|
|
|
0. 1. 2. 3.
|
|
|
|
--> delete_Foo(f);
|
|
</pre>
|
|
</div>
|
|
<p> Members of a structure that are also structures are also accepted
|
|
and wrapped as a pointer:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
|
|
typedef struct {
|
|
int x;
|
|
} Bar;
|
|
|
|
typedef struct {
|
|
Bar b;
|
|
} Foo;
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> b = new_Bar();
|
|
--> Bar_x_set(b, 20.);
|
|
|
|
--> f = new_Foo();
|
|
--> Foo_b_set(f, b);
|
|
|
|
--> b2 = Foo_b_get(f);
|
|
--> Bar_x_get(b2);
|
|
ans =
|
|
|
|
20.
|
|
</pre>
|
|
</div>
|
|
<p> Note: the pointer to the struct works as described in <a href="#Scilab_wrapping_pointers">
|
|
Pointers</a>. For example, the type of the struct pointer can be get
|
|
with <tt>typeof</tt>, as following:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> example_Init();
|
|
--> b = new_Bar();
|
|
--> typeof(b)
|
|
ans =
|
|
|
|
_p_Bar
|
|
--> delete_Bar(b);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_cpp_classes">36.3.8 C++ classes</a></h3>
|
|
<p> Classes do not exist in Scilab. The classes are wrapped the same way
|
|
as structs. Low-level accessor functions are generated for class
|
|
members. Also, constructor and destructor functions are generated to
|
|
create and destroy an instance of the class.</p>
|
|
<p> For example, the following class:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
|
|
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 in Scilab like this:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> p1 = Point_new(3, 5);
|
|
--> p2 = Point_new(1, 2);
|
|
--> p1.distance(p2)
|
|
ans =
|
|
|
|
3.6056
|
|
|
|
--> delete_Point(p1);
|
|
--> delete_Point(p2);
|
|
</pre>
|
|
</div>
|
|
<p> Note: like structs, class pointers are mapped as described in <a href="#Scilab_wrapping_pointers">
|
|
Pointers</a>. Let's give an example which shows that each class pointer
|
|
type is a new type in Scilab that can be used for example (through <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">
|
|
overloading</a>) to implement a custom print for the <tt>Point</tt>
|
|
class:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> function %_p_Point_p(p)
|
|
--> mprintf('[%d, %d]\n', Point_x_get(p), Point_y_get(p));
|
|
--> endfunction
|
|
|
|
--> example_Init();
|
|
--> p = new_Point(1, 2)
|
|
p =
|
|
|
|
[1, 2]
|
|
|
|
--> delete_Point(p);
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_cpp_inheritance">36.3.9 C++ inheritance</a></h3>
|
|
<p> Inheritance is supported. SWIG knows the inheritance relationship
|
|
between classes.</p>
|
|
<p> A function is only generated for the class in which it is actually
|
|
declared. But if one of its parameters is a class, any instance of a
|
|
derived class is accepted as the argument.</p>
|
|
<p> This mechanism also applies for accessor functions: they are
|
|
generated only in the class in which they are defined. But any instance
|
|
of a derived class can be used as the argument to these accessor
|
|
functions.</p>
|
|
<p> For example, let's take a base class <tt>Shape</tt> and two derived
|
|
classes <tt>Circle</tt> and <tt>Square</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
|
|
class Shape {
|
|
public:
|
|
double x, y;
|
|
void set_location(double _x, double _y) { x = _x; y = _y; }
|
|
virtual double get_perimeter() { return 0; };
|
|
};
|
|
|
|
class Circle : public Shape {
|
|
public:
|
|
int radius;
|
|
Circle(int _radius): radius(_radius) {};
|
|
virtual double get_perimeter() { return 6.28 * radius; }
|
|
};
|
|
|
|
class Square : public Shape {
|
|
public:
|
|
int size;
|
|
Square(int _size): size(_size) {};
|
|
virtual double get_perimeter() { return 4 * size; }
|
|
};
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> To set the location of the <tt>Circle</tt>, we have to use the
|
|
function <tt>set_location()</tt> of the parent <tt>Shape</tt>. But we
|
|
can use either use the <tt>get_perimeter()</tt> function of the parent
|
|
class or the derived class:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> c = new_Circle(3);
|
|
|
|
--> Shape_set_location(c, 2, 3);
|
|
--> Shape_x_get(c)
|
|
ans =
|
|
|
|
2.
|
|
|
|
--> Circle_get_perimeter(c)
|
|
ans =
|
|
|
|
18.84
|
|
|
|
--> Shape_get_perimeter(c)
|
|
ans =
|
|
|
|
18.84
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_cpp_overloading">36.3.10 C++ overloading</a>
|
|
</h3>
|
|
<p> As explained in <a href="#SWIGPlus_overloaded_methods">Overloaded
|
|
functions and methods</a> SWIG provides support for overloaded
|
|
functions and constructors.</p>
|
|
<p>As SWIG knows pointer types, the overloading works also with pointer
|
|
types, here is an example with a function <tt>magnify</tt> overloaded
|
|
for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
void magnify(Square *square, double factor) {
|
|
square->size *= factor;
|
|
};
|
|
|
|
void magnify(Circle *circle, double factor) {
|
|
square->radius *= factor;
|
|
};
|
|
</pre>
|
|
</div><div class="targetlang">
|
|
<pre>
|
|
--> example_Init();
|
|
--> c = new_Circle(3);
|
|
--> s = new_Square(2);
|
|
|
|
--> magnify(c, 10);
|
|
--> Circle_get_radius(c)
|
|
ans =
|
|
|
|
30;
|
|
--> magnify(s, 10);
|
|
--> Square_get_size(s)
|
|
ans =
|
|
|
|
20;
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_pointers_references_values_arrays">36.3.11
|
|
Pointers, references, values, and arrays</a></h3>
|
|
<p> In C++ objects can be passed by value, pointer, reference, or by an
|
|
array:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%{
|
|
#include <sciprint.h>
|
|
%}
|
|
|
|
%inline %{
|
|
|
|
class Foo {
|
|
public:
|
|
Foo(int _x) : x(_x) {}
|
|
int x;
|
|
};
|
|
|
|
void spam1(Foo *f) { sciprint("%d\n", f->x); } // Pass by pointer
|
|
void spam2(Foo &f) { sciprint("%d\n", f.x); } // Pass by reference
|
|
void spam3(Foo f) { sciprint("%d\n", f.x); } // Pass by value
|
|
void spam4(Foo f[]) { sciprint("%d\n", f[0].x); } // Array of objects
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> In SWIG, there is no real distinction between these. So in Scilab,
|
|
it is perfectly legal to do this:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> f = new_Foo()
|
|
--> spam1(f)
|
|
3
|
|
--> spam2(f)
|
|
3
|
|
--> spam3(f)
|
|
3
|
|
--> spam4(f)
|
|
3
|
|
</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> All these functions will return a pointer to an instance of <tt>Foo</tt>
|
|
. As the function <tt>spam7</tt> returns a value, new instance of <tt>
|
|
Foo</tt> has to be allocated, and a pointer on this instance is
|
|
returned.</p>
|
|
<h3><a name="Scilab_wrapping_cpp_templates">36.3.12 C++ templates</a></h3>
|
|
<p> As in other languages, function and class templates are supported in
|
|
SWIG Scilab.</p>
|
|
<p> You have to tell SWIG to create wrappers for a particular template
|
|
instantiation. The <tt>%template</tt> directive is used for this
|
|
purpose. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
template<class T1, class T2, class T3>
|
|
struct triplet {
|
|
T1 first;
|
|
T2 second;
|
|
T3 third;
|
|
triplet(const T1& a, const T2& b, const T3& c) {
|
|
third = a; second = b; third = c;
|
|
}
|
|
};
|
|
|
|
%template(IntTriplet) triplet<int, int, int>;
|
|
</pre>
|
|
</div>
|
|
<p> Then in Scilab:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> t = new_IntTriplet(3, 4, 1);
|
|
|
|
--> IntTriplet_first_get(t)
|
|
ans =
|
|
|
|
3.
|
|
|
|
--> IntTriplet_second_get(t)
|
|
ans =
|
|
|
|
4.
|
|
|
|
--> IntTriplet_third_get(t)
|
|
ans =
|
|
|
|
1.
|
|
|
|
--> delete_IntTriplet(t);
|
|
</pre>
|
|
</div>
|
|
<p> More details on template support can be found in the <a href="#SWIGPlus_nn30">
|
|
templates</a> documentation.</p>
|
|
<h3><a name="Scilab_wrapping_cpp_operators">36.3.13 C++ operators</a></h3>
|
|
<p> C++ operators are partially supported. Operator overloading exists
|
|
in Scilab, but a C++ operator is not (in this version) wrapped by SWIG
|
|
as a Scilab operator, but as a function. It is not automatic, you have
|
|
to rename each operator (with the instruction <tt>%rename</tt>) with
|
|
the suitable wrapper name.</p>
|
|
<p> Let's see it with an example of class with two operators <tt>+</tt>
|
|
and <tt>double()</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%rename(plus) operator +;
|
|
%rename(toDouble) operator double();
|
|
|
|
%inline %{
|
|
|
|
class Complex {
|
|
public:
|
|
Complex(double re, double im) : real(re), imag(im) {};
|
|
|
|
Complex operator+(const Complex& other) {
|
|
double result_real = real + other.real;
|
|
double result_imaginary = imag + other.imag;
|
|
return Complex(result_real, result_imaginary);
|
|
}
|
|
operator double() { return real; }
|
|
private:
|
|
double real;
|
|
double imag;
|
|
};
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> c1 = new_Complex(3, 7);
|
|
|
|
--> c2 = Complex_plus(c, new_Complex(1, 1));
|
|
|
|
--> Complex_toDouble(c2)
|
|
ans =
|
|
|
|
4.
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_wrapping_cpp_namespaces">36.3.14 C++ namespaces</a></h3>
|
|
<p> SWIG is aware of C++ namespaces, but does not use it for wrappers.
|
|
The module is not broken into submodules, nor do namespace appear in
|
|
functions names. All the namespaces are all flattened in the module.
|
|
For example with one namespace <tt>Foo</tt>:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
|
|
namespace foo {
|
|
int fact(int n) {
|
|
if (n > 1)
|
|
return n * fact(n-1);
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
struct Vector {
|
|
double x, y, z;
|
|
};
|
|
};
|
|
|
|
%}
|
|
|
|
</pre>
|
|
</div>
|
|
<p> In Scilab, there is no need to the specify the <tt>Foo</tt>
|
|
namespace:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> fact(3)
|
|
ans =
|
|
|
|
6.
|
|
|
|
--> v = new_Vector();
|
|
--> Vector_x_set(v, 3.4);
|
|
--> Vector_y_get(v)
|
|
ans =
|
|
|
|
0.
|
|
</pre>
|
|
</div>
|
|
<p> If your program has more than one namespace, name conflicts 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> Note: the <a href="#SWIGPlus_nspace">nspace</a> feature is not
|
|
supported.</p>
|
|
<h3><a name="Scilab_wrapping_cpp_exceptions">36.3.15 C++ exceptions</a></h3>
|
|
<p> Scilab does not natively support exceptions, but has errors. When an
|
|
exception is thrown, SWIG catches it, and sets a Scilab error. An error
|
|
message is displayed in Scilab. For example:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
void throw_exception() throw(char const *) {
|
|
throw "Bye world !";
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
-->throw_exception()
|
|
!--error 999
|
|
SWIG/Scilab: Exception (char const *) occurred: Bye world !
|
|
</pre>
|
|
</div>
|
|
<p> Scilab has a <tt>try-catch</tt> mechanism (and a similar instruction
|
|
<tt>execstr()</tt>) to handle exceptions. It can be used with the <tt>
|
|
lasterror()</tt> function as following:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> execstr('throw_exception()', 'errcatch');
|
|
ans =
|
|
|
|
999.
|
|
|
|
--> lasterror()
|
|
ans =
|
|
|
|
SWIG/Scilab: Exception (char const *) occurred: Bye world !
|
|
</pre>
|
|
</div>
|
|
<p> If the function has a <tt>throw</tt> exception specification, SWIG
|
|
can automatically map the exception type and set an appropriate Scilab
|
|
error message. It works for a few primitive types, and also for STL
|
|
exceptions (the library <tt>std_except.i</tt> has to be included to get
|
|
the STL exception support):</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%include <std_except.i>
|
|
|
|
%inline %{
|
|
void throw_int() throw(int) {
|
|
throw 12;
|
|
}
|
|
|
|
void throw_stl_invalid_arg(int i) throw(std::invalid_argument) {
|
|
if (i < 0)
|
|
throw std::invalid_argument("argument is negative.");
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> throw_int();
|
|
!--error 999
|
|
SWIG/Scilab: Exception (int) occurred: 12
|
|
|
|
-->throw_stl_invalid_arg(-1);
|
|
!--error 999
|
|
SWIG/Scilab: ValueError: argument is negative.
|
|
</pre>
|
|
</div>
|
|
<p> More complex or custom exception types require specific exception
|
|
typemaps to be implemented in order to specifically handle a thrown
|
|
type. See the <a href="#SWIGPlus">SWIG C++ documentation</a> for more
|
|
details.</p>
|
|
<h3><a name="Scilab_wrapping_cpp_stl">36.3.16 C++ STL</a></h3>
|
|
<p> The Standard Template Library (STL) is partially supported. See <a href="#Scilab_typemaps_stl">
|
|
STL</a> for more details.</p>
|
|
<h2><a name="Scilab_typemaps">36.4 Type mappings and libraries</a></h2>
|
|
<h3><a name="Scilab_typemaps_primitive_types">36.4.1 Default primitive
|
|
type mappings</a></h3>
|
|
<p> The following table provides the equivalent Scilab type for C/C++
|
|
primitive types.</p>
|
|
<div class="table">
|
|
<table border="1" summary="Scilab default primitive type mappings">
|
|
<tr><td><b>C/C++ type</b></td><td><b>Scilab type</b></td></tr>
|
|
<tr><td>bool</td><td>boolean</td></tr>
|
|
<tr><td>char</td><td>string</td></tr>
|
|
<tr><td>signed char</td><td>double or int8</td></tr>
|
|
<tr><td>unsigned char</td><td>double or uint8</td></tr>
|
|
<tr><td>short</td><td>double or int16</td></tr>
|
|
<tr><td>unsigned short</td><td>double or uint16</td></tr>
|
|
<tr><td>int</td><td>double or int32</td></tr>
|
|
<tr><td>unsigned int</td><td>double or uint32</td></tr>
|
|
<tr><td>long</td><td>double or int32</td></tr>
|
|
<tr><td>unsigned long</td><td>double or uint32</td></tr>
|
|
<tr><td>signed long long</td><td>not supported in Scilab 5.x</td></tr>
|
|
<tr><td>unsigned long long</td><td>not supported in Scilab 5.x</td></tr>
|
|
<tr><td>float</td><td>double</td></tr>
|
|
<tr><td>double</td><td>double</td></tr>
|
|
<tr><td>char * or char[]</td><td>string</td></tr>
|
|
</table>
|
|
</div>
|
|
<p> Notes:</p>
|
|
<ul>
|
|
<li>In Scilab the <tt>double</tt> type is far more used than any integer
|
|
type. This is why integer values (<tt>int32</tt>, <tt>uint32</tt>, ...)
|
|
are automatically converted to Scilab <tt>double</tt> values when
|
|
marshalled from C into Scilab. Additionally on input to a C function,
|
|
Scilab <tt>double</tt> values are converted into the related integer
|
|
type.</li>
|
|
<li> When an integer is expected, if the input is a double, the value
|
|
must be an integer, i.e. it must not have any decimal part, otherwise a
|
|
SWIG value error occurs.</li>
|
|
<li> In SWIG for Scilab 5.x, the <tt>long long</tt> type is not
|
|
supported, since Scilab 5.x does not have a 64-bit integer type. The
|
|
default behaviour is for SWIG to generate code that will give a runtime
|
|
error if <tt>long long</tt> type arguments are used from Scilab.</li>
|
|
</ul>
|
|
<h3><a name="Scilab_typemaps_arrays">36.4.2 Arrays</a></h3>
|
|
<p> Typemaps are available by default for arrays. Primitive type arrays
|
|
are automatically converted to/from Scilab matrices. Typemaps are also
|
|
provided to handle members of a struct or class that are arrays.</p>
|
|
<p> In input, the matrix is usually one-dimensional (it can be either a
|
|
row or column vector). But it can also be a two-dimensional matrix.
|
|
Warning: in Scilab, the values are column-major ordered, unlike in C,
|
|
which is row-major ordered.</p>
|
|
<p> The type mappings used for arrays is the same for primitive types,
|
|
described <a href="#Scilab_typemaps_primitive_types">earlier</a>. This
|
|
means that, if needed, a Scilab <tt>double</tt> vector is converted in
|
|
input into the related C integer array and this C integer array is
|
|
automatically converted on output into a Scilab <tt>double</tt> vector.
|
|
Note that unlike scalars, no control is done for arrays when a <tt>
|
|
double</tt> is converted into an integer.</p>
|
|
<p> The following example illustrates all this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%#include <stdio.h>
|
|
|
|
%inline %{
|
|
|
|
void printArray(int values[], int len) {
|
|
int i = 0;
|
|
for (i = 0; i < len; i++) {
|
|
printf("%s %d %s", i==0?"[":"", values[i], i==len-1?"]\n":"");
|
|
}
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> printArray([0 1 2 3], 4)
|
|
[ 0 1 2 3 ]
|
|
|
|
--> printArray([0.2; -1.8; 2; 3.7], 4)
|
|
[ 0 -1 2 3 ]
|
|
|
|
--> printArray([0 1; 2 3], 4)
|
|
[ 0 2 1 3 ]
|
|
|
|
--> printArray([0; 1; 2; 3], 4)
|
|
[ 0 1 2 3 ]
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_typemaps_pointer-to-pointers">36.4.3
|
|
Pointer-to-pointers</a></h3>
|
|
<p> There are no specific typemaps for pointer-to-pointers, they are
|
|
mapped as pointers in Scilab.</p>
|
|
<p> Pointer-to-pointers are sometimes used to implement matrices in C.
|
|
The following is an example of this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%inline %{
|
|
|
|
// Returns the matrix [1 2; 3 4];
|
|
double **create_matrix() {
|
|
double **M;
|
|
int i;
|
|
M = (double **) malloc(2 * sizeof(double *));
|
|
for (i = 0; i < 2; i++) {
|
|
M[i] = (double *) malloc(2 * sizeof(double));
|
|
M[i][0] = 2 * i + 1;
|
|
M[i][1] = 2 * i + 2;
|
|
}
|
|
return M;
|
|
}
|
|
|
|
// Gets the item M(i, j) value
|
|
double get_matrix(double **M, int i, int j) {
|
|
return M[i][j];
|
|
}
|
|
|
|
// Sets the item M(i, j) value to be val
|
|
void set_matrix(double **M, int i, int j, double val) {
|
|
M[i][j] = val;
|
|
}
|
|
|
|
// Prints a matrix (2, 2) to console
|
|
void print_matrix(double **M, int nbRows, int nbCols) {
|
|
int i, j;
|
|
for (i = 0; i < 2; i++) {
|
|
for (j = 0; j < 2; j++) {
|
|
printf("%3g ", M[i][j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<p> These functions are used like this in Scilab:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> m = create_matrix();
|
|
|
|
--> print_matrix(m);
|
|
1. 2.
|
|
3. 4.
|
|
|
|
--> set_matrix(m, 1, 1, 5.);
|
|
|
|
--> get_matrix(m, 1, 1)
|
|
ans =
|
|
|
|
5.
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Scilab_typemaps_matrices">36.4.4 Matrices</a></h3>
|
|
<p> The <tt>matrix.i</tt> library provides a set of typemaps which can
|
|
be useful when working with one-dimensional and two-dimensional
|
|
matrices.</p>
|
|
<p> In order to use this library, just include it in the interface file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <matrix.i>
|
|
</pre>
|
|
</div>
|
|
<p> Several typemaps are available for the common Scilab matrix types:</p>
|
|
<ul>
|
|
<li><tt>double</tt></li>
|
|
<li><tt>int</tt></li>
|
|
<li><tt>char *</tt></li>
|
|
<li><tt>bool</tt></li>
|
|
</ul>
|
|
<p> For example: for a matrix of <tt>int</tt>, we have the typemaps, for
|
|
input:</p>
|
|
<ul>
|
|
<li><tt>(int *IN, int IN_ROWCOUNT, int IN_COLCOUNT)</tt></li>
|
|
<li><tt>(int IN_ROWCOUNT, int IN_COLCOUNT, int *IN)</tt></li>
|
|
<li><tt>(int *IN, int IN_SIZE)</tt></li>
|
|
<li><tt>(int IN_SIZE, int *IN)</tt></li>
|
|
</ul>
|
|
<p> and output:</p>
|
|
<ul>
|
|
<li><tt>(int **OUT, int *OUT_ROWCOUNT, int *OUT_COLCOUNT)</tt></li>
|
|
<li><tt>(int *OUT_ROWCOUNT, int *OUT_COLCOUNT, int **OUT)</tt></li>
|
|
<li><tt>(int **OUT, int *OUT_SIZE)</tt></li>
|
|
<li><tt>(int *OUT_SIZE, int **OUT)</tt></li>
|
|
</ul>
|
|
<p> They marshall a Scilab matrix type into the appropriate 2 or 3 C
|
|
parameters. The following is an example using the typemaps in this
|
|
library:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%include <matrix.i>
|
|
|
|
%apply (int *IN, int IN_ROWCOUNT, int IN_COLCOUNT) { (int *matrix, int matrixNbRow, int matrixNbCol) };
|
|
%apply (int **OUT, int *OUT_ROWCOUNT, int *OUT_COLCOUNT) { (int **outMatrix, int *outMatrixNbRow, int *outMatrixNbCol) };
|
|
|
|
%inline %{
|
|
|
|
void absolute(int *matrix, int matrixNbRow, int matrixNbCol,
|
|
int **outMatrix, int *outMatrixNbRow, int *outMatrixNbCol) {
|
|
int i, j;
|
|
*outMatrixNbRow = matrixNbRow;
|
|
*outMatrixNbCol = matrixNbCol;
|
|
*outMatrix = malloc(matrixNbRow * matrixNbCol * sizeof(int));
|
|
for (i=0; i < matrixNbRow * matrixNbCol; i++) {
|
|
(*outMatrix)[i] = matrix[i] > 0 ? matrix[i]:-matrix[i];
|
|
}
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> absolute([-0 1 -2; 3 4 -5])
|
|
ans =
|
|
|
|
0. 1. 2.
|
|
3. 4. 5.
|
|
</pre>
|
|
</div>
|
|
<p> The remarks made earlier for arrays also apply here:</p>
|
|
<ul>
|
|
<li>The values of matrices in Scilab are column-major orderered,</li>
|
|
<li>There is no control while converting <tt>double</tt> values to
|
|
integers, <tt>double</tt> values are truncated without any checking or
|
|
warning.</li>
|
|
</ul>
|
|
<h3><a name="Scilab_typemaps_stl">36.4.5 STL</a></h3>
|
|
<p> The STL library wraps some containers defined in the STL (Standard
|
|
Template Library), so that they can be manipulated in Scilab. This
|
|
library also provides the appropriate typemaps to use the containers in
|
|
functions and variables.</p>
|
|
<p> The list of wrapped sequence containers are:</p>
|
|
<ul>
|
|
<li><tt>std::vector</tt></li>
|
|
<li><tt>std::list</tt></li>
|
|
<li><tt>std::deque</tt></li>
|
|
</ul>
|
|
<p> And associative containers are:</p>
|
|
<ul>
|
|
<li><tt>std::set</tt></li>
|
|
<li><tt>std::multiset</tt></li>
|
|
</ul>
|
|
<p> Typemaps are available for the following container types:</p>
|
|
<ul>
|
|
<li><tt>double</tt></li>
|
|
<li><tt>float</tt></li>
|
|
<li><tt>int</tt></li>
|
|
<li><tt>string</tt></li>
|
|
<li><tt>bool</tt></li>
|
|
<li><tt>pointer</tt></li>
|
|
</ul>
|
|
<p> Containers of other item types are not supported. Using them does
|
|
not break compilation, but provokes a runtime error. Containers of enum
|
|
are not supported yet.</p>
|
|
<p> In order to use the STL, the library must first be included in the
|
|
SWIG interface file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <stl.i>
|
|
</pre>
|
|
</div>
|
|
<p>Then for each container used, the appropriate template must be
|
|
instantiated, in the <tt>std</tt> namespace:<div class="code">
|
|
<pre>
|
|
namespace std {
|
|
%template(IntVector) vector<int>;
|
|
%template(DoubleVector) vector<double>;
|
|
}
|
|
</pre>
|
|
</div></p>
|
|
<p> Additionally, the module initialization function has to be executed
|
|
first in Scilab, so that all the types are known to Scilab. See the <a href="#Scilab_module_initialization">
|
|
Module initialization</a> section for more details.</p>
|
|
<p> Because in Scilab matrices exist for basic types only, a sequence
|
|
container of pointers is mapped to a Scilab list. For other item types
|
|
(double, int, string...) the sequence container is mapped to a Scilab
|
|
matrix.</p>
|
|
<p> The first example below shows how to create a vector (of <tt>int</tt>
|
|
) in Scilab, add some values to the vector and pass it as an argument of
|
|
a function. It also shows, thanks to the typemaps, that we can also
|
|
pass a Scilab matrix of values directly into the function:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%include <stl.i>
|
|
|
|
namespace std {
|
|
%template(IntVector) vector<int>;
|
|
}
|
|
|
|
%{
|
|
#include <numeric>
|
|
%}
|
|
|
|
%inline %{
|
|
|
|
double average(std::vector<int> v) {
|
|
return std::accumulate(v.begin(), v.end(), 0.0) / v.size();
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> example_Init();
|
|
|
|
--> v = new_IntVector();
|
|
|
|
--> for i = 1:4
|
|
--> IntVector_push_back(v, i);
|
|
--> end;
|
|
|
|
--> average(v)
|
|
ans =
|
|
|
|
2.5
|
|
|
|
--> average([0 1 2 3])
|
|
ans =
|
|
|
|
2.5
|
|
|
|
--> delete_IntVector();
|
|
</pre>
|
|
</div>
|
|
<p> In the second example, a set of struct (<tt>Person</tt>) is wrapped.
|
|
A function performs a search in this set, and returns a subset. As one
|
|
can see, the result in Scilab is a list of pointers:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%include <stl.i>
|
|
|
|
%{
|
|
#include <string>
|
|
%}
|
|
|
|
%inline %{
|
|
|
|
struct Person {
|
|
Person(std::string _name, int _age) : name(_name), age(_age) {};
|
|
std::string name;
|
|
int age;
|
|
};
|
|
typedef Person * PersonPtr;
|
|
|
|
%}
|
|
|
|
namespace std {
|
|
%template(PersonPtrSet) set<PersonPtr>;
|
|
}
|
|
|
|
%inline %{
|
|
|
|
std::set<PersonPtr> findPersonsByAge(std::set<PersonPtr> persons, int minAge, int maxAge) {
|
|
std::set<PersonPtr> foundPersons;
|
|
for (std::set<PersonPtr>::iterator it = persons.begin(); it != persons.end(); it++) {
|
|
if (((*it)->age >= minAge) && ((*it)->age <= maxAge)) {
|
|
foundPersons.insert(*it);
|
|
}
|
|
}
|
|
return foundPersons;
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<br><div class="targetlang">
|
|
<pre>
|
|
--> example_Init();
|
|
|
|
--> joe = new_Person("Joe", 25);
|
|
--> susan = new_Person("Susan", 32);
|
|
--> bill = new_Person("Bill", 50);
|
|
|
|
--> p = new_PersonPtrSet();
|
|
--> PersonPtrSet_insert(p, susan);
|
|
--> PersonPtrSet_insert(p, joe);
|
|
--> PersonPtrSet_insert(p, bill);
|
|
|
|
--> l = findPersonsByAge(p, 20, 40);
|
|
|
|
--> size(l)
|
|
ans =
|
|
|
|
2.
|
|
|
|
--> Person_name_get(l(1))
|
|
ans =
|
|
|
|
Susan
|
|
|
|
--> Person_name_get(l(2))
|
|
ans =
|
|
|
|
Joe
|
|
|
|
--> delete_PersonPtrSet(p);
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Scilab_module_initialization">36.5 Module initialization</a>
|
|
</h2>
|
|
<p> The wrapped module contains an initialization function to:</p>
|
|
<ul>
|
|
<li>initialize the SWIG runtime, needed for pointer type tracking or
|
|
when working with the STL</li>
|
|
<li>initialize the module constants and enumerations declared with <tt>
|
|
%scilabconst()</tt></li>
|
|
</ul>
|
|
<p> This initialization function should be executed at the start of a
|
|
script, before the wrapped library has to be used.</p>
|
|
<p> The function has the name of the module suffixed by <tt>_Init</tt>.
|
|
For example, to initialize the module <tt>example</tt>:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
--> example_Init();
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Scilab_building_modes">36.6 Building modes</a></h2>
|
|
<p> The mechanism to load an external module in Scilab is called<i>
|
|
Dynamic Link</i> and works with dynamic modules (or shared libraries, <tt>
|
|
.so</tt> files).</p>
|
|
<p> To produce a dynamic module, when generating the wrapper, there are
|
|
two possibilities, or build modes:</p>
|
|
<ul>
|
|
<li>the <tt>nobuilder</tt> mode, this is the default mode in SWIG. The
|
|
user is responsible of the build.</li>
|
|
<li>the <tt>builder</tt> mode. In this mode, Scilab is responsible of
|
|
building.</li>
|
|
</ul>
|
|
<h3><a name="Scilab_building_modes_nobuilder_mode">36.6.1 No-builder
|
|
mode</a></h3>
|
|
<p> In this mode, used by default, SWIG generates the wrapper sources,
|
|
which have to be manually compiled and linked. A loader script <tt>
|
|
loader.sce</tt> is also produced, this one is executed further in Scilab
|
|
to load the module.</p>
|
|
<p> This mode is the best option to use when you have to integrate the
|
|
module build into a larger build process.</p>
|
|
<h3><a name="Scilab_building_modes_builder_mode">36.6.2 Builder mode</a></h3>
|
|
<p> In this mode, in addition to the wrapper sources, SWIG produces a
|
|
builder Scilab script (<tt>builder.sce</tt>), which is executed in
|
|
Scilab to build the module. In a few words, the Scilab <tt>ilib_build()</tt>
|
|
command is used, which produces the shared library file, and the loader
|
|
script <tt>loader.sce</tt> (and also a cleaner script <tt>cleaner.sce</tt>
|
|
).</p>
|
|
<p> An advantage of this mode is that it hides all the complexity of the
|
|
build and other platform issues. Also it allows the module to conform
|
|
to a Scilab external module convention which is that an external module
|
|
should be simply built by calling a builder script.</p>
|
|
<p> The builder mode is activated with the <tt>-builder</tt> SWIG
|
|
option. In this mode, the following SWIG options may be used to setup
|
|
the build:</p>
|
|
<ul>
|
|
<li><tt><b>-buildersources</b></tt>: to add sources to the build
|
|
(several files must be separated by a comma)</li>
|
|
<li><tt><b>-buildercflags</b></tt>: to add flags to the builder compiler
|
|
flags, for example to set library dependencies include paths</li>
|
|
<li><tt><b>-builderldflags</b></tt>: to add flags to the linker flags,
|
|
for example to set library dependency names and paths</li>
|
|
</ul>
|
|
<p> Let's give an example how to build a module <tt>example</tt>,
|
|
composed of two sources, and using a library dependency:</p>
|
|
<ul>
|
|
<li>the sources are <tt>baa1.c</tt> and <tt>baa2.c</tt> (and are stored
|
|
in the current directory)</li>
|
|
<li>the library is <tt>libfoo</tt> in <tt>/opt/foo</tt> (headers stored
|
|
in <tt>/opt/foo/include</tt>, and shared library in <tt>/opt/foo/lib</tt>
|
|
)</li>
|
|
</ul>
|
|
<p> The command is:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -scilab -builder -buildercflags -I/opt/foo/include -builderldflags "-L/opt/foo/lib -lfoo" -buildersources baa1.cxx, baa2.cxx example.i
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Scilab_generated_scripts">36.7 Generated scripts</a></h2>
|
|
<p> In this part we give some details about the generated Scilab
|
|
scripts.</p>
|
|
<h3><a name="Scilab_generated_scripts_builder_script">36.7.1 Builder
|
|
script</a></h3>
|
|
<p> <tt>builder.sce</tt> is the name of the builder script generated by
|
|
SWIG in <tt>builder</tt> mode. It contains code like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
ilib_name = "examplelib";
|
|
files = ["example_wrap.c"];
|
|
libs = [];
|
|
table = ["fact", "_wrap_fact";"Foo_set", "_wrap_Foo_set";"Foo_get", "_wrap_Foo_get";];
|
|
ilib_build(ilib_name, table, files, libs);
|
|
</pre>
|
|
</div>
|
|
<p> <tt>ilib_build(lib_name, table, files, libs)</tt> is used to create
|
|
shared libraries, and to generate a loader file used to dynamically
|
|
load the shared library into Scilab.</p>
|
|
<ul>
|
|
<li><tt><b>ilib_name</b></tt>: a character string, the generic name of
|
|
the library without path and extension.</li>
|
|
<li><tt><b>files</b></tt>: string matrix containing objects files needed
|
|
for shared library creation.</li>
|
|
<li><tt><b>libs</b></tt>: string matrix containing extra libraries
|
|
needed for shared library creation.</li>
|
|
<li><tt><b>table</b></tt>: two column string matrix containing a table
|
|
of pairs of 'scilab function name', 'C function name'.</li>
|
|
</ul>
|
|
<h3><a name="Scilab_generated_scripts_loader_script">36.7.2 Loader
|
|
script</a></h3>
|
|
<p> The loader script is used to load in Scilab all the module
|
|
functions. When loaded, these functions can be used as other Scilab
|
|
functions.</p>
|
|
<p> The loader script <tt>loader.sce</tt> contains code similar to:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// ------------------------------------------------------
|
|
// generated by builder.sce: Please do not edit this file
|
|
// ------------------------------------------------------
|
|
|
|
libexamplelib_path = get_file_path('loader.sce');
|
|
list_functions = [ 'fact';
|
|
'Foo_set';
|
|
'Foo_get';
|
|
];
|
|
addinter(libexamplelib_path+'/libexamplelib.so', 'libexamplelib', list_functions);
|
|
// remove temp. variables on stack
|
|
clear libexamplelib_path;
|
|
clear list_functions;
|
|
clear get_file_path;
|
|
// ------------------------------------------------------
|
|
</pre>
|
|
</div>
|
|
<p> <tt>addinter(files, spname, fcts)</tt> performs dynamic linking of a
|
|
compiled C interface function.</p>
|
|
<ul>
|
|
<li><tt><b>files</b></tt>: a character string or a vector of character
|
|
strings defining the object files (containing the C interface
|
|
functions) to link with.</li>
|
|
<li><tt><b>spname</b></tt>: a character string. Name of interface
|
|
routine entry point.</li>
|
|
<li><tt><b>fcts</b></tt>: vector of character strings. The name of new
|
|
Scilab function.</li>
|
|
</ul>
|
|
<h3><a name="Scilab_generated_scripts_gateway">36.7.3 Gateway XML files</a>
|
|
</h3>
|
|
<p>If you need to post-process the entry points, Scilab gateway files
|
|
are XML files that can be used to retrieve all SWIG-generated entry
|
|
points. With these XML files you can write your own <tt>
|
|
builder_swig.sce</tt> file to add custom Scilab for building or linking
|
|
the generated code. Documentation stubs can also be generated thanks to
|
|
these function listings.</p>
|
|
<p>As an example, for a SWIG <a href="Modules.html">module</a> named <tt>
|
|
fmuswig</tt> the Scilab code below can be used to store all
|
|
SWIG-generated functions in a variable named <tt>funs</tt>.</p>
|
|
<div class="code">
|
|
<pre>
|
|
// src_swig_path is a path to the directory containing the fmuswig.i file
|
|
|
|
doc = xmlRead(src_swig_path + "/fmuswig_gateway.xml");
|
|
names = xmlAsText(xmlXPath(doc, "//gateway/@name"));
|
|
funs = xmlAsText(xmlXPath(doc, "//gateway/@function"));
|
|
xmlDelete(doc);
|
|
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Scilab_other_resources">36.8 Other resources</a></h2>
|
|
<ul>
|
|
<li>Example use cases can be found in the <tt>Examples/scilab</tt>
|
|
directory.</li>
|
|
<li>The test suite in the <tt>Examples/test-suite/scilab</tt> can be
|
|
another source of useful use cases.</li>
|
|
<li>The <a href="https://help.scilab.org/api_scilab.html">Scilab API</a>
|
|
is used in the generated code and is a useful reference when examining
|
|
the output.</li>
|
|
<li>This <a href="https://wiki.scilab.org/howto/Create%20a%20toolbox">
|
|
guide</a> describes the Scilab external modules structure and files, in
|
|
particular the files that are generated by SWIG for Scilab.</li>
|
|
</ul>
|
|
<HR NOSHADE>
|
|
<h1><a name="Tcl">37 SWIG and Tcl</a></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. Since SWIG 4.1.0, Tcl
|
|
8.4 or a later release is required. Prior to that earlier Tcl 8.x
|
|
releases were also supported. Tcl 9.0 is supported since SWIG 4.2.1.</p>
|
|
<h2><a name="Tcl_nn2">37.1 Preliminaries</a></h2>
|
|
<p> To build a Tcl module, run SWIG using the <tt>-tcl</tt> or <tt>-tcl8</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">37.1.1 Getting the right header files</a></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">37.1.2 Compiling a dynamic module</a></h3>
|
|
<p> The preferred approach to building an extension module is to compile
|
|
it into a shared object file or DLL. Assuming you have code you need to
|
|
link to in a file called <tt>example.c</tt>, you will need to compile
|
|
your program using commands like this (shown for Linux):</p>
|
|
<div class="code">
|
|
<pre>
|
|
$ swig -tcl example.i
|
|
$ gcc -fPIC -c example.c
|
|
$ gcc -fPIC -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="https://github.com/swig/swig/wiki">
|
|
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">37.1.3 Static linking</a></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">37.1.4 Using your module</a></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">37.1.5 Compilation of C++ extensions</a></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++ -fPIC -c example.cxx
|
|
% g++ -fPIC -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 -KPIC -c example.cxx
|
|
% CC -KPIC -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">37.1.6 Compiling for 64-bit platforms</a></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">37.1.7 Setting a package prefix</a></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">37.1.8 Using namespaces</a></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">37.2 Building Tcl/Tk Extensions under Windows
|
|
95/NT</a></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">37.2.1 Running SWIG from Developer Studio</a></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">37.2.2 Using NMAKE</a></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 it's enough to
|
|
get you started. With a little practice, you'll be making lots of Tcl
|
|
extensions.</p>
|
|
<h2><a name="Tcl_nn14">37.3 A tour of basic C/C++ wrapping</a></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">37.3.1 Modules</a></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">37.3.2 Functions</a></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">37.3.3 Global variables</a></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">37.3.4 Constants and enums</a></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>
|
|
<h3><a name="Tcl_nn19">37.3.5 Pointers</a></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">37.3.6 Structures</a></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 as
|
|
shown below. Objects won't get automatically destroyed when the Tcl
|
|
program exits, so if it's important that the C++ destructor is called
|
|
for a class you'll need to make sure that you explicitly do this for
|
|
objects of that class before program exit.</p>
|
|
<p> 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">37.3.7 C++ classes</a></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 [x 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">37.3.8 C++ inheritance</a></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">37.3.9 Pointers, references, values, and arrays</a>
|
|
</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">37.3.10 C++ overloaded functions</a></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 method spam(short) effectively ignored,
|
|
example.i:11: Warning 509: as it is shadowed by spam(int).
|
|
</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">37.3.11 C++ operators</a></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">37.3.12 C++ namespaces</a></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">37.3.13 C++ templates</a></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">37.3.14 C++ Smart Pointers</a></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">37.4 Further details on the Tcl class interface</a>
|
|
</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">37.4.1 Proxy classes</a></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">37.4.2 Memory management</a></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">37.5 Input and output parameters</a></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 *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">37.6 Exception handling</a></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_SetResult(interp, (char *)"Array index out-of-bounds", TCL_STATIC);
|
|
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_SetResult(interp, (char *)"Array index out-of-bounds", TCL_STATIC);
|
|
return TCL_ERROR;
|
|
}
|
|
}
|
|
|
|
%exception setitem {
|
|
try {
|
|
$action
|
|
}
|
|
catch (RangeError) {
|
|
Tcl_SetResult(interp, (char *)"Array index out-of-bounds", TCL_STATIC);
|
|
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_SetResult(interp, (char *)"Array index out-of-bounds", TCL_STATIC);
|
|
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">37.7 Typemaps</a></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">37.7.1 What is a typemap?</a></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">37.7.2 Tcl typemaps</a></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">37.7.3 Typemap variables</a></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">37.7.4 Converting a Tcl list to a char **</a></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_GetString(listobjv[i]);
|
|
}
|
|
$1[i] = 0;
|
|
}
|
|
|
|
// This gives SWIG some cleanup code that will get called after the function call
|
|
%typemap(freearg) char ** {
|
|
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">37.7.5 Returning values in arguments</a></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">37.7.6 Useful functions</a></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);
|
|
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">37.7.7 Standard typemaps</a></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, noblock=1, fragment="SWIG_FromCharPtr") char *, const char * {
|
|
Tcl_SetObjResult(interp, SWIG_FromCharPtr((const char *)$1));
|
|
}
|
|
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Tcl_nn42">37.7.8 Pointer handling</a></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_IsOK(SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
|
|
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_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
}
|
|
</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_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<h2><a name="Tcl_nn43">37.8 Turning a SWIG module into a Tcl Package.</a>
|
|
</h2>
|
|
<p> SWIG generates all of the code necessary to create a Tcl extension
|
|
package. To set the package version 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">37.9 Building new kinds of Tcl interfaces (in
|
|
Tcl)</a></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">37.9.1 Proxy classes</a></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">37.10 Tcl/Tk Stubs</a></h2>
|
|
<p> For background information about the Tcl Stubs feature, see <a href="https://www.tcl.tk/doc/howto/stubs.html">
|
|
https://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>.</p>
|
|
<p> By default SWIG sets the minimum Tcl version to support to the 8.4
|
|
as that's the minimum Tcl version we aim to support (since SWIG 4.1.0;
|
|
before this SWIG set it to 8.1, which was the first Tcl version with
|
|
the stubs mechanism). This minimum version is passed to <tt>
|
|
Tcl_InitStubs()</tt> and <tt>Tk_InitStubs()</tt>. You can override with
|
|
a specific version using <tt>-DSWIG_TCL_STUBS_VERSION="8.5"</tt> or set
|
|
it to the Tcl version being compiled with using <tt>
|
|
-DSWIG_TCL_STUBS_VERSION=TCL_VERSION</tt>.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="C">38 SWIG and C as the target language</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#C_overview">Overview</a>
|
|
<ul>
|
|
<li><a href="#C_shortcomings">Known C++ Shortcomings in Generated C API</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#C_preliminaries">Preliminaries</a>
|
|
<ul>
|
|
<li><a href="#C_running_swig">Running SWIG</a></li>
|
|
<li><a href="#C_commandline">Command line options</a></li>
|
|
<li><a href="#C_dynamic">Compiling a dynamic module</a></li>
|
|
<li><a href="#C_using_module">Using the generated module</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#C_basic_c_wrapping">Basic C wrapping</a>
|
|
<ul>
|
|
<li><a href="#C_functions">Functions</a></li>
|
|
<li><a href="#C_variables">Variables</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#C_basic_cpp_wrapping">Basic C++ wrapping</a>
|
|
<ul>
|
|
<li><a href="#C_enums">Enums</a></li>
|
|
<li><a href="#C_classes">Classes</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#C_developer">Backend Developer Documentation</a></li>
|
|
<li><a href="#C_typemaps">Typemaps</a>
|
|
<ul>
|
|
<li><a href="#C_typemaps_walkthrough">C Typemaps, a Code Generation
|
|
Walkthrough</a>
|
|
<ul>
|
|
<li><a href="#C_walkthrough_interface">The Interface</a></li>
|
|
<li><a href="#C_walkthrough_wrapper">The Wrapper</a></li>
|
|
<li><a href="#C_walkthrough_proxy">The Proxy</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#C_exceptions">Exception handling</a></li>
|
|
<li><a href="#C_cxx_wrappers">C++ Wrappers</a>
|
|
<ul>
|
|
<li><a href="#C_additional_possibilities">Additional customization
|
|
possibilities</a></li>
|
|
<li><a href="#C_exception_handling">Exception handling</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> This chapter describes SWIG's support for creating ISO C wrappers.
|
|
This module has a special purpose and thus is different from most other
|
|
modules.</p>
|
|
<p><b> NOTE:</b> this module is still under development.</p>
|
|
<h2><a name="C_overview">38.1 Overview</a></h2>
|
|
<p> SWIG is normally used to provide access to C or C++ libraries from
|
|
target languages such as scripting languages or languages running on a
|
|
virtual machine. SWIG performs analysis of the input C/C++ library
|
|
header files from which it generates further code. For most target
|
|
languages this code consists of two layers; namely an intermediary C
|
|
code layer and a set of language specific proxy classes and functions
|
|
on top of the C code layer. We could also think of C as just another
|
|
target language supported by SWIG. The aim then is to generate a pure
|
|
ISO C interface to the input C or C++ library and hence the C target
|
|
language module.</p>
|
|
<p> With wrapper interfaces generated by SWIG, it is easy to use the
|
|
functionality of C++ libraries inside application code written in C.
|
|
This module may also be useful to generate custom APIs for a library,
|
|
to suit particular needs, e.g. to supply function calls with error
|
|
checking or to implement a "design by contract".</p>
|
|
<p> Flattening C++ language constructs into a set of C-style functions
|
|
obviously comes with many limitations and inconveniences, but this
|
|
module is actually also capable of generating C++ wrappers defined
|
|
completely inline using the C functions, thus wrapping the original C++
|
|
library API in another, similar C++ API. Contrary to the natural
|
|
initial reaction, this is far from being completely pointless, as
|
|
wrapping C++ API in this way avoids all problems due to C++ ABI issues,
|
|
e.g. it is now possible to use the original C++ API using a different
|
|
C++ compiler, or a different version of the same compiler, or even the
|
|
same compiler, but with different compilation options affecting the
|
|
ABI. The C++ wrapper API is not identical to the original one, but
|
|
strives to be as close to it as possible.</p>
|
|
<h3><a name="C_shortcomings">38.1.1 Known C++ Shortcomings in Generated
|
|
C API</a></h3>
|
|
<ul>
|
|
<li>Enums with a context like class or namespace are broken</li>
|
|
<li>Global variables are not supported</li>
|
|
<li>Qualifiers are stripped</li>
|
|
<li>Vararg functions are not supported.</li>
|
|
</ul>
|
|
<h2><a name="C_preliminaries">38.2 Preliminaries</a></h2>
|
|
<h3><a name="C_running_swig">38.2.1 Running SWIG</a></h3>
|
|
<p> Consider the following simple example. Suppose we have an interface
|
|
file like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File: example.i */
|
|
%module test
|
|
%{
|
|
#include "stuff.h"
|
|
%}
|
|
int fact(int n);
|
|
</pre>
|
|
</div>
|
|
<p> To build a C module (C as the target language), run SWIG using the <tt>
|
|
-c</tt> option :</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c example.i
|
|
</pre>
|
|
</div>
|
|
<p> The above assumes C as the input language. If the input language is
|
|
C++ add the <tt>-c++</tt> option:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c++ -c example.i
|
|
</pre>
|
|
</div>
|
|
<p> Note that <tt>-c</tt> is the option specifying the<b> target</b>
|
|
language and <tt>-c++</tt> controls what the<b> input</b> language is.</p>
|
|
<p> This will generate an <tt>example_wrap.c</tt> file or, in the latter
|
|
case, <tt>example_wrap.cxx</tt> file, along with <tt>example_wrap.h</tt>
|
|
(the same extension is used in both C and C++ cases for the last one).
|
|
The names of the files are derived from the name of the input file by
|
|
default, but can be changed using the <tt>-o</tt> and <tt>-oh</tt>
|
|
options common to all language modules.</p>
|
|
<p> The <tt>xxx_wrap.c</tt> file contains the wrapper functions, which
|
|
perform the main functionality of SWIG: each of the wrappers translates
|
|
the input arguments from C to C++, makes calls to the original
|
|
functions and marshals C++ output back to C data. The <tt>xxx_wrap.h</tt>
|
|
header file contains the declarations of these functions as well as
|
|
global variables.</p>
|
|
<h3><a name="C_commandline">38.2.2 Command line options</a></h3>
|
|
<p> The following table list the additional command line options
|
|
available for the C module. They can also be seen by using:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c -help
|
|
</pre>
|
|
</div>
|
|
<table summary="C specific options">
|
|
<tr><th>C specific options</th></tr>
|
|
<tr><td>-namespace <nspace></td><td>Generate wrappers with the prefix
|
|
based on the provided namespace, e.g. if the option value is <tt>
|
|
outer::inner</tt>, the prefix <tt>outer_inner_</tt> will be used. Notice
|
|
that this is different from using SWIG <tt>nspace</tt> feature, as it
|
|
applies the prefix to all the symbols, regardless of the namespace they
|
|
were actually declared in. Notably, this provides a way to export
|
|
instantiations of templates defined in the <tt>std</tt> namespace, such
|
|
as <tt>std::vector</tt>, using a custom prefix rather than <tt>std_</tt>
|
|
.</td></tr>
|
|
<tr><td>-nocxx</td><td>Don't generate C++ wrappers, even when the <tt>
|
|
-c++</tt> option is used. See <a href="#C_cxx_wrappers">C++ Wrappers</a>
|
|
section for more details.</td></tr>
|
|
<tr><td>-noexcept</td><td>generate wrappers with no support for
|
|
exception handling; see <a href="#C_exceptions">Exceptions</a> chapter
|
|
for more details</td></tr>
|
|
</table>
|
|
<h3><a name="C_dynamic">38.2.3 Compiling a dynamic module</a></h3>
|
|
<p> The next step is to build a dynamically loadable module, which we
|
|
can link to our application. For example, to do this using the <tt>gcc</tt>
|
|
compiler (Linux, MinGW, etc.):</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c example.i
|
|
$ gcc -fPIC -c example_wrap.c
|
|
$ gcc -shared example_wrap.o -o libexample.so
|
|
</pre>
|
|
</div>
|
|
<p> Or, for C++ input:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c++ -c example.i
|
|
$ g++ -fPIC -c example_wrap.cxx
|
|
$ g++ -shared example_wrap.o -o libexample.so
|
|
</pre>
|
|
</div>
|
|
<p> Now the shared library module is ready to use. Note that the name of
|
|
the generated module is important: is should be prefixed with <tt>lib</tt>
|
|
on Unix, and have the specific extension, like <tt>.dll</tt> for
|
|
Windows or <tt>.so</tt> for Unix systems.</p>
|
|
<h3><a name="C_using_module">38.2.4 Using the generated module</a></h3>
|
|
<p> The simplest way to use the generated shared module is to link it to
|
|
the application code during the compilation stage. The process is
|
|
usually similar to this:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ gcc runme.c -L. -lexample -o runme
|
|
</pre>
|
|
</div>
|
|
<p> This will compile the application code (<tt>runme.c</tt>) and link
|
|
it against the generated shared module. Following the <tt>-L</tt>
|
|
option is the path to the directory containing the shared module. The
|
|
output executable is ready to use. The last thing to do is to supply to
|
|
the operating system the information of location of our module. This is
|
|
system dependant, for instance Unix systems look for shared modules in
|
|
certain directories, like <tt>/usr/lib</tt>, and additionally we can
|
|
set the environment variable <tt>LD_LIBRARY_PATH</tt> (Unix) or <tt>
|
|
PATH</tt> (Windows) for other directories.</p>
|
|
<h2><a name="C_basic_c_wrapping">38.3 Basic C wrapping</a></h2>
|
|
<p> Wrapping C functions and variables is obviously performed in a
|
|
straightforward way. There is no need to perform type conversions, and
|
|
all language constructs can be preserved in their original form.
|
|
However, SWIG allows you to enhance the code with some additional
|
|
elements, for instance using a <tt>check</tt> typemap or <tt>%extend</tt>
|
|
directive.</p>
|
|
<p> It is also possible to output arbitrary additional code into the
|
|
generated header by using the <tt>%insert</tt> directive with <tt>
|
|
cheader</tt> section, e.g.</p>
|
|
<div class="code">
|
|
<pre>
|
|
%insert("cheader") %{
|
|
#include "another.h"
|
|
%}
|
|
</pre>
|
|
</div>
|
|
<h3><a name="C_functions">38.3.1 Functions</a></h3>
|
|
<p> For each C function declared in the interface file a wrapper
|
|
function with a prefix, required to make its name different from the
|
|
original one, is created. The prefix for the global functions is <tt>
|
|
module_</tt>, i.e. the name of the SWIG module followed by underscore,
|
|
by default. If <tt>-namespace</tt> option is used, the prefix
|
|
corresponding to the given fixed namespace is used instead. If <tt>
|
|
nspace</tt> feature is used, the prefix corresponding to the namespace
|
|
in which the function is defined is used -- note that, unlike with <tt>
|
|
-namespace</tt> option, this prefix can be different for different
|
|
functions. The wrapper function performs a call to the original
|
|
function, and returns its result.</p>
|
|
<p> For example, for function declaration in the module <tt>mymath</tt>:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
int gcd(int x, int y);
|
|
</pre>
|
|
</div>
|
|
<p> The output is simply:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
int mymath_gcd(int arg1, int arg2) {
|
|
int result;
|
|
result = gcd(arg1,arg2);
|
|
return result;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Now one might think, what's the use of creating such functions in C?
|
|
The answer is, you can apply special rules to the generated code. Take
|
|
for example constraint checking. You can write a "check" typemap in
|
|
your interface file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(check) int POSITIVE {
|
|
if ($1 <= 0)
|
|
fprintf(stderr, "Expected positive value for parameter $1 in $name.\n");
|
|
}
|
|
|
|
int gcd(int POSITIVE, int POSITIVE);
|
|
</pre>
|
|
</div>
|
|
<p> And now the generated result looks like:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
int _wrap_gcd(int arg1, int arg2) {
|
|
int result;
|
|
{
|
|
if (arg1 <= 0)
|
|
fprintf(stderr, "Expected positive value for parameter arg1 in gcd.\n");
|
|
}
|
|
{
|
|
if (arg2 <= 0)
|
|
fprintf(stderr, "Expected positive value for parameter arg2 in gcd.\n");
|
|
}
|
|
result = gcd(arg1,arg2);
|
|
return result;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> This time calling <tt>gcd</tt> with negative value argument will
|
|
trigger an error message. This can save you time writing all the
|
|
constraint checking code by hand.</p>
|
|
<h3><a name="C_variables">38.3.2 Variables</a></h3>
|
|
<p> Wrapping variables comes also without any special issues. All global
|
|
variables are directly accessible from application code. There is a
|
|
difference in the semantics of <tt>struct</tt> definition in C and C++.
|
|
When handling C <tt>struct</tt>, SWIG simply rewrites its declaration.
|
|
In C++ <tt>struct</tt> is handled as class declaration.</p>
|
|
<p> You can still apply some of the SWIG features when handling structs,
|
|
e.g. <tt>%extend</tt> directive. Suppose, you have a C struct
|
|
declaration:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
typedef struct {
|
|
int x;
|
|
char *str;
|
|
} my_struct;
|
|
</pre>
|
|
</div>
|
|
<p> You can redefine it to have an additional fields, like:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%extend my_struct {
|
|
double d;
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> In application code:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
struct my_struct ms;
|
|
ms.x = 123;
|
|
ms.d = 123.123;
|
|
</pre>
|
|
</div>
|
|
<h2><a name="C_basic_cpp_wrapping">38.4 Basic C++ wrapping</a></h2>
|
|
<p> The main reason of having the C module in SWIG is to be able to
|
|
access C++ from C. In this chapter we will take a look at the rules of
|
|
wrapping elements of the C++ language.</p>
|
|
<p> By default, SWIG attempts to build a natural C interface to your
|
|
C/C++ code.</p>
|
|
<table BORDER summary="Generated C representation of C++">
|
|
<tr><th>C++ Type</th><th>SWIG C Translation</th></tr>
|
|
<tr><td>Class <tt>Example</tt></td><td>Empty structure <tt>Example</tt></td>
|
|
</tr>
|
|
<tr><td>Public, mutable member variable <tt>Foo Example::foo</tt></td><td>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Example_foo_get(Example *e);
|
|
Example_foo_set(Example *e, Foo *f);
|
|
</pre>
|
|
</div></td></tr>
|
|
<tr><td>Public, immutable member variable <tt>Foo Example::bar</tt></td><td>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Example_foo_get(Example *e);
|
|
</pre>
|
|
</div></td></tr>
|
|
</table>
|
|
<p> This section briefly covers the essential aspects of this wrapping.</p>
|
|
<h3><a name="C_enums">38.4.1 Enums</a></h3>
|
|
<p> C enums and unscoped C++ enums are simply copied to the generated
|
|
code and both the enum itself and its elements keep the same name as in
|
|
the original code unless <tt>-namespace</tt> option is used or <tt>
|
|
nspace</tt> feature is enabled, in which case the prefix corresponding
|
|
to the specified namespace is used.</p>
|
|
<p> For scoped C++11 enums, the enum name itself is used as an
|
|
additional prefix.</p>
|
|
<h3><a name="C_classes">38.4.2 Classes</a></h3>
|
|
<p> Consider the following example. We have a C++ class, and want to use
|
|
it from C code.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
class Circle {
|
|
public:
|
|
double radius;
|
|
|
|
Circle(double r) : radius(r) { };
|
|
double area(void);
|
|
};
|
|
</pre>
|
|
</div>
|
|
<p> What we need to do is to create an object of the class, manipulate
|
|
it, and finally, destroy it. SWIG generates C functions for this
|
|
purpose each time a class declaration is encountered in the interface
|
|
file.</p>
|
|
<p> The first two generated functions are used to create and destroy
|
|
instances of class <tt>Circle</tt>. Such instances are represented on
|
|
the C side as pointers to special structs, called <tt>SwigObj</tt>.
|
|
They are all "renamed" (via typedef) to the original class names, so
|
|
that you can use the object instances on the C side using pointers
|
|
like:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Circle *circle;
|
|
</pre>
|
|
</div>
|
|
<p> The generated functions make calls to class' constructors and
|
|
destructors, respectively. They also do all the necessary things
|
|
required by the SWIG object management system in C.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Circle * Circle_new(double r);
|
|
void Circle_delete(Circle * self);
|
|
</pre>
|
|
</div>
|
|
<p> The class <tt>Circle</tt> has a public variable called <tt>radius</tt>
|
|
. SWIG generates a pair of setters and getters for each such variable:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
void Circle_radius_set(Circle * self, double radius);
|
|
double Circle_radius_get(Circle * self);
|
|
</pre>
|
|
</div>
|
|
<p> For each public method, an appropriate function is generated:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
double Circle_area(Circle * self);
|
|
</pre>
|
|
</div>
|
|
<p> You can see that in order to use the generated object we need to
|
|
provide a pointer to the object instance (struct <tt>Circle</tt> in
|
|
this case) as the first function argument. In fact, this struct is
|
|
basically wrapping pointer to the "real" C++ object.</p>
|
|
<p> Our application code could look like this:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
Circle *c = Circle_new(1.5);
|
|
printf("radius: %f\narea: %f\n", Circle_radius_get(c), Circle_area(c));
|
|
Circle_delete(c);
|
|
</pre>
|
|
</div>
|
|
<p> After running this we'll get:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
radius: 1.500000
|
|
area: 7.068583
|
|
</pre>
|
|
</div>
|
|
<h2><a name="C_developer">38.5 Backend Developer Documentation</a></h2>
|
|
<h2><a name="C_typemaps">38.6 Typemaps</a></h2>
|
|
<table BORDER summary="C Backend Typemaps">
|
|
<tr><th>Typemap</th><th>Used for</th></tr>
|
|
<tr><td><tt>ctype</tt></td><td>Provides types used for the C API and
|
|
<br> Typecasts wrapper functions return values in proxy functions<div class="targetlang">
|
|
<pre>
|
|
MyClass *MyClass_new(void) {
|
|
return (MyClass *)MyClass_new();
|
|
}
|
|
</pre>
|
|
</div></td></tr>
|
|
<tr><td><tt>in</tt></td><td>Mapping of wrapper functions parameters to
|
|
local C++ variables<div class="targetlang">
|
|
<pre>
|
|
SwigObj* MyClass_do(SwigObj *carg1) {
|
|
SomeCPPClass *arg1 = 0;
|
|
if (carg1)
|
|
arg1 = (SomeCPPClass*)carg1->obj
|
|
else
|
|
arg1 = 0;
|
|
}
|
|
</pre>
|
|
</div></td></tr>
|
|
<tr><td><tt>out</tt></td><td>Assigns wrapped function's return value to
|
|
a dedicated return variable, packaging it into SwigObj if necessary</td>
|
|
</tr>
|
|
<tr><td><tt>cppouttype</tt></td><td>Type of the result variable used for
|
|
the return value if the wrapped function is a C++ function</td></tr>
|
|
<tr><td><tt>cxxintype</tt></td><td>Defines the type for the parameters
|
|
of C++ wrapper functions corresponding to this type. By default is the
|
|
same as <tt>ctype</tt>, but may sometimes be different to make the
|
|
functions more convenient to use. For example, <tt>ctype</tt> for <tt>
|
|
std::string</tt> is <tt>const char*</tt>, but <tt>cxxintype</tt> typemap
|
|
for it is <tt>std::string const&</tt>, i.e. even though the C++ string
|
|
passed as a raw pointer via C API, the C++ wrapper still accepts a C++
|
|
string. If this typemap is defined, <tt>cxxin</tt> should normally be
|
|
defined as well. If it is not defined, <tt>ctype</tt> is used.</td></tr>
|
|
<tr><td><tt>cxxouttype</tt></td><td>Similar to <tt>cxxintype</tt>, but
|
|
is used for the function return values and together with <tt>cxxout</tt>
|
|
typemap. Also defaults to <tt>ctype</tt> if not defined.</td></tr>
|
|
<tr><td><tt>cxxin</tt></td><td>Defines how to transform <tt>cxxintype</tt>
|
|
value to <tt>ctype</tt></td></tr>
|
|
<tr><td><tt>cxxout</tt></td><td>Defines how to transform <tt>ctype</tt>
|
|
value returned by a function to <tt>cxxouttype</tt></td></tr>
|
|
<tr><td><tt>cxxcode</tt></td><td>May contain arbitrary code that will be
|
|
injected in the declaration of the C++ wrapper class corresponding to
|
|
the given type. Ignored for non-class types. The special variable <tt>
|
|
$cxxclassname</tt> is replaced with the name of the class inside this
|
|
typemap expansion and <tt>$cclassptrname</tt> is replaced with the name
|
|
of the pointer type used to represent the class in C wrapper functions.</td>
|
|
</tr>
|
|
</table>
|
|
<h3><a name="C_typemaps_walkthrough">38.6.1 C Typemaps, a Code
|
|
Generation Walkthrough</a></h3>
|
|
<p> To get a better idea of which typemap is used for which generated
|
|
code, have a look at the following 'walk through'.</p>
|
|
<p> Let's assume we have the following C++ interface file, we'd like to
|
|
generate code for:</p>
|
|
<h4><a name="C_walkthrough_interface">38.6.1.1 The Interface</a></h4>
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
%inline
|
|
%{
|
|
class SomeClass{};
|
|
template <typename T> class SomeTemplateClass{};
|
|
SomeClass someFunction(SomeTemplateClass<int> &someParameter, int simpleInt);
|
|
%}
|
|
|
|
%template (SomeIntTemplateClass) SomeTemplateClass<int>;
|
|
</pre>
|
|
</div>
|
|
<p> What we would like to generate as a C interface of this function
|
|
would be something like this:</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
// wrapper header file
|
|
typedef struct SwigObj_SomeClass SomeClass;
|
|
|
|
SomeClass * SomeClass_new();
|
|
|
|
void SomeClass_delete(SomeClass * carg1);
|
|
|
|
SomeClass* someFunction(SomeIntTemplateClass* carg1, int carg2);
|
|
|
|
|
|
typedef struct SwigObj_SomeIntTemplateClass SomeIntTemplateClass;
|
|
|
|
SomeIntTemplateClass * SomeIntTemplateClass_new();
|
|
|
|
void SomeIntTemplateClass_delete(SomeIntTemplateClass * carg1);
|
|
</pre>
|
|
</div>
|
|
<h4><a name="C_walkthrough_wrapper">38.6.1.2 The Wrapper</a></h4>
|
|
<p> We'll examine the generation of the wrapper function first.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
SWIGEXPORTC SwigObj * module_someFunction(SwigObj * carg1, int carg2) {
|
|
SomeClass * cppresult;
|
|
SomeTemplateClass< int > *arg1 = 0 ;
|
|
int arg2 ;
|
|
SwigObj * result;
|
|
|
|
{
|
|
if (carg1)
|
|
arg1 = (SomeTemplateClass< int > *) carg1->obj;
|
|
else
|
|
arg1 = (SomeTemplateClass< int > *) 0;
|
|
}
|
|
arg2 = (int) carg2;
|
|
{
|
|
const SomeClass &_result_ref = someFunction(*arg1,arg2);cppresult = (SomeClass*) &_result_ref;
|
|
}
|
|
{
|
|
result = SWIG_create_object(cppresult, SWIG_STR(SomeClass));
|
|
}
|
|
return result;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> It might be helpful to think of the way function calls are generated
|
|
as a composition of building blocks. A typical wrapper will be
|
|
composited with these [optional] blocks:</p>
|
|
<ol>
|
|
<li>Prototype</li>
|
|
<li>C return value variable</li>
|
|
<li>Local variables equal to the called C++ function's parameters</li>
|
|
<li>[C++ return value variable]</li>
|
|
<li>Assignment (extraction) of wrapper parameters to local parameter
|
|
copies</li>
|
|
<li>[Contract (e.g. constraints) checking]</li>
|
|
<li> C++ function call</li>
|
|
<li>[Exception handling]</li>
|
|
<li>[Assignment to C++ return value]</li>
|
|
<li>Assignment to C return value</li>
|
|
</ol>
|
|
<p> Let's go through it step by step and start with the wrapper
|
|
prototype</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
ctype ctype ctype
|
|
--------- --------- ---
|
|
SwigObj * module_someFunction(SwigObj * carg1, int carg2);
|
|
</pre>
|
|
</div>
|
|
<p> As first unit of the wrapper code, a variable to hold the return
|
|
value of the function is emitted to the wrapper's body</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
ctype
|
|
---------
|
|
SwigObj * result;
|
|
</pre>
|
|
</div>
|
|
<p> Now for each of the C++ function's arguments, a local variable with
|
|
the very same type is emitted to the wrapper's body.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
SomeTemplateClass< int > *arg1 = 0 ;
|
|
int arg2 ;
|
|
</pre>
|
|
</div>
|
|
<p> If it's a C++ function that is wrapped (in this case it is), another
|
|
variable is emitted for the 'original' return value of the C++
|
|
function. At this point, we simply 'inject' behavior if it's a C++
|
|
function that is wrapped (in this case it obviously is).</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
cppouttype
|
|
-----------
|
|
SomeClass * cppresult;
|
|
</pre>
|
|
</div>
|
|
<p> Next, the values of the input parameters are assigned to the local
|
|
variables using the 'in' typemap.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
{
|
|
if (carg1)
|
|
arg1 = (SomeTemplateClass< int > *) carg1->obj;
|
|
else
|
|
arg1 = (SomeTemplateClass< int > *) 0;
|
|
}
|
|
arg2 = (int) carg2;
|
|
</pre>
|
|
</div>
|
|
<p> A reasonable question would be: "Why aren't the parameters assigned
|
|
in the declaration of their local counterparts?" As seen above, for
|
|
complex types pointers have to be verified before extracting and
|
|
casting the actual data pointer from the provided SwigObj pointer. This
|
|
could easily become messy if it was done in the same line with the
|
|
local variable declaration.</p>
|
|
<p> At this point we are ready to call the C++ function with our
|
|
parameters.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
{
|
|
const SomeClass &_result_ref = someFunction(*arg1,arg2);cppresult = (SomeClass*) &_result_ref;
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Subsequently, the return value is assigned to the dedicated return
|
|
value variable using the 'out' typemap</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
{
|
|
result = SWIG_create_object(cppresult, SWIG_STR(SomeClass));
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> Finally, the return value variable is returned.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
return result;
|
|
</pre>
|
|
</div>
|
|
<p> Note that typemaps may use <tt>$null</tt> special variable which
|
|
will be replaced with either <tt>0</tt> or nothing, depending on
|
|
whether the function has a non-void return value or not.</p>
|
|
<h4><a name="C_walkthrough_proxy">38.6.1.3 The Proxy</a></h4>
|
|
<p> Compared to the wrapper code generation, the header code is very
|
|
simple. Basically it contains just the declarations corresponding to
|
|
the definitions above.</p>
|
|
<div class="targetlang">
|
|
<pre>
|
|
// wrapper header file
|
|
typedef struct SwigObj_SomeClass SomeClass;
|
|
|
|
SomeClass * SomeClass_new();
|
|
|
|
void SomeClass_delete(SomeClass * carg1);
|
|
|
|
SomeClass* someFunction(SomeIntTemplateClass* carg1, int carg2);
|
|
|
|
|
|
typedef struct SwigObj_SomeIntTemplateClass SomeIntTemplateClass;
|
|
|
|
SomeIntTemplateClass * SomeIntTemplateClass_new();
|
|
|
|
void SomeIntTemplateClass_delete(SomeIntTemplateClass * carg1);
|
|
</pre>
|
|
</div>
|
|
<h2><a name="C_exceptions">38.7 Exception handling</a></h2>
|
|
<p> Any call to a C++ function may throw an exception, which cannot be
|
|
caught by C code. Instead, the special <tt>
|
|
SWIG_CException_get_pending()</tt> function must be called to check for
|
|
this. If it returns a non-null pointer, <tt>SWIG_CException_msg_get()</tt>
|
|
can be called to retrieve the error message associated with the
|
|
exception. Finally, <tt>SWIG_CException_reset_pending()</tt> must be
|
|
called to free the exception object and reset the current pending
|
|
exception. Note that exception handling is much simpler when using C++,
|
|
rather than C, wrappers, see sections 36.6.2.</p>
|
|
<h2><a name="C_cxx_wrappers">38.8 C++ Wrappers</a></h2>
|
|
<p> When <tt>-c++</tt> command line option is used (and <tt>-nocxx</tt>
|
|
one is not), the header file generated by SWIG will also contain the
|
|
declarations of C++ wrapper functions and classes mirroring the
|
|
original API. All C++ wrappers are fully inline, i.e. don't need to be
|
|
compiled separately, and are always defined inside the namespace (or
|
|
nested namespaces) specified by <tt>-namespace</tt> command-line option
|
|
or the namespace with the same name as the SWIG module name if this
|
|
option is not specified.</p>
|
|
<p> C++ wrappers try to provide a similar API to the original C++ API
|
|
being wrapped, notably any class <tt>Foo</tt> in the original API
|
|
appears as a class with the same name in the wrappers namespace, and
|
|
has the same, or similar, public methods. A class <tt>Bar</tt> deriving
|
|
from <tt>Foo</tt> also derives from it in the wrappers and so on. There
|
|
are some differences with the original API, however. Some of them are
|
|
due to fundamental limitations of the approach used, e.g.:</p>
|
|
<ul>
|
|
<li>Only template instantiations are present in the wrappers, not the
|
|
templates themselves.</li>
|
|
</ul>
|
|
<p> Other ones are due to things that could be supported but haven't
|
|
been implemented yet:</p>
|
|
<ul>
|
|
<li>Only single, not multiple, inheritance is currently supported.</li>
|
|
<li>Only enums using <tt>int</tt> (or smaller type) as underlying type
|
|
are supported.</li>
|
|
</ul>
|
|
<h3><a name="C_additional_possibilities">38.8.1 Additional customization
|
|
possibilities</a></h3>
|
|
<p> Generated C++ code can be customized by inserting custom code in the
|
|
following sections:</p>
|
|
<ul>
|
|
<li><tt>cxxheader</tt> for including additional headers and other
|
|
declarations in the global scope.</li>
|
|
<li><tt>cxxcode</tt> for additional code to appear after the
|
|
declarations of all wrapper classes, inside the module-specific
|
|
namespace.</li>
|
|
</ul>
|
|
<p> The following features are taken into account when generating C++
|
|
wrappers:</p>
|
|
<ul>
|
|
<li><tt>cxxignore</tt> May be set to skip generation of C++ wrappers for
|
|
the given function or class, while still generating C wrappers for
|
|
them.</li>
|
|
</ul>
|
|
<h3><a name="C_exception_handling">38.8.2 Exception handling</a></h3>
|
|
<p> Exception handling in C++ is more natural, as the exceptions are
|
|
re-thrown when using C++ wrappers and so can be caught, as objects of
|
|
the special <tt>SWIG_CException</tt> type, using the usual <tt>
|
|
try/catch</tt> statement. The objects of <tt>SWIG_CException</tt> class
|
|
have <tt>code()</tt> and <tt>msg()</tt> methods, with the latter
|
|
returning the error message associated with the exception.</p>
|
|
<p> If necessary, a custom exception type may be used instead of <tt>
|
|
SWIG_CException</tt>. To do this, a custom implementation of <tt>
|
|
swig_check()</tt> function, called to check for the pending exception
|
|
and throw the corresponding C++ exception if necessary, must be
|
|
provided and <tt>SWIG_swig_check_DEFINED</tt> preprocessor symbol must
|
|
be defined to prevent the default implementation of this function from
|
|
being compiled:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%insert(cxxheader) %{
|
|
#ifndef SWIG_swig_check_DEFINED
|
|
#define SWIG_swig_check_DEFINED 1
|
|
|
|
#include <stdexcept>
|
|
|
|
class Exception : public std::runtime_error {
|
|
public:
|
|
explicit Exception(const char* msg) : std::runtime_error{msg} {}
|
|
};
|
|
|
|
inline void swig_check() {
|
|
if (auto* swig_ex = SWIG_CException_get_pending()) {
|
|
Exception const e{SWIG_CException_msg_get(swig_ex)};
|
|
SWIG_CException_reset_pending();
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
template <typename T> T swig_check(T x) {
|
|
swig_check();
|
|
return x;
|
|
}
|
|
|
|
#endif // SWIG_swig_check_DEFINED
|
|
%}
|
|
</pre>
|
|
</div><HR NOSHADE>
|
|
<h1><a name="Mzscheme">39 SWIG and MzScheme/Racket</a></h1>
|
|
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#MzScheme_nn2">Creating native structures</a></li>
|
|
<li><a href="#MzScheme_simple">Simple example</a></li>
|
|
<li><a href="#MzScheme_external_docs">External documentation</a></li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> This section contains information on SWIG's support of Racket,
|
|
formally known as MzScheme. SWIG works with Racket versions < 8 (Racket
|
|
8 switched to be based on a different scheme interpreter and SWIG
|
|
hasn't been updated for this change).</p>
|
|
<h2><a name="MzScheme_nn2">39.1 Creating native structures</a></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>
|
|
<h2><a name="MzScheme_simple">39.2 Simple example</a></h2>
|
|
<p> A few examples are available in the Examples/mzscheme directory. The
|
|
code and log of a session using SWIG below should help getting started.</p>
|
|
<p> C header file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
// example.h
|
|
int fact(int n);
|
|
</pre>
|
|
</div>
|
|
<p> C source code:</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> SWIG interface file:</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* File: example.i */
|
|
%module example
|
|
|
|
%{
|
|
#include "example.h"
|
|
%}
|
|
|
|
int fact(int n);
|
|
</pre>
|
|
</div>
|
|
<p> The session below using the above files is on an OS X machine, but
|
|
the points to be made are more general. On OS X, libtool is the tool
|
|
which creates libraries, which are named .dylib, rather than .so on
|
|
other unixes, or .dll on Windows.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
% swig -mzscheme -declaremodule example.i
|
|
% gcc -c -m32 -o example.o example.c # force 32-bit object file (mzscheme is 32-bit only)
|
|
% libtool -dynamic -o libexample.dylib example.o # make it into a library
|
|
% ls # what've we got so far?
|
|
example.c example.o
|
|
example.h example_wrap.c
|
|
example.i libexample.dylib*
|
|
% mzc --cgc --cc example_wrap.c # compile the wrapping code
|
|
% LDFLAGS="-L. -lexample" mzc --ld example_wrap.dylib example_wrap.o # ...and link it
|
|
% mzscheme -e '(path->string (build-path "compiled" "native" (system-library-subpath)))'
|
|
"compiled/native/i386-macosx/3m"
|
|
% mkdir -p compiled/native/i386-macosx/3m # move the extension library to a magic place
|
|
% mv example_wrap.dylib compiled/native/i386-macosx/3m/example_ss.dylib
|
|
% mzscheme
|
|
Welcome to MzScheme v4.2.4 [3m], Copyright (c) 2004-2010 PLT Scheme Inc.
|
|
> (require "example.ss")
|
|
> (fact 5)
|
|
120
|
|
> ^D
|
|
% echo 'It works!'
|
|
</pre>
|
|
</div>
|
|
<p> Some points of interest:</p>
|
|
<ul>
|
|
<li> This is on a 64-bit machine, so we have to include the -m32 option
|
|
when building the object file</li>
|
|
<li> If you want to declare a scheme module (and you probably do), it's
|
|
important that you include the -declaremodule option to swig (if you
|
|
miss this out, it'll appear to work, but fail later).</li>
|
|
<li> Use mzc to compile and then link the wrapped code. You'll probably
|
|
need to adjust the link flags to refer to the library you're wrapping
|
|
(you can either do this with an LDFLAGS declaration, as here, or with
|
|
multiple ++ldf options to mzc).</li>
|
|
<li> Create the directory with path (build-path "compiled" "native"
|
|
(system-library-subpath)) and move the freshly-generated .dylib to
|
|
there, changing its name to module-name_ss.dylib. After that, you can
|
|
REQUIRE the new module with (require "module-name.ss").</li>
|
|
<li> The above requests mzc to create an extension using the CGC
|
|
garbage-collector. The alternative -- the 3m collector -- has generally
|
|
better performance, but work is still required for SWIG to emit code
|
|
which is compatible with it.</li>
|
|
</ul>
|
|
<h2><a name="MzScheme_external_docs">39.3 External documentation</a></h2>
|
|
<p> See the <a href="https://docs.racket-lang.org/inside/index.html">C
|
|
API</a> for more description of using the mechanism for adding
|
|
extensions. The main documentation is <a href="https://docs.racket-lang.org/">
|
|
here</a>.</p>
|
|
<p> Tip: mzc's --vv option is very useful for debugging the inevitable
|
|
library problems you'll encounter.</p>
|
|
<HR NOSHADE>
|
|
<h1><a name="Ocaml">40 SWIG and OCaml</a></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, directorin,
|
|
directorout, directorargout</a></li>
|
|
<li><a href="#Ocaml_nn28">directorin typemap</a></li>
|
|
<li><a href="#Ocaml_nn29">directorout typemap</a></li>
|
|
<li><a href="#Ocaml_nn30">directorargout typemap</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Ocaml_nn31">Exceptions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Ocaml_nn32">Documentation Features</a>
|
|
<ul>
|
|
<li><a href="#Ocaml_nn33">Module docstring</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<p> This chapter describes SWIG's support of Ocaml.</p>
|
|
<p> Ocaml was the second compiled, typed language to be added to SWIG.
|
|
Ocaml has 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="https://ocaml.org/">The Ocaml Website</a>.</p>
|
|
<h2><a name="Ocaml_nn2">40.1 Preliminaries</a></h2>
|
|
<p> SWIG is known to be compatible with OCaml 4.13.1 and above - older
|
|
versions are not regularly tested. 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://download.camlcity.org/download/">
|
|
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">40.1.1 Running SWIG</a></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">40.1.2 Compiling the code</a></h3>
|
|
<p> The OCaml 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
|
|
% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c
|
|
% ...
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Ocaml_nn5">40.1.3 The camlp4 module</a></h3>
|
|
<p> The camlp4 module (swigp4.ml -> swigp4.cmo) contains a simple
|
|
rewriter which makes C++ code blend more seamlessly with objective caml
|
|
code. Its 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.
|
|
<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>
|
|
</th></tr>
|
|
</table>
|
|
<h3><a name="Ocaml_nn6">40.1.4 Using your module</a></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">40.1.5 Compilation problems and compiling with
|
|
C++</a></h3>
|
|
<p> Ocaml's C extension API unfortunately defines a <tt>value</tt>
|
|
typedef - this overly-generic name can collide with the C or C++ API
|
|
being wrapped if it defines a variable, function, member or type also
|
|
called <tt>value</tt>. Prior to SWIG 4.2.1, SWIG attempted to work
|
|
around this but the hack used itself caused problems so we've removed
|
|
it. The problem is not one SWIG created, nor one SWIG can really solve.</p>
|
|
<p> As mentioned earlier, C++ 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">40.2 The low-level Ocaml/C interface</a></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.</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.</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 its
|
|
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">40.2.1 The generated module</a></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">40.2.2 Enums</a></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">40.2.2.1 Enum typing in Ocaml</a></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">40.2.3 Arrays</a></h3>
|
|
<h4><a name="Ocaml_nn13">40.2.3.1 Simple types of bounded arrays</a></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">40.2.3.2 Complex and unbounded arrays</a></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">40.2.3.3 Using an object</a></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">40.2.3.4 Example typemap for a function taking
|
|
float * and int</a></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">40.2.4 C++ Classes</a></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">40.2.4.1 STL vector and string Example</a></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$ ./runme_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">40.2.4.2 C++ Class Example</a></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 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">40.2.4.3 Compiling the example</a></h4>
|
|
<div class="code">
|
|
<pre>
|
|
$ QTPATH=/your/qt/path
|
|
$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
|
|
$ ocamlc -c swig.mli ; ocamlc -c swig.ml
|
|
$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
|
|
$ swig -ocaml -c++ -o qt_wrap.c qt.i
|
|
$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
|
|
$ ocamlc -c qt.mli
|
|
$ ocamlc -c qt.ml
|
|
$ 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">40.2.4.4 Sample Session</a></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">40.2.5 Director Classes</a></h3>
|
|
<h4><a name="Ocaml_nn23">40.2.5.1 Director Introduction</a></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">40.2.5.2 Overriding Methods in Ocaml</a></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">40.2.5.3 Director Usage Example</a></h4>
|
|
<table bgcolor="#dddddd" border="1" summary="Director usage example">
|
|
<tr><th>
|
|
<center>runme.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.6)))
|
|
'() ;;
|
|
|
|
let _ = _draw_shape_coverage '(triangle, 60, 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">40.2.5.4 Creating director objects</a></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">40.2.5.5 Typemaps for directors, directorin,
|
|
directorout, directorargout</a></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">40.2.5.6 directorin typemap</a></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">40.2.5.7 directorout typemap</a></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">40.2.5.8 directorargout typemap</a></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">40.2.6 Exceptions</a></h3>
|
|
<p> If an error occurs in a C or C++ function, you may want to convert
|
|
that error into an OCaml 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="#Customization_exception">
|
|
Exception handling with %exception</a> section.</p>
|
|
<p> In C, a function often indicates an error by returning a status code
|
|
(e.g. a negative number or a NULL pointer). Here is a simple example of
|
|
how you might handle that:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%exception malloc {
|
|
$action
|
|
if (result == NULL) {
|
|
caml_failwith("Not enough memory");
|
|
}
|
|
}
|
|
void *malloc(size_t nbytes);
|
|
</pre>
|
|
</div>
|
|
<p> In OCaml:</p>
|
|
<div class="code">
|
|
<pre>
|
|
# let a = _malloc (C_int 20000000000);;
|
|
Exception: Failure "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()) {
|
|
caml_failwith(err_message());
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
<p> If no declaration name is given to <tt>%exception</tt>, it is
|
|
applied to all wrapper functions. <tt>$action</tt> is a SWIG special
|
|
variable and is replaced by the C/C++ function call being wrapped.</p>
|
|
<p> C++ exceptions are also easy to handle. We can catch a C++ exception
|
|
and rethrow it as an OCaml exception like this:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%exception getitem {
|
|
try {
|
|
$action
|
|
} catch (std::out_of_range &e) {
|
|
caml_failwith(e.what());
|
|
}
|
|
}
|
|
|
|
class FooClass {
|
|
public:
|
|
int getitem(int index); // Exception handling added
|
|
...
|
|
};
|
|
</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="Ocaml_nn32">40.3 Documentation Features</a></h2>
|
|
<p> The features described in this section can be used to generate
|
|
documentation comments (colloquially referred to as "docstrings") that
|
|
can be read by <a href="https://caml.inria.fr/pub/docs/manual-ocaml/ocamldoc.html">
|
|
OCamldoc</a>.</p>
|
|
<h3><a name="Ocaml_nn33">40.3.1 Module docstring</a></h3>
|
|
<p> The first documentation comment of an <tt>mli</tt> file is the
|
|
comment associated with 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, you can retain the
|
|
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,
|
|
controls on a panel, etc. to be loaded from an XML file."
|
|
%enddef
|
|
|
|
%module(docstring=DOCSTRING) xrc
|
|
</pre>
|
|
</div><HR NOSHADE>
|
|
<h1><a name="Extending">41 Extending SWIG to support new languages</a></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_starting_out">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_configuration_files">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">User examples</a></li>
|
|
<li><a href="#Extending_test_suite">Test driven development and the
|
|
test-suite</a>
|
|
<ul>
|
|
<li><a href="#Extending_running_test_suite">Running the test-suite</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Extending_nn43">Documentation</a></li>
|
|
<li><a href="#Extending_coding_style_guidelines">Coding style guidelines</a>
|
|
</li>
|
|
<li><a href="#Extending_language_status">Target language status</a>
|
|
<ul>
|
|
<li><a href="#Extending_supported_status">Supported status</a></li>
|
|
<li><a href="#Extending_experimental_status">Experimental status</a></li>
|
|
<li><a href="#Extending_deprecated_status">Deprecated status</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Extending_prerequisites">Prerequisites for adding a new
|
|
language module to the SWIG distribution</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Extending_debugging_options">Debugging Options</a></li>
|
|
<li><a href="#Extending_nn46">Guide to parse tree nodes</a></li>
|
|
<li><a href="#Extending_further_info">Further Development Information</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
<h2><a name="Extending_nn2">41.1 Introduction</a></h2>
|
|
<p> This chapter primarily describes SWIG's internal organization and
|
|
the process by which new target languages can be developed. It also
|
|
provides details for debugging and extending existing target languages
|
|
and functionality.</p>
|
|
<p> 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. 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">41.2 Prerequisites</a></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">41.3 The Big Picture</a></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">41.4 Execution Model</a></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">41.4.1 Preprocessing</a></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 aid, the text that SWIG feeds to its C++ parser can
|
|
be obtained by running <tt>swig -E interface.i</tt>. This option, like
|
|
the same option that regular C/C++ compilers support, generates the
|
|
preprocessed output and is useful for looking at how macros have been
|
|
expanded as well as everything else that goes into the low-level
|
|
construction of the wrapper code. Also, like a regular C/C++ compiler,
|
|
the preprocessed output can be generated in one invocation and then fed
|
|
back in with a second invocation. This is the approach that the <a href="#CCache">
|
|
CCache</a> tool uses as part of its strategy to speed up repeated builds
|
|
with the same inputs.</p>
|
|
<h3><a name="Extending_nn7">41.4.2 Parsing</a></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">41.4.3 Parse Trees</a></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.
|
|
Adding the <tt>-debug-quiet</tt> option is recommended as it removes
|
|
some noise which is not usually needed, that is, the display of many
|
|
linked list pointers and symbol table pointers. See <a href="#Extending_debugging_options">
|
|
Debugging Options</a> for a full list.</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c++ -python -debug-module 1 -debug-quiet example.i
|
|
debug-module stage 1
|
|
+++ module ----------------------------------------
|
|
| name - "example"
|
|
|
|
|
+++ insert ----------------------------------------
|
|
| code - "\n#include \"example.h\"\n"
|
|
|
|
|
+++ include ----------------------------------------
|
|
| name - "example.h"
|
|
|
|
+++ class ----------------------------------------
|
|
| abstracts - 0x7f4f15182930
|
|
| allows_typedef - "1"
|
|
| kind - "class"
|
|
| name - "Shape"
|
|
| sym:name - "Shape"
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "public"
|
|
|
|
|
+++ constructor ----------------------------------------
|
|
| access - "public"
|
|
| code - "{\n nshapes++;\n }"
|
|
| decl - "f()."
|
|
| feature:new - "1"
|
|
| ismember - "1"
|
|
| name - "Shape"
|
|
| sym:name - "Shape"
|
|
|
|
|
+++ destructor ----------------------------------------
|
|
| access - "public"
|
|
| code - "{\n nshapes--;\n }"
|
|
| decl - "f()."
|
|
| ismember - "1"
|
|
| name - "~Shape"
|
|
| storage - "virtual"
|
|
| sym:name - "~Shape"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "public"
|
|
| decl - ""
|
|
| ismember - "1"
|
|
| kind - "variable"
|
|
| name - "x"
|
|
| sym:name - "x"
|
|
| type - "double"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "public"
|
|
| decl - ""
|
|
| ismember - "1"
|
|
| kind - "variable"
|
|
| name - "y"
|
|
| sym:name - "y"
|
|
| type - "double"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "public"
|
|
| decl - "f(double,double)."
|
|
| ismember - "1"
|
|
| kind - "function"
|
|
| name - "move"
|
|
| parms - 'double dx,double dy'
|
|
| sym:name - "move"
|
|
| type - "void"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| abstract - "1"
|
|
| access - "public"
|
|
| decl - "f()."
|
|
| ismember - "1"
|
|
| kind - "function"
|
|
| name - "area"
|
|
| storage - "virtual"
|
|
| sym:name - "area"
|
|
| type - "double"
|
|
| value - "0"
|
|
| valuetype - "int"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| abstract - "1"
|
|
| access - "public"
|
|
| decl - "f()."
|
|
| ismember - "1"
|
|
| kind - "function"
|
|
| name - "perimeter"
|
|
| storage - "virtual"
|
|
| sym:name - "perimeter"
|
|
| type - "double"
|
|
| value - "0"
|
|
| valuetype - "int"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "public"
|
|
| decl - ""
|
|
| ismember - "1"
|
|
| kind - "variable"
|
|
| name - "nshapes"
|
|
| storage - "static"
|
|
| sym:name - "nshapes"
|
|
| type - "int"
|
|
|
|
|
+++ class ----------------------------------------
|
|
| allows_typedef - "1"
|
|
| baselist - 0x7f4f15182ad0
|
|
| kind - "class"
|
|
| name - "Circle"
|
|
| privatebaselist - 0x7f4f15182b10
|
|
| protectedbaselist - 0x7f4f15182af0
|
|
| sym:name - "Circle"
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "private"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "private"
|
|
| decl - ""
|
|
| ismember - "1"
|
|
| kind - "variable"
|
|
| name - "radius"
|
|
| type - "double"
|
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "public"
|
|
|
|
|
+++ constructor ----------------------------------------
|
|
| access - "public"
|
|
| code - "{ }"
|
|
| decl - "f(double)."
|
|
| feature:new - "1"
|
|
| ismember - "1"
|
|
| name - "Circle"
|
|
| parms - 'double r'
|
|
| sym:name - "Circle"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "public"
|
|
| decl - "f()."
|
|
| ismember - "1"
|
|
| kind - "function"
|
|
| name - "area"
|
|
| storage - "virtual"
|
|
| sym:name - "area"
|
|
| type - "double"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "public"
|
|
| decl - "f()."
|
|
| ismember - "1"
|
|
| kind - "function"
|
|
| name - "perimeter"
|
|
| storage - "virtual"
|
|
| sym:name - "perimeter"
|
|
| type - "double"
|
|
|
|
|
+++ class ----------------------------------------
|
|
| allows_typedef - "1"
|
|
| baselist - 0x7f4f15183830
|
|
| kind - "class"
|
|
| name - "Square"
|
|
| privatebaselist - 0x7f4f15183870
|
|
| protectedbaselist - 0x7f4f15183850
|
|
| sym:name - "Square"
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "private"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "private"
|
|
| decl - ""
|
|
| ismember - "1"
|
|
| kind - "variable"
|
|
| name - "width"
|
|
| type - "double"
|
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "public"
|
|
|
|
|
+++ constructor ----------------------------------------
|
|
| access - "public"
|
|
| code - "{ }"
|
|
| decl - "f(double)."
|
|
| feature:new - "1"
|
|
| ismember - "1"
|
|
| name - "Square"
|
|
| parms - 'double w'
|
|
| sym:name - "Square"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "public"
|
|
| decl - "f()."
|
|
| ismember - "1"
|
|
| kind - "function"
|
|
| name - "area"
|
|
| storage - "virtual"
|
|
| sym:name - "area"
|
|
| type - "double"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| access - "public"
|
|
| decl - "f()."
|
|
| ismember - "1"
|
|
| kind - "function"
|
|
| name - "perimeter"
|
|
| storage - "virtual"
|
|
| sym:name - "perimeter"
|
|
| type - "double"
|
|
</pre>
|
|
</div>
|
|
<h3><a name="Extending_nn9">41.4.4 Attribute namespaces</a></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">41.4.5 Symbol Tables</a></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 1 -debug-quiet example.i
|
|
...
|
|
+++ cdecl ----------------------------------------
|
|
| decl - "f(int)."
|
|
| name - "foo"
|
|
| parms - int
|
|
| sym:name - "foo_i"
|
|
| type - "void"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| decl - "f(double)."
|
|
| name - "foo"
|
|
| parms - double
|
|
| sym:name - "foo_d"
|
|
| type - "void"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| decl - "f(p.Bar)."
|
|
| name - "foo"
|
|
| parms - Bar *
|
|
| sym:name - "foo"
|
|
| type - "void"
|
|
</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">41.4.6 The %feature directive</a></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 -debug-quiet</tt> option. For example:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
+++ cdecl ----------------------------------------
|
|
| decl - "f(int).p."
|
|
| feature:except - "{\n try {\n $action\n } catc..."
|
|
| name - "getitem"
|
|
| parms - int
|
|
| sym:name - "getitem"
|
|
| type - "Object"
|
|
|
|
|
</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">41.4.7 Code Generation</a></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">41.4.8 SWIG and XML</a></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>
|
|
<p> In addition to the options beginning <tt>-debug-</tt> for dumping
|
|
out SWIG's parse tree in a simple text format, the parse tree can also
|
|
be dumped as XML. There are three options below, where <tt>file</tt>
|
|
specifies the name of a file for generating the resulting XML into:</p>
|
|
<ol>
|
|
<li>
|
|
<p> <tt>-xmlout <file></tt></p>
|
|
<p> Use this XML option in addition to any target language options. The
|
|
parse tree is dumped after the final stage of processing, that is,
|
|
after the target language has finished processing. It is useful for
|
|
seeing the parse tree at stage 4 after any target language processing.
|
|
The parse tree dumped is very similar in content to that generated by <tt>
|
|
-debug-top 4</tt>.</p>
|
|
</li>
|
|
<li>
|
|
<p> <tt>-xml -o <file></tt></p>
|
|
<p> Use this XML option without specifying a target language. The parse
|
|
tree that is dumped is the same as if there was a no target language
|
|
option. It is useful for seeing the parse tree at stage 3, which is the
|
|
same as stage 4, as there is no target language processing. The parse
|
|
tree dumped is very similar in content to that generated by <tt>
|
|
-debug-top 3</tt>.</p>
|
|
</li>
|
|
<li>
|
|
<p> <tt>-xml -xmllite -o <file></tt></p>
|
|
<p> Same as above, except the addition of <tt>-xmllite</tt> reduces the
|
|
output by skipping some type information, that is, the typescope and
|
|
typetab nodes.</p>
|
|
</li>
|
|
</ol>
|
|
<p> The parse tree generated using <tt>-xmlout</tt> is much bigger than
|
|
that using <tt>-xml</tt> as the target languages process numerous extra
|
|
SWIG system files and also add to the parse tree quite considerably in
|
|
stage 4.</p>
|
|
<p> The XML is a dump of SWIG's internal parse tree and as such it is
|
|
subject to change at any time as and when SWIG's implementation
|
|
changes.</p>
|
|
<h2><a name="Extending_nn14">41.5 Primitive Data Structures</a></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">41.5.1 Strings</a></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>
|
|
<p> At most one of <tt>DOH_REPLACE_ANY</tt> and <tt>DOH_REPLACE_FIRST</tt>
|
|
should be specified. <tt>DOH_REPLACE_ANY</tt> is the default if neither
|
|
is specified.</p>
|
|
</div>
|
|
<h3><a name="Extending_nn16">41.5.2 Hashes</a></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>
|
|
<p><b> <tt>List *SortedKeys(Hash *h, int (*cmp) (const DOH *, const DOH
|
|
*))</tt></b></p>
|
|
<div class="indent"> Returns the list of sorted hash table keys.</div>
|
|
<h3><a name="Extending_nn17">41.5.3 Lists</a></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">41.5.4 Common operations</a></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">41.5.5 Iterating over Lists and Hashes</a></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">41.5.6 I/O</a></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> There's no explicit function to close a file, just call <tt>
|
|
Delete(f)</tt> - this decreases the reference count, and the file will
|
|
be closed when the reference count reaches zero.</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>
|
|
<h2><a name="Extending_nn21">41.6 Navigating and manipulating parse
|
|
trees</a></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 children 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">41.7 Working with attributes</a></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">41.8 Type system</a></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">41.8.1 String encoding of types</a></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">41.8.2 Type construction</a></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">41.8.3 Type tests</a></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">41.8.4 Typedef and inheritance</a></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">41.8.5 Lvalues</a></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">41.8.6 Output functions</a></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">41.9 Parameters</a></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">41.10 Writing a Language Module</a></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">41.10.1 Execution model</a></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_starting_out">41.10.2 Starting out</a></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/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">41.10.3 Command line options</a></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">41.10.4 Configuration and preprocessing</a></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">41.10.5 Entry point to code generation</a></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">41.10.6 Module I/O and wrapper skeleton</a></h3>
|
|
|
|
<!-- please report bugs in this section to mgossage -->
|
|
<p> Within SWIG wrappers, there are five main sections. These are (in
|
|
order)</p>
|
|
<ul>
|
|
<li>begin: This section is a placeholder for users to put code at the
|
|
beginning of the C/C++ wrapper file.</li>
|
|
<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 wrapper code.</li>
|
|
<li>init: This section holds the module initialisation 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);
|
|
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);
|
|
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">41.10.7 Low-level code generators</a></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 attributes */
|
|
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 wrapper function's 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 variables are needed, add them now */
|
|
...
|
|
|
|
/* write the list of locals/arguments required */
|
|
emit_args(type, parms, wrapper);
|
|
|
|
/* check arguments */
|
|
...
|
|
|
|
/* write typemaps(in) */
|
|
....
|
|
|
|
/* write constraints */
|
|
....
|
|
|
|
/* 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 substitutions 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_configuration_files">41.10.8 Configuration files</a>
|
|
</h3>
|
|
|
|
<!-- please report bugs in this section to ttn -->
|
|
<p> At the time of this writing, SWIG supports nearly twenty 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/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.ac</b></dt>
|
|
<dd> This file is processed by
|
|
<p> <a HREF="https://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> 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 the top 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> 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">41.10.9 Runtime support</a></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">41.10.10 Standard library files</a></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">41.10.11 User examples</a></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="#Extending_configuration_files">
|
|
configuration files</a>.</p>
|
|
<h3><a name="Extending_test_suite">41.10.12 Test driven development and
|
|
the test-suite</a></h3>
|
|
<p> A test driven development approach is central to the improvement and
|
|
development of SWIG. Most modifications to SWIG are accompanied by
|
|
additional regression tests and checking all tests to ensure that no
|
|
regressions have been introduced.</p>
|
|
<p> The regression testing is carried out by the SWIG<i> test-suite</i>.
|
|
The test-suite consists of numerous testcase interface files in the <tt>
|
|
Examples/test-suite</tt> directory as well as target language specific
|
|
runtime tests in the <tt>Examples/test-suite/[lang]</tt> directory.
|
|
When a testcase is run, it will execute the following steps for each
|
|
testcase:</p>
|
|
<ol>
|
|
<li>Execute SWIG passing it the testcase interface file.</li>
|
|
<li>Compile the resulting generated C/C++ code with either the C or C++
|
|
compiler into object files.</li>
|
|
<li>Link the object files into a dynamic library (dll/shared object).</li>
|
|
<li>Compile any generated and any runtime test target language code with
|
|
the target language compiler, if the target language supports
|
|
compilation. This step thus does not apply to the interpreted
|
|
languages.</li>
|
|
<li>Execute a runtime test if one exists.</li>
|
|
</ol>
|
|
<p> For example, the<i> ret_by_value</i> testcase consists of two
|
|
components. The first component is the <tt>
|
|
Examples/test-suite/ret_by_value.i</tt> interface file. The name of the
|
|
SWIG module<b> must</b> always be the name of the testcase, so the <tt>
|
|
ret_by_value.i</tt> interface file thus begins with:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%module ret_by_value
|
|
</pre>
|
|
</div>
|
|
<p> The testcase code will then follow the module declaration, usually
|
|
within a <tt>%inline %{ ... %}</tt> section for the majority of the
|
|
tests.</p>
|
|
<p> The second component is the optional runtime tests. Any runtime
|
|
tests are named using the following convention: <tt>
|
|
[testcase]_runme.[ext]</tt>, where <tt>[testcase]</tt> is the testcase
|
|
name and <tt>[ext]</tt> is the normal extension for the target language
|
|
file. In this case, the Java and Python target languages implement a
|
|
runtime test, so their files are respectively, <tt>
|
|
Examples/test-suite/java/ret_by_value_runme.java</tt> and <tt>
|
|
Examples/test-suite/python/ret_by_value_runme.py</tt>.</p>
|
|
<p> The goal of the test-suite is to test as much as possible in a<b>
|
|
silent</b> manner. This way any SWIG or compiler errors or warnings are
|
|
easily visible. Should there be any warnings, changes must be made to
|
|
either fix them (preferably) or suppress them. Compilation or runtime
|
|
errors result in a testcase failure and will be immediately visible. It
|
|
is therefore essential that the runtime tests are written in a manner
|
|
that displays nothing to stdout/stderr on success but error/exception
|
|
out with an error message on stderr on failure.</p>
|
|
<h4><a name="Extending_running_test_suite">41.10.12.1 Running the
|
|
test-suite</a></h4>
|
|
<p> In order for the test-suite to work for a particular target
|
|
language, the language must be correctly detected and configured during
|
|
the configure stage so that the correct Makefiles are generated. Most
|
|
development occurs on Linux, so usually it is a matter of installing
|
|
the development packages for the target language and simply configuring
|
|
as outlined <a href="#Extending_starting_out">earlier</a>.</p>
|
|
<p> If when running the test-suite commands that follow, you get a
|
|
message that the test was skipped, it indicates that the configure
|
|
stage is missing information in order to compile and run everything for
|
|
that language.</p>
|
|
<p> The test-suite can be run in a number of ways. The first group of
|
|
commands are for running multiple testcases in one run and should be
|
|
executed in the top level directory. To run the entire test-suite (can
|
|
take a long time):</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make -k check-test-suite
|
|
</pre>
|
|
</div>
|
|
<p> To run the test-suite just for target language [lang], replace
|
|
[lang] with one of csharp, java, perl5, python, ruby, tcl etc:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make check-[lang]-test-suite
|
|
</pre>
|
|
</div>
|
|
<p> Note that if a runtime test is available, a message "(with run
|
|
test)" is displayed when run. For example:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
$ make check-python-test-suite
|
|
checking python test-suite
|
|
checking python testcase argcargvtest (with run test)
|
|
checking python testcase python_autodoc
|
|
checking python testcase python_append (with run test)
|
|
checking python testcase callback (with run test)
|
|
</pre>
|
|
</div>
|
|
<p> The files generated on a previous run can be deleted using the clean
|
|
targets, either the whole test-suite or for a particular language:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make clean-test-suite
|
|
make clean-[lang]-test-suite
|
|
</pre>
|
|
</div>
|
|
<p> The test-suite can be run in a<i> partialcheck</i> mode where just
|
|
SWIG is executed, that is, the compile, link and running of the
|
|
testcases is not performed. Note that the partialcheck does not require
|
|
the target language to be correctly configured and detected and unlike
|
|
the other test-suite make targets, is never skipped. Once again, either
|
|
all the languages can be executed or just a chosen language:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make partialcheck-test-suite
|
|
make partialcheck-[lang]-test-suite
|
|
</pre>
|
|
</div>
|
|
<p> If your computer has more than one CPU, you are strongly advised to
|
|
use parallel make to speed up the execution speed. This can be done
|
|
with any of the make targets that execute more than one testcase. For
|
|
example, a dual core processor can efficiently use 2 parallel jobs:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make -j2 check-test-suite
|
|
make -j2 check-python-test-suite
|
|
make -j2 partialcheck-java-test-suite
|
|
</pre>
|
|
</div>
|
|
<p> The second group of commands are for running individual testcases
|
|
and should be executed in the appropriate target language directory, <tt>
|
|
Examples/test-suite/[lang]</tt>. Testcases can contain either C or C++
|
|
code and when one is written, a decision must be made as to which of
|
|
these input languages is to be used. Replace <tt>[testcase]</tt> in the
|
|
commands below with the name of the testcase.</p>
|
|
<p> For a C language testcase, add the testcase under the C_TEST_CASES
|
|
list in <tt>Examples/test-suite/common.mk</tt> and execute individually
|
|
as:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make -s [testcase].ctest
|
|
</pre>
|
|
</div>
|
|
<p> For a C++ language testcase, add the testcase under the
|
|
CPP_TEST_CASES list in <tt>Examples/test-suite/common.mk</tt> and
|
|
execute individually as:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make -s [testcase].cpptest
|
|
</pre>
|
|
</div>
|
|
<p> A third category of tests are C++ language testcases testing
|
|
multiple modules (the %import directive). These require more than one
|
|
shared library (dll/shared object) to be built and so are separated out
|
|
from the normal C++ testcases. Add the testcase under the
|
|
MULTI_CPP_TEST_CASES list in <tt>Examples/test-suite/common.mk</tt> and
|
|
execute individually as:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make -s [testcase].multicpptest
|
|
</pre>
|
|
</div>
|
|
<p> To delete the generated files, execute:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make -s [testcase].clean
|
|
</pre>
|
|
</div>
|
|
<p> If you would like to see the exact commands being executed, drop the
|
|
-s option:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make [testcase].ctest
|
|
make [testcase].cpptest
|
|
make [testcase].multicpptest
|
|
</pre>
|
|
</div>
|
|
<p> Some real examples of each:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make -s ret_by_value.clean
|
|
make -s ret_by_value.ctest
|
|
make -s bools.cpptest
|
|
make -s imports.multicpptest
|
|
</pre>
|
|
</div>
|
|
<p> Advanced usage of the test-suite facilitates running tools on some
|
|
of the five stages. The make variables <tt>SWIGTOOL</tt> and <tt>
|
|
RUNTOOL</tt> are used to specify a tool to respectively, invoke SWIG and
|
|
the execution of the runtime test. You are advised to view the <tt>
|
|
Examples/test-suite/common.mk</tt> file for details but for a short
|
|
summary, the classic usage is to use <a href="https://valgrind.org/">
|
|
Valgrind</a> for memory checking. For example, checking for memory leaks
|
|
when running the runtime test in the target language interpreter:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make ret_by_value.ctest RUNTOOL="valgrind --leak-check=full"
|
|
</pre>
|
|
</div>
|
|
<p> This will probably make more sense if you look at the output of the
|
|
above as it will show the exact commands being executed. SWIG can be
|
|
analyzed for bad memory by first rebuilding swig with just the <tt>-g</tt>
|
|
option. Also define DOH_DEBUG_MEMORY_POOLS, see <a href="#Extending_further_info">
|
|
</a> section. SWIG can then be invoked via valgrind using:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make ret_by_value.ctest SWIGTOOL="valgrind --tool=memcheck --trace-children=yes"
|
|
</pre>
|
|
</div>
|
|
<p> A debugger can also be invoked easily on an individual test, for
|
|
example gdb:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make ret_by_value.ctest RUNTOOL="gdb --args"
|
|
</pre>
|
|
</div>
|
|
<p> SWIG reads the <tt>SWIG_FEATURES</tt> environment variable to obtain
|
|
options in addition to those passed on the command line. This is
|
|
particularly useful as the entire test-suite or a particular testcase
|
|
can be run customized by using additional arguments, for example the -O
|
|
optimization flag can be added in, as shown below for the bash shell:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
env SWIG_FEATURES=-O make check-python-test-suite
|
|
</pre>
|
|
</div>
|
|
<p> The syntax for setting environment variables varies from one shell
|
|
to the next, but it also works as shown in the example below, where
|
|
some typemap debugging is added in:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
make ret_by_value.ctest SWIG_FEATURES="-debug-tmsearch"
|
|
</pre>
|
|
</div>
|
|
<p> There is also a special 'errors' test-suite which is a set of
|
|
regression tests checking SWIG warning and error messages. It can be
|
|
run in the same way as the other language test-suites, replacing [lang]
|
|
with errors, such as <tt>make check-errors-test-suite</tt>. The test
|
|
cases used and the way it works is described in <tt>
|
|
Examples/test-suite/errors/Makefile.in</tt>.</p>
|
|
<h3><a name="Extending_nn43">41.10.13 Documentation</a></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_coding_style_guidelines">41.10.14 Coding style
|
|
guidelines</a></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>
|
|
<h3><a name="Extending_language_status">41.10.15 Target language status</a>
|
|
</h3>
|
|
<p> Target languages are given a status of either 'Supported',
|
|
'Experimental' or 'Deprecated' depending on their maturity as broadly
|
|
outlined in the <a href="#Introduction_target_languages">Target
|
|
language introduction</a>. This section provides more details on how
|
|
this status is given.</p>
|
|
<h4><a name="Extending_supported_status">41.10.15.1 Supported status</a></h4>
|
|
<p> A target language is given the 'Supported' status when</p>
|
|
<ul>
|
|
<li> It is in a mature, well functioning state.</li>
|
|
<li> It has its own comprehensive chapter in the documentation. The
|
|
level of documentation should be comprehensive and match the standard
|
|
of the other mature modules. Python and Java are good references.</li>
|
|
<li> It passes all of the main SWIG test-suite. The main test-suite is
|
|
defined by the tests in the C_TEST_CASES, CPP_TEST_CASES and
|
|
MULTI_CPP_TEST_CASES lists in Examples/test-suite/common.mk. All the
|
|
newer C++ standard tests need to work and are grouped together, such as
|
|
CPP11_TEST_CASES for C++11. These more 'modern' C++ standards are only
|
|
tested though if the compiler is detected as supporting the given
|
|
standard.</li>
|
|
<li> The test-suite must also include at least twenty wide-ranging
|
|
runtime tests. The most mature languages have a few hundred runtime
|
|
tests. Note that porting runtime tests from another language module is
|
|
a quick and easy way to achieve this.</li>
|
|
<li> It supports the vast majority of SWIG features. Some more advanced
|
|
features, such as, directors, full nested class support and target
|
|
language namespaces (nspace) may be unimplemented. A few support
|
|
libraries may be missing, for example, a small number of STL libraries.</li>
|
|
<li> It provides strong backwards compatibility between releases. Each
|
|
point release must aim to be fully backwards compatible. A point
|
|
release version is the 3rd version digit, so each of the x.y.* versions
|
|
should be backwards compatible. Backwards compatibility breakages can
|
|
occur in a new major or minor version if absolutely necessary and if
|
|
documented. A major or minor version is the first or second digit in
|
|
the three digit version.</li>
|
|
<li> Fixing unintended regressions in the Supported languages will be
|
|
given higher priority over the Experimental languages by the core SWIG
|
|
developers.</li>
|
|
<li> Examples must be available and run successfully.</li>
|
|
<li> The examples and test-suite must be fully functioning on the Github
|
|
Actions Continuous Integration platform.</li>
|
|
</ul>
|
|
<h4><a name="Extending_experimental_status">41.10.15.2 Experimental
|
|
status</a></h4>
|
|
<p> A target language is given the 'Experimental' status when</p>
|
|
<ul>
|
|
<li> It is of sub-standard quality, failing to meet the above
|
|
'Supported' status.</li>
|
|
<li> It is somewhere between the mid to mature stage of development.</li>
|
|
<li> It is in need of help to finish development.</li>
|
|
</ul>
|
|
<p> Some minimum requirements and notes about languages with the
|
|
'Experimental' status:</p>
|
|
<ul>
|
|
<li> Will at least implement basic functionality - support wrapping C
|
|
functions and simple C++ classes and templates.</li>
|
|
<li> Have its own documentation chapter containing a reasonable level of
|
|
detail. The documentation must provide enough basic functionality for a
|
|
user to get started.</li>
|
|
<li> Have fully functional examples of basic functionality (the simple
|
|
and class examples).</li>
|
|
<li> The test-suite must be implemented and include a few runtime tests
|
|
for both C and C++ test cases.</li>
|
|
<li> Failing tests must be put into one of the FAILING_CPP_TESTS or
|
|
FAILING_C_TESTS lists in the test-suite. This will ensure the
|
|
test-suite can be superficially made to pass by ignoring failing tests.
|
|
The number of tests in these lists should be no greater than half of
|
|
the number of tests in the full test-suite.</li>
|
|
<li> The examples and test-suite must also be fully functioning on the
|
|
Github Actions Continuous Integration platform. However, experimental
|
|
languages will be flagged as 'continue-on-error'. This means that pull
|
|
requests and normal development commits will not break the entire
|
|
Github Actions build should an experimental language fail.</li>
|
|
<li> Any new failed tests will be fixed on a 'best effort' basis by core
|
|
developers with no promises made.</li>
|
|
<li> If a language module has an official maintainer, then the
|
|
maintainer will be requested to focus on fixing test-suite regressions
|
|
and commit to migrating the module to become a 'Supported' module.</li>
|
|
<li> If a module does not have an official maintainer, then, as
|
|
maintenance will be on a 'best efforts' basis by the core maintainers,
|
|
no guarantees will be provided from one release to the next and
|
|
regressions may creep in.</li>
|
|
<li> Experimental target languages will have a (suppressible) warning
|
|
explaining the Experimental sub-standard status and encourage users to
|
|
help improve it.</li>
|
|
<li> No backwards compatibility is guaranteed as the module is
|
|
effectively 'in development'. If a language module has an official
|
|
maintainer, then a backwards compatibility guarantee may be provided at
|
|
the maintainer's discretion and should be documented as such.</li>
|
|
</ul>
|
|
<h4><a name="Extending_deprecated_status">41.10.15.3 Deprecated status</a>
|
|
</h4>
|
|
<p> Unfortunately target languages that once met 'Experimental' or
|
|
'Supported' status can become non-functional and simply bit rot due to
|
|
neglect or due to the language's C/C++ API evolving and changing over
|
|
time. If there is no language maintainer and the maintenance burden
|
|
becomes too much for the core SWIG developers to keep the test-suite
|
|
working with easily available versions of the target language, the
|
|
language is put into the 'Deprecated' status.</p>
|
|
<p> Changing the status to 'Deprecated' is an unfortunate step not done
|
|
lightly and only if recent versions cannot successfully run the
|
|
test-suite and examples on the Github Actions Continuous Integration
|
|
platform. As the target language would once have had a working set of
|
|
examples and test-suite, this usually only occurs when the more modern
|
|
operating system distributions available on Github can no longer run
|
|
any distribution supplied version of the target language.</p>
|
|
<p> Changing status to 'Deprecated' flags it for removal from SWIG in a
|
|
subsequent release (usually one SWIG release). This step becomes the
|
|
final plea for help from the community who use the target language. The
|
|
language will need updating by an interested community member to meet
|
|
the requirements of at least 'Experimental' status in order to prevent
|
|
removal. If you are a user of a 'Deprecated' target language and would
|
|
like to keep it available in future releases, please contact the SWIG
|
|
developers for details of how you can help.</p>
|
|
<h3><a name="Extending_prerequisites">41.10.16 Prerequisites for adding
|
|
a new language module to the SWIG distribution</a></h3>
|
|
<p> New target language modules can be included in SWIG and
|
|
contributions are encouraged for popular languages. In order to be
|
|
considered for inclusion, a language must at a minimum fit the
|
|
'Experimental' status described above.</p>
|
|
<p> Below are some practical steps that should help meet these
|
|
requirements.</p>
|
|
<ol>
|
|
<li> The "simple" example needs to be working to demonstrate basic C
|
|
code wrappers. Port the example from another language, such as from <tt>
|
|
Examples/python/simple</tt>.</li>
|
|
<li> The "class" example needs to be working to demonstrate basic C++
|
|
code wrappers. Port the example from another language, such as from <tt>
|
|
Examples/python/class</tt>.</li>
|
|
<li> Modify <tt>configure.ac</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> Copying an existing language module and adapting the source for it
|
|
is likely to be the most efficient approach to fully developing a new
|
|
module as a number of corner cases are covered in the existing
|
|
implementations. The most advanced scripting languages are Python and
|
|
Ruby. The most advanced compiled target languages are Java and C#.</li>
|
|
<li> Get the <a href="#Extending_running_test_suite">test-suite</a>
|
|
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 without much effort once the generated code is compiling
|
|
correctly for basic functionality as most of the corner cases are
|
|
covered in the SWIG core. Aim to first get one C and one C++ runtime
|
|
test running in the test-suite. Adding further runtime tests should be
|
|
a lot easier afterwards by porting existing runtime tests from another
|
|
language module.</li>
|
|
<li> The structure and contents of the html documentation chapter can be
|
|
copied and adapted from one of the other language modules.</li>
|
|
<li> Source code can be formatted correctly using the info in the <a href="#Extending_coding_style_guidelines">
|
|
coding style guidelines</a> section.</li>
|
|
<li> When ready, post a patch on Github, join the swig-devel mailing
|
|
list and email the SWIG developers with a demonstration of commitment
|
|
to maintaining the language module, certainly in the short term and
|
|
ideally long term.</li>
|
|
</ol>
|
|
<p> Once accepted into the official Git repository, development efforts
|
|
should concentrate on getting the entire test-suite to work in order to
|
|
migrate the language module to the 'Supported' status. Runtime tests
|
|
should be added for existing testcases and new test cases can be added
|
|
should there be an area not already covered by the existing tests.</p>
|
|
<h2><a name="Extending_debugging_options">41.11 Debugging Options</a></h2>
|
|
<p> There are various command line options which can aid debugging a
|
|
SWIG interface as well as debugging the development of a language
|
|
module. These are as follows:</p>
|
|
<div class="shell">
|
|
<pre>
|
|
-debug-classes - Display information about the classes found in the interface
|
|
-debug-module <n> - Display module parse tree at stages 1-4, <n> is a csv list of stages
|
|
-debug-symtabs - Display symbol tables information
|
|
-debug-symbols - Display target language symbols in the symbol tables
|
|
-debug-csymbols - Display C symbols in the symbol tables
|
|
-debug-lsymbols - Display target language layer symbols
|
|
-debug-quiet - Display less parse tree node debug info when using other -debug options
|
|
-debug-tags - Display information about the tags found in the interface
|
|
-debug-template - Display information for debugging templates
|
|
-debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages
|
|
-debug-typedef - Display information about the types and typedefs in the interface
|
|
-debug-typemap - Display information for debugging typemaps
|
|
-debug-tmsearch - Display typemap search debugging information
|
|
-debug-tmused - Display typemaps used debugging information
|
|
</pre>
|
|
</div>
|
|
<p> The complete list of command line options for SWIG are available by
|
|
running <tt>swig -help</tt>.</p>
|
|
<h2><a name="Extending_nn46">41.12 Guide to parse tree nodes</a></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>
|
|
<h2><a name="Extending_further_info">41.13 Further Development
|
|
Information</a></h2>
|
|
<p> There is further documentation available on the internals of SWIG,
|
|
API documentation and debugging information. This is shipped with SWIG
|
|
in the <tt>Doc/Devel</tt> directory.</p>
|
|
</BODY>
|
|
</HTML> |