/tags/rel-2.0.4/Doc/Manual/SWIG.html
HTML | 2036 lines | 1737 code | 295 blank | 4 comment | 0 complexity | 31dc4ae9bbd484a39b2e2bc326506eb9 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>SWIG Basics</title>
- <link rel="stylesheet" type="text/css" href="style.css">
- </head>
- <body bgcolor="#ffffff">
- <H1><a name="SWIG"></a>5 SWIG Basics</H1>
- <!-- INDEX -->
- <div class="sectiontoc">
- <ul>
- <li><a href="#SWIG_nn2">Running SWIG</a>
- <ul>
- <li><a href="#SWIG_nn3">Input format</a>
- <li><a href="#SWIG_output">SWIG Output</a>
- <li><a href="#SWIG_nn5">Comments</a>
- <li><a href="#SWIG_nn6">C Preprocessor</a>
- <li><a href="#SWIG_nn7">SWIG Directives</a>
- <li><a href="#SWIG_nn8">Parser Limitations</a>
- </ul>
- <li><a href="#SWIG_nn9">Wrapping Simple C Declarations</a>
- <ul>
- <li><a href="#SWIG_nn10">Basic Type Handling</a>
- <li><a href="#SWIG_nn11">Global Variables</a>
- <li><a href="#SWIG_nn12">Constants</a>
- <li><a href="#SWIG_nn13">A brief word about <tt>const</tt></a>
- <li><a href="#SWIG_nn14">A cautionary tale of <tt>char *</tt></a>
- </ul>
- <li><a href="#SWIG_nn15">Pointers and complex objects</a>
- <ul>
- <li><a href="#SWIG_nn16">Simple pointers</a>
- <li><a href="#SWIG_nn17">Run time pointer type checking</a>
- <li><a href="#SWIG_nn18">Derived types, structs, and classes</a>
- <li><a href="#SWIG_nn19">Undefined datatypes</a>
- <li><a href="#SWIG_nn20">Typedef</a>
- </ul>
- <li><a href="#SWIG_nn21">Other Practicalities</a>
- <ul>
- <li><a href="#SWIG_nn22">Passing structures by value</a>
- <li><a href="#SWIG_nn23">Return by value</a>
- <li><a href="#SWIG_nn24">Linking to structure variables</a>
- <li><a href="#SWIG_nn25">Linking to <tt>char *</tt></a>
- <li><a href="#SWIG_nn26">Arrays</a>
- <li><a href="#SWIG_readonly_variables">Creating read-only variables</a>
- <li><a href="#SWIG_rename_ignore">Renaming and ignoring declarations</a>
- <ul>
- <li><a href="#SWIG_nn29">Simple renaming of specific identifiers</a>
- <li><a href="#SWIG_advanced_renaming">Advanced renaming support</a>
- <li><a href="#SWIG_limiting_renaming">Limiting global renaming rules</a>
- </ul>
- <li><a href="#SWIG_default_args">Default/optional arguments</a>
- <li><a href="#SWIG_nn30">Pointers to functions and callbacks</a>
- </ul>
- <li><a href="#SWIG_nn31">Structures and unions</a>
- <ul>
- <li><a href="#SWIG_nn32">Typedef and structures</a>
- <li><a href="#SWIG_nn33">Character strings and structures</a>
- <li><a href="#SWIG_nn34">Array members</a>
- <li><a href="#SWIG_structure_data_members">Structure data members</a>
- <li><a href="#SWIG_nn36">C constructors and destructors</a>
- <li><a href="#SWIG_adding_member_functions">Adding member functions to C structures</a>
- <li><a href="#SWIG_nested_structs">Nested structures</a>
- <li><a href="#SWIG_nn39">Other things to note about structure wrapping</a>
- </ul>
- <li><a href="#SWIG_nn40">Code Insertion</a>
- <ul>
- <li><a href="#SWIG_nn41">The output of SWIG</a>
- <li><a href="#SWIG_nn42">Code insertion blocks</a>
- <li><a href="#SWIG_nn43">Inlined code blocks</a>
- <li><a href="#SWIG_nn44">Initialization blocks</a>
- </ul>
- <li><a href="#SWIG_nn45">An Interface Building Strategy</a>
- <ul>
- <li><a href="#SWIG_nn46">Preparing a C program for SWIG</a>
- <li><a href="#SWIG_nn47">The SWIG interface file</a>
- <li><a href="#SWIG_nn48">Why use separate interface files?</a>
- <li><a href="#SWIG_nn49">Getting the right header files</a>
- <li><a href="#SWIG_nn50">What to do with main()</a>
- </ul>
- </ul>
- </div>
- <!-- INDEX -->
- <p>
- This chapter describes the basic operation of SWIG, the structure of its
- input files, and how it handles standard ANSI C declarations. C++ support is
- described in the next chapter. However, C++ programmers should still read this
- chapter to understand the basics.
- Specific details about each target language are described in later
- chapters.
- </p>
- <H2><a name="SWIG_nn2"></a>5.1 Running SWIG</H2>
- <p>
- To run SWIG, use the <tt>swig</tt> command with options and a filename like this:
- </p>
- <div class="shell"><pre>
- swig [ <em>options</em> ] filename
- </pre></div>
- <p>
- where <tt>filename</tt> is a SWIG interface file or a C/C++ header file.
- Below is a subset of <em>options</em> that can be used.
- Additional options are also defined for each target language. A full list
- can be obtained by typing <tt>swig -help</tt> or <tt>swig
- -<em>lang</em> -help</tt>.
- </p>
- <div class="shell"><pre>
- -allegrocl Generate ALLEGROCL wrappers
- -chicken Generate CHICKEN wrappers
- -clisp Generate CLISP wrappers
- -cffi Generate CFFI wrappers
- -csharp Generate C# wrappers
- -go Generate Go wrappers
- -guile Generate Guile wrappers
- -java Generate Java wrappers
- -lua Generate Lua wrappers
- -modula3 Generate Modula 3 wrappers
- -mzscheme Generate Mzscheme wrappers
- -ocaml Generate Ocaml wrappers
- -perl Generate Perl wrappers
- -php Generate PHP wrappers
- -pike Generate Pike wrappers
- -python Generate Python wrappers
- -r Generate R (aka GNU S) wrappers
- -ruby Generate Ruby wrappers
- -sexp Generate Lisp S-Expressions wrappers
- -tcl Generate Tcl wrappers
- -uffi Generate Common Lisp / UFFI wrappers
- -xml Generate XML wrappers
- -c++ Enable C++ parsing
- -D<em>symbol</em> Define a preprocessor symbol
- -Fstandard Display error/warning messages in commonly used format
- -Fmicrosoft Display error/warning messages in Microsoft format
- -help Display all options
- -I<em>dir</em> Add a directory to the file include path
- -l<em>file</em> Include a SWIG library file.
- -module <em>name</em> Set the name of the SWIG module
- -o <em>outfile</em> Name of output file
- -outcurrentdir Set default output dir to current dir instead of input file's path
- -outdir <em>dir</em> Set language specific files output directory
- -pcreversion Display PCRE version information
- -swiglib Show location of SWIG library
- -version Show SWIG version number
- </pre></div>
- <H3><a name="SWIG_nn3"></a>5.1.1 Input format</H3>
- <p>
- As input, SWIG expects a file containing ANSI C/C++ declarations and
- special SWIG directives. More often than not, this is a special SWIG
- interface file which is usually denoted with a special <tt>.i</tt> or
- <tt>.swg</tt> suffix. In certain cases, SWIG can be used directly on
- raw header files or source files. However, this is not the most
- typical case and there are several reasons why you might not want to
- do this (described later).
- </p>
- <p>
- The most common format of a SWIG interface is as follows:
- </p>
- <div class="code"><pre>
- %module mymodule
- %{
- #include "myheader.h"
- %}
- // Now list ANSI C/C++ declarations
- int foo;
- int bar(int x);
- ...
- </pre></div>
- <p>
- The module name is supplied using the special <tt>%module</tt>
- directive. Modules are described further in the <a href="Modules.html#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"></a>5.1.2 SWIG Output</H3>
- <p>
- The output of SWIG is a C/C++ file that contains all of the wrapper
- code needed to build an extension module. SWIG may generate some
- additional files depending on the target language. By default, an input file
- with the name <tt>file.i</tt> is transformed into a file
- <tt>file_wrap.c</tt> or <tt>file_wrap.cxx</tt> (depending on whether
- or not the <tt>-c++</tt> option has been used). The name of the
- output file can be changed using the <tt>-o</tt> option. In certain
- cases, file suffixes are used by the compiler to determine the source
- language (C, C++, etc.). Therefore, you have to use the
- <tt>-o</tt> option to change the suffix of the SWIG-generated wrapper
- file if you want something different than the default. For example:
- </p>
- <div class="shell"><pre>
- $ swig -c++ -python -o example_wrap.cpp example.i
- </pre></div>
- <p>
- The C/C++ output file created by SWIG often
- contains everything that is needed to construct a extension module
- for the target scripting language. SWIG is not a stub compiler nor is it
- usually necessary to edit the output file (and if you look at the output,
- you probably won't want to). To build the final extension module, the
- SWIG output file is compiled and linked with the rest of your C/C++
- program to create a shared library.
- </p>
- <p>
- Many target languages will also generate proxy class files in the
- target language. The default output directory for these language
- specific files is the same directory as the generated C/C++ file. This
- can be modified using the <tt>-outdir</tt> option. For example:
- </p>
- <div class="shell"><pre>
- $ swig -c++ -python -outdir pyfiles -o cppfiles/example_wrap.cpp example.i
- </pre></div>
- <p>
- If the directories <tt>cppfiles</tt> and <tt>pyfiles</tt> exist, the following
- will be generated:</p>
- <div class="shell"><pre>
- cppfiles/example_wrap.cpp
- pyfiles/example.py
- </pre></div>
- <p>
- If the <tt>-outcurrentdir</tt> option is used (without <tt>-o</tt>)
- then SWIG behaves like a typical C/C++
- compiler and the default output directory is then the current directory. Without
- this option the default output directory is the path to the input file.
- If <tt>-o</tt> and
- <tt>-outcurrentdir</tt> are used together, <tt>-outcurrentdir</tt> is effectively ignored
- as the output directory for the language files is the same directory as the
- generated C/C++ file if not overidden with <tt>-outdir</tt>.
- </p>
- <H3><a name="SWIG_nn5"></a>5.1.3 Comments</H3>
- <p>
- C and C++ style comments may appear anywhere in interface files. In
- previous versions of SWIG, comments were used to generate
- documentation files. However, this feature is currently under repair
- and will reappear in a later SWIG release.
- </p>
- <H3><a name="SWIG_nn6"></a>5.1.4 C Preprocessor</H3>
- <p>
- Like C, SWIG preprocesses all input files through an enhanced version
- of the C preprocessor. All standard preprocessor features are
- supported including file inclusion, conditional compilation and
- macros. However, <tt>#include</tt> statements are ignored unless the
- <tt>-includeall</tt> command line option has been supplied. The
- reason for disabling includes is that SWIG is sometimes used to
- process raw C header files. In this case, you usually only want the
- extension module to include functions in the supplied header file
- rather than everything that might be included by that header file
- (i.e., system headers, C library functions, etc.).
- </p>
- <p>
- It should also be noted that the SWIG preprocessor skips all text
- enclosed inside a <tt>%{...%}</tt> block. In addition, the
- preprocessor includes a number of macro handling enhancements that
- make it more powerful than the normal C preprocessor. These
- extensions are described in the "<a href="Preprocessor.html#Preprocessor">Preprocessor</a>" chapter.
- </p>
- <H3><a name="SWIG_nn7"></a>5.1.5 SWIG Directives</H3>
- <p>
- Most of SWIG's operation is controlled by special directives that are
- always preceded by a "<tt>%</tt>" to distinguish them from normal C
- declarations. These directives are used to give SWIG hints or to alter
- SWIG's parsing behavior in some manner.
- </p>
- <p>
- Since SWIG directives are not legal C syntax, it is generally not
- possible to include them in header files. However, SWIG directives can be
- included in C header files using conditional compilation like this:
- </p>
- <div class="code"><pre>
- /* header.h --- Some header file */
- /* SWIG directives -- only seen if SWIG is running */
- #ifdef SWIG
- %module foo
- #endif
- </pre>
- </div>
- <p>
- <tt>SWIG</tt> is a special preprocessing symbol defined by SWIG when
- it is parsing an input file.
- </p>
- <H3><a name="SWIG_nn8"></a>5.1.6 Parser Limitations</H3>
- <p>
- Although SWIG can parse most C/C++ declarations, it does not
- provide a complete C/C++ parser implementation. Most of these
- limitations pertain to very complicated type declarations and certain
- advanced C++ features. Specifically, the following features are not
- currently supported:
- </p>
- <ul>
- <li>
- <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.html#SWIGPlus_nested_classes">Nested classes</a> section
- for more information.
- </p>
- </ul>
- <p>
- In the event of a parsing error, conditional compilation can be used to skip
- offending code. For example:
- </p>
- <div class="code">
- <pre>
- #ifndef SWIG
- ... some bad declarations ...
- #endif
- </pre>
- </div>
- <p>
- Alternatively, you can just delete the offending code from the interface file.
- </p>
- <p>
- One of the reasons why SWIG does not provide a full C++ parser
- implementation is that it has been designed to work with incomplete
- specifications and to be very permissive in its handling of C/C++
- datatypes (e.g., SWIG can generate interfaces even when there are
- missing class declarations or opaque datatypes). Unfortunately, this
- approach makes it extremely difficult to implement certain parts of a
- C/C++ parser as most compilers use type information to assist in the
- parsing of more complex declarations (for the truly curious, the
- primary complication in the implementation is that the SWIG parser
- does not utilize a separate <em>typedef-name</em> terminal symbol as
- described on p. 234 of K&R).
- </p>
- <H2><a name="SWIG_nn9"></a>5.2 Wrapping Simple C Declarations</H2>
- <p>
- SWIG wraps simple C declarations by creating an interface that closely matches
- the way in which the declarations would be used in a C program.
- For example, consider the following interface file:
- </p>
- <div class="code"><pre>
- %module example
- %inline %{
- extern double sin(double x);
- extern int strcmp(const char *, const char *);
- extern int Foo;
- %}
- #define STATUS 50
- #define VERSION "1.1"
- </pre></div>
- <p>
- In this file, there are two functions <tt>sin()</tt> and <tt>strcmp()</tt>,
- a global variable <tt>Foo</tt>, and two constants <tt>STATUS</tt> and
- <tt>VERSION</tt>. When SWIG creates an extension module, these
- declarations are accessible as scripting language functions, variables, and
- constants respectively. For example, in Tcl:
- </p>
- <div class="targetlang"><pre>
- % sin 3
- 5.2335956
- % strcmp Dave Mike
- -1
- % puts $Foo
- 42
- % puts $STATUS
- 50
- % puts $VERSION
- 1.1
- </pre></div>
- <p>
- Or in Python:
- </p>
- <div class="targetlang"><pre>
- >>> example.sin(3)
- 5.2335956
- >>> example.strcmp('Dave','Mike')
- -1
- >>> print example.cvar.Foo
- 42
- >>> print example.STATUS
- 50
- >>> print example.VERSION
- 1.1
- </pre></div>
- <p>
- Whenever possible, SWIG creates an interface that closely matches the underlying C/C++
- code. However, due to subtle differences between languages, run-time
- environments, and semantics, it is not always possible to do so. The
- next few sections describes various aspects of this mapping.
- </p>
- <H3><a name="SWIG_nn10"></a>5.2.1 Basic Type Handling</H3>
- <p>
- In order to build an interface, SWIG has to convert C/C++ datatypes to
- equivalent types in the target language. Generally,
- scripting languages provide a more limited set of primitive types than C.
- Therefore, this conversion process involves a certain amount of type
- coercion.
- </p>
- <p>
- Most scripting languages provide a single integer type that is implemented using
- the <tt>int</tt> or <tt>long</tt> datatype in C. The following list shows
- all of the C datatypes that SWIG will convert to and from integers in the target language:
- </p>
- <div class="code"><pre>
- int
- short
- long
- unsigned
- signed
- unsigned short
- unsigned long
- unsigned char
- signed char
- bool
- </pre></div>
- <p>
- When an integral value is converted from C, a cast is used to convert it to
- the representation in the target language.
- Thus, a 16 bit short in C may be promoted to a 32 bit integer. When integers are
- converted in the other direction, the value is cast back into the original C type.
- If the value is too large to fit, it is silently truncated.
- <!-- Dave: Maybe we should fix this -->
- </p>
- <p>
- <tt>unsigned char</tt> and <tt>signed char</tt> are special cases that
- are handled as small 8-bit integers. Normally, the <tt>char</tt>
- datatype is mapped as a one-character ASCII string. </p>
- <p>
- The <tt>bool</tt> datatype is cast to and from an integer value of 0
- and 1 unless the target language provides a special boolean type.</p>
- <p>
- Some care is required when working with large integer values. Most
- scripting languages use 32-bit integers so mapping a 64-bit long
- integer may lead to truncation errors. Similar problems may arise with
- 32 bit unsigned integers (which may appear as large negative
- numbers). As a rule of thumb, the <tt>int</tt> datatype and all
- variations of <tt>char</tt> and <tt>short</tt> datatypes are safe to
- use. For <tt>unsigned int</tt> and <tt>long</tt> datatypes, you will
- need to carefully check the correct operation of your program after
- it has been wrapped with SWIG.
- </p>
- <p>
- Although the SWIG parser supports the <tt>long long</tt> datatype, not
- all language modules support it. This is because <tt>long long</tt>
- usually exceeds the integer precision available in the target
- language. In certain modules such as Tcl and Perl5, <tt>long
- long</tt> integers are encoded as strings. This allows the full range
- of these numbers to be represented. However, it does not allow
- <tt>long long</tt> values to be used in arithmetic expressions. It
- should also be noted that although <tt>long long</tt> is part
- of the ISO C99 standard, it is not universally supported by all C
- compilers. Make sure you are using a compiler that supports <tt>long
- long</tt> before trying to use this type with SWIG.
- </p>
- <p>
- SWIG recognizes the following floating point types :</p>
- <div class="code"><pre>
- float
- double
- </pre></div>
- <p>
- Floating point numbers are mapped to and from the natural
- representation of floats in the target language. This is almost always
- a C <tt>double</tt>. The rarely used datatype of <tt>long double</tt>
- is not supported by SWIG.</p>
- <p>
- The <tt>char</tt> datatype is mapped into a NULL terminated ASCII
- string with a single character. When used in a scripting language it
- shows up as a tiny string containing the character value. When
- converting the value back into C, SWIG takes a character string
- from the scripting language and strips off the first character as the
- char value. Thus if the value "foo" is assigned to a
- <tt>char</tt> datatype, it gets the value `f'.</p>
- <p>
- The <tt>char *</tt> datatype is handled as a NULL-terminated ASCII
- string. SWIG maps this into a 8-bit character string in the target
- scripting language. SWIG converts character strings in the target
- language to NULL terminated strings before passing them into
- C/C++. The default handling of these strings does not allow them to
- have embedded NULL bytes. Therefore, the <tt>char *</tt> datatype is
- not generally suitable for passing binary data. However, it is
- possible to change this behavior by defining a SWIG typemap. See the chapter
- on <a href="Typemaps.html#Typemaps">Typemaps</a> for details about this.
- </p>
- <p>
- At this time, SWIG provides limited support for Unicode and
- wide-character strings (the C <tt>wchar_t</tt> type).
- Some languages provide typemaps for wchar_t, but bear in mind these
- might not be portable across different operating systems. This is a
- delicate topic that is poorly understood by many programmers and not
- implemented in a consistent manner across languages. For those
- scripting languages that provide Unicode support, Unicode strings are
- often available in an 8-bit representation such as UTF-8 that can be
- mapped to the <tt>char *</tt> type (in which case the SWIG interface
- will probably work). If the program you are wrapping uses Unicode,
- there is no guarantee that Unicode characters in the target language
- will use the same internal representation (e.g., UCS-2 vs. UCS-4).
- You may need to write some special conversion functions.
- </p>
- <H3><a name="SWIG_nn11"></a>5.2.2 Global Variables</H3>
- <p>
- Whenever possible, SWIG maps C/C++ global variables into scripting language
- variables. For example,
- </p>
- <div class="code"><pre>
- %module example
- double foo;
- </pre></div>
- <p>
- results in a scripting language variable like this:
- </p>
- <div class="code"><pre>
- # Tcl
- set foo [3.5] ;# Set foo to 3.5
- puts $foo ;# Print the value of foo
- # Python
- cvar.foo = 3.5 # Set foo to 3.5
- print cvar.foo # Print value of foo
- # Perl
- $foo = 3.5; # Set foo to 3.5
- print $foo,"\n"; # Print value of foo
- # Ruby
- Module.foo = 3.5 # Set foo to 3.5
- print Module.foo, "\n" # Print value of foo
- </pre></div>
- <p>
- Whenever the scripting language variable is used, the underlying C
- global variable is accessed. Although SWIG makes every
- attempt to make global variables work like scripting language
- variables, it is not always possible to do so. For instance, in
- Python, all global variables must be accessed through a special
- variable object known as <tt>cvar</tt> (shown above). In Ruby, variables are
- accessed as attributes of the module. Other languages may
- convert variables to a pair of accessor functions. For example, the
- Java module generates a pair of functions <tt>double get_foo()</tt>
- and <tt>set_foo(double val)</tt> that are used to manipulate the
- value.
- </p>
- <p>
- Finally, if a global variable has been declared as <tt>const</tt>, it
- only supports read-only access. Note: this behavior is new to SWIG-1.3.
- Earlier versions of SWIG incorrectly handled <tt>const</tt> and created
- constants instead.
- </p>
- <H3><a name="SWIG_nn12"></a>5.2.3 Constants</H3>
- <p>
- Constants can be created using <tt>#define</tt>, enumerations,
- or a special <tt>%constant</tt> directive. The following
- interface file shows a few valid constant declarations :</p>
- <div class="code"><pre>
- #define I_CONST 5 // An integer constant
- #define PI 3.14159 // A Floating point constant
- #define S_CONST "hello world" // A string constant
- #define NEWLINE '\n' // Character constant
- enum boolean {NO=0, YES=1};
- enum months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG,
- SEP, OCT, NOV, DEC};
- %constant double BLAH = 42.37;
- #define PI_4 PI/4
- #define FLAGS 0x04 | 0x08 | 0x40
- </pre></div>
- <p>
- In <tt>#define</tt> declarations, the type of a constant is inferred
- by syntax. For example, a number with a decimal point is assumed to be
- floating point. In addition, SWIG must be able to fully resolve all
- of the symbols used in a <tt>#define</tt> in order for a constant to
- actually be created. This restriction is necessary because
- <tt>#define</tt> is also used to define preprocessor macros that are
- definitely not meant to be part of the scripting language interface.
- For example:
- </p>
- <div class="code">
- <pre>
- #define EXTERN extern
- EXTERN void foo();
- </pre>
- </div>
- <p>
- In this case, you probably don't want to create a constant called
- <tt>EXTERN</tt> (what would the value be?). In general,
- SWIG will not create constants for macros unless the value can
- be completely determined by the preprocessor. For instance, in the above example,
- the declaration
- </p>
- <div class="code">
- <pre>
- #define PI_4 PI/4
- </pre>
- </div>
- <p>
- defines a constant because <tt>PI</tt> was already defined as a
- constant and the value is known.
- However, for the same conservative reasons even a constant with a simple cast will be ignored, such as
- </p>
- <div class="code">
- <pre>
- #define F_CONST (double) 5 // A floating pointer constant with cast
- </pre>
- </div>
- <p>
- The use of constant expressions is allowed, but SWIG does not evaluate
- them. Rather, it passes them through to the output file and lets the C
- compiler perform the final evaluation (SWIG does perform a limited
- form of type-checking however).</p>
- <p>
- For enumerations, it is critical that the original enum definition be
- included somewhere in the interface file (either in a header file or
- in the <tt>%{,%}</tt> block). SWIG only translates the enumeration
- into code needed to add the constants to a scripting language. It
- needs the original enumeration declaration in order to get the correct
- enum values as assigned by the C compiler.
- </p>
- <p>
- The <tt>%constant</tt> directive is used to more precisely create
- constants corresponding to different C datatypes. Although it is not
- usually not needed for simple values, it is more useful when working
- with pointers and other more complex datatypes. Typically, <tt>%constant</tt>
- is only used when you want to add constants to the scripting language
- interface that are not defined in the original header file.
- </p>
- <H3><a name="SWIG_nn13"></a>5.2.4 A brief word about <tt>const</tt></H3>
- <p>
- A common confusion with C programming is the semantic meaning of the
- <tt>const</tt> qualifier in declarations--especially when it is mixed
- with pointers and other type modifiers. In fact, previous versions of SWIG
- handled <tt>const</tt> incorrectly--a situation that SWIG-1.3.7 and newer
- releases have fixed.
- </p>
- <p>
- Starting with SWIG-1.3, all variable declarations, regardless of any
- use of <tt>const</tt>, are wrapped as global variables. If a
- declaration happens to be declared as <tt>const</tt>, it is wrapped as
- a read-only variable. To tell if a variable is <tt>const</tt> or not,
- you need to look at the right-most occurrence of the <tt>const</tt>
- qualifier (that appears before the variable name). If the right-most
- <tt>const</tt> occurs after all other type modifiers (such as
- pointers), then the variable is <tt>const</tt>. Otherwise, it is not.
- </p>
- <p>
- Here are some examples of <tt>const</tt> declarations.
- </p>
- <div class="code">
- <pre>
- const char a; // A constant character
- char const b; // A constant character (the same)
- char *const c; // A constant pointer to a character
- const char *const d; // A constant pointer to a constant character
- </pre>
- </div>
- <p>
- Here is an example of a declaration that is not <tt>const</tt>:
- </p>
- <div class="code">
- <pre>
- const char *e; // A pointer to a constant character. The pointer
- // may be modified.
- </pre>
- </div>
- <p>
- In this case, the pointer <tt>e</tt> can change---it's only the value
- being pointed to that is read-only.
- </p>
- <p>
- 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.html#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"></a>5.2.5 A cautionary tale of <tt>char *</tt></H3>
- <p>
- Before going any further, there is one bit of caution involving
- <tt>char *</tt> that must now be mentioned. When strings are passed
- from a scripting language to a C <tt>char *</tt>, the pointer usually
- points to string data stored inside the interpreter. It is almost
- always a really bad idea to modify this data. Furthermore, some
- languages may explicitly disallow it. For instance, in Python,
- strings are supposed be immutable. If you violate this, you will probably
- receive a vast amount of wrath when you unleash your module on the world.
- </p>
- <p>
- The primary source of problems are functions that might modify string data in place.
- A classic example would be a function like this:
- </p>
- <div class="code">
- <pre>
- char *strcat(char *s, const char *t)
- </pre>
- </div>
- <p>
- Although SWIG will certainly generate a wrapper for this, its behavior
- will be undefined. In fact, it will probably cause your application
- to crash with a segmentation fault or other memory related problem.
- This is because <tt>s</tt> refers to some internal data in the target
- language---data that you shouldn't be touching.
- </p>
- <p>
- The bottom line: don't rely on <tt>char *</tt> for anything other than read-only
- input values. However, it must be noted that you could change the behavior of SWIG
- using <a href="Typemaps.html#Typemaps">typemaps</a>.
- </p>
- <H2><a name="SWIG_nn15"></a>5.3 Pointers and complex objects</H2>
- <p>
- Most C programs manipulate arrays, structures, and other types of objects. This section
- discusses the handling of these datatypes.
- </p>
- <H3><a name="SWIG_nn16"></a>5.3.1 Simple pointers</H3>
- <p>
- Pointers to primitive C datatypes such as </p>
- <div class="code"><pre>
- int *
- double ***
- char **
- </pre></div>
- <p>
- are fully supported by SWIG. Rather than trying to convert the data being pointed to into a scripting
- representation, SWIG simply encodes the pointer itself into a
- representation that contains the actual value of the pointer and a type-tag.
- Thus, the SWIG representation of the above
- pointers (in Tcl), might look like this:</p>
- <div class="targetlang"><pre>
- _10081012_p_int
- _1008e124_ppp_double
- _f8ac_pp_char
- </pre></div>
- <p>
- A NULL pointer is represented by the string "NULL" or the value 0
- encoded with type information.</p>
- <p>
- All pointers are treated as opaque objects by SWIG. Thus, a pointer
- may be returned by a function and passed around to other C functions
- as needed. For all practical purposes, the scripting language
- interface works in exactly the same way as you would use the
- pointer in a C program. The only difference is that there is no mechanism for
- dereferencing the pointer since this would require the target language
- to understand the memory layout of the underlying object.
- </p>
- <p>
- The scripting language representation of a pointer value should never be
- manipulated directly. Even though the values shown look like hexadecimal
- addresses, the numbers used may differ from the actual machine address (e.g.,
- on little-endian machines, the digits may appear in reverse order).
- Furthermore, SWIG does not
- normally map pointers into high-level objects such as associative
- arrays or lists (for example, converting an
- <tt>int *</tt> into an list of integers). There are several reasons
- why SWIG does not do this:</p>
- <ul>
- <li>There is not enough information in a C declaration to properly map
- pointers into higher level constructs. For example, an <tt>int *</tt>
- may indeed be an array of integers, but if it contains ten million
- elements, converting it into a list object is probably a bad idea.
- </li>
- <li>The underlying semantics associated with a pointer is not known
- by SWIG. For instance, an <tt>int *</tt> might not be an array at all--perhaps it
- is an output value!
- </li>
- <li>By handling all pointers in a consistent manner, the implementation of SWIG is greatly
- simplified and less prone to error.
- </li>
- </ul>
- <H3><a name="SWIG_nn17"></a>5.3.2 Run time pointer type checking</H3>
- <p>
- By allowing pointers to be manipulated from a scripting language, extension modules
- effectively bypass compile-time type checking in the C/C++
- compiler. To prevent errors, a type signature is encoded into all
- pointer values and is used to perform run-time type checking. This
- type-checking process is an integral part of SWIG and can not be
- disabled or modified without using typemaps (described in later
- chapters).
- </p>
- <p>
- Like C, <tt>void *</tt> matches any kind of pointer. Furthermore,
- <tt>NULL</tt> pointers can be passed to any function that expects to
- receive a pointer. Although this has the potential to cause a crash,
- <tt>NULL</tt> pointers are also sometimes used
- as sentinel values or to denote a missing/empty value. Therefore,
- SWIG leaves NULL pointer checking up to the application.
- </p>
- <H3><a name="SWIG_nn18"></a>5.3.3 Derived types, structs, and classes</H3>
- <p>
- For everything else (structs, classes, arrays, etc...) SWIG applies a
- very simple rule :</p>
- <center>
- <b>Everything else is a pointer</b>
- </center>
- <p>
- In other words, SWIG manipulates everything else by reference. This
- model makes sense because most C/C++ programs make heavy use of
- pointers and SWIG can use the type-checked pointer mechanism already
- present for handling pointers to basic datatypes.</p>
- <p>
- Although this probably sounds complicated, it's really quite
- simple. Suppose you have an interface file like this :</p>
- <div class="code"><pre>
- %module fileio
- FILE *fopen(char *, char *);
- int fclose(FILE *);
- unsigned fread(void *ptr, unsigned size, unsigned nobj, FILE *);
- unsigned fwrite(void *ptr, unsigned size, unsigned nobj, FILE *);
- void *malloc(int nbytes);
- void free(void *);
- </pre></div>
- <p>
- In this file, SWIG doesn't know what a <tt>FILE</tt> is, but since it's used
- as a pointer, so it doesn't really matter what it is. If you wrapped
- this module into Python, you can use the functions just like you
- expect :</p>
- <div class="targetlang"><pre>
- # Copy a file
- def filecopy(source,target):
- f1 = fopen(source,"r")
- f2 = fopen(target,"w")
- buffer = malloc(8192)
- nbytes = fread(buffer,8192,1,f1)
- while (nbytes > 0):
- fwrite(buffer,8192,1,f2)
- nbytes = fread(buffer,8192,1,f1)
- free(buffer)
- </pre></div>
- <p>
- In this case <tt>f1</tt>,<tt> f2</tt>, and <tt>buffer</tt> are all
- opaque objects containing C pointers. It doesn't matter what value
- they contain--our program works just fine without this knowledge.</p>
- <H3><a name="SWIG_nn19"></a>5.3.4 Undefined datatypes</H3>
- <p>
- When SWIG encounters an undeclared datatype, it automatically assumes
- that it is a structure or class. For example, suppose the following
- function appeared in a SWIG input file:</p>
- <div class="code"><pre>
- void matrix_multiply(Matrix *a, Matrix *b, Matrix *c);
- </pre></div>
- <p>
- SWIG has no idea what a "<tt>Matrix</tt>" is. However, it is obviously
- a pointer to something so SWIG generates a wrapper using its generic pointer
- handling code.
- </p>
- <p>
- Unlike C or C++, SWIG does not actually care whether <tt>Matrix</tt>
- has been previously defined in the interface file or not. This
- allows SWIG to generate interfaces from
- only partial or limited information. In some cases, you may not care
- what a <tt>Matrix</tt> really is as long as you can pass an opaque reference to
- one around in the scripting language interface.
- </p>
- <p>
- An important detail to mention is that SWIG will gladly generate
- wrappers for an interface when there are unspecified type names.
- However, <b>all unspecified types are internally handled as pointers
- to structures or classes!</b> For example, consider the following declaration:
- </p>
- <div class="code">
- <pre>
- void foo(size_t num);
- </pre>
- </div>
- <p>
- If <tt>size_t</tt> is undeclared, SWIG generates wrappers
- that expect to receive a type of <tt>size_t *</tt> (this mapping is described shortly).
- As a result, the scripting interface might behave strangely. For example:
- </p>
- <div class="code">
- <pre>
- foo(40);
- TypeError: expected a _p_size_t.
- </pre>
- </div>
- <p>
- The only way to fix this problem is to make sure you properly declare type names using
- <tt>typedef</tt>.
- </p>
- <!-- We might want to add an error reporting flag to swig -->
- <H3><a name="SWIG_nn20"></a>5.3.5 Typedef</H3>
- <p>
- Like C, <tt>typedef</tt> can be used to define new type names in SWIG. For example:
- </p>
- <div class="code"><pre>
- typedef unsigned int size_t;
- </pre></div>
- <p>
- <tt>typedef</tt> definitions appearing in a SWIG interface
- are not propagated to the generated wrapper code. Therefore, they
- either need to be defined in an included header file or placed in the
- declarations section like this:
- </p>
- <div class="code">
- <pre>
- %{
- /* Include in the generated wrapper file */
- typedef unsigned int size_t;
- %}
- /* Tell SWIG about it */
- typedef unsigned int size_t;
- </pre>
- </div>
- <p>
- or
- </p>
- <div class="code">
- <pre>
- %inline %{
- typedef unsigned int size_t;
- %}
- </pre>
- </div>
- <p>
- In certain cases, you might be able to include other header files to collect type information.
- For example:
- </p>
- <div class="code">
- <pre>
- %module example
- %import "sys/types.h"
- </pre>
- </div>
- <p>
- In this case, you might run SWIG as follows:
- </p>
- <div class="shell">
- <pre>
- $ swig -I/usr/include -includeall example.i
- </pre>
- </div>
- <p>
- It should be noted that your mileage will vary greatly here.
- System headers are notoriously complicated and may rely upon a variety
- of non-standard C coding extensions (e.g., such as special directives
- to GCC). Unless you exactly specify the right include directories and
- preprocessor symbols, this may not work correctly (you will have to
- experiment).
- </p>
- <p>
- SWIG tracks <tt>typedef</tt> declarations and uses this information
- for run-time type checking. For instance, if you use the above <tt>typedef</tt> and
- had the following function declaration:
- </p>
- <div class="code">
- <pre>
- void foo(unsigned int *ptr);
- </pre>
- </div>
- <p>
- The corresponding wrapper function will accept arguments of
- type <tt>unsigned int *</tt> or <tt>size_t *</tt>.
- </p>
- <H2><a name="SWIG_nn21"></a>5.4 Other Practicalities</H2>
- <p>
- So far, this chapter has presented almost everything you need to know to use SWIG
- for simple interfaces. However, some C programs use idioms that are somewhat
- more difficult to map to a scripting language interface. This section describes
- some of these issues.
- </p>
- <H3><a name="SWIG_nn22"></a>5.4.1 Passing structures by value</H3>
- <p>
- Sometimes a C function takes structure parameters that are passed
- by value. For example, consider the following function:
- </p>
- <div class="code"><pre>
- double dot_product(Vector a, Vector b);
- </pre></div>
- <p>
- To deal with this, SWIG transforms the function to use pointers by
- creating a wrapper equivalent to the following:
- </p>
- <div class="code"><pre>
- double wrap_dot_product(Vector *a, Vector *b) {
- Vector x = *a;
- Vector y = *b;
- return dot_product(x,y);
- }
- </pre></div>
- <p>
- In the target language, the <tt>dot_product()</tt> function now accepts pointers
- to Vectors instead of Vectors. For the most part, this transformation
- is transparent so you might not notice.
- </p>
- <H3><a name="SWIG_nn23"></a>5.4.2 Return by value</H3>
- <p>
- C functions that return structures or classes datatypes by value are more difficult
- to handle. Consider the following function:</p>
- <div class="code"><pre>
- Vector cross_product(Vector v1, Vector v2);
- </pre></div>
- <p>
- This function wants to return <tt>Vector</tt>, but SWIG only really supports
- pointers. As a result, SWIG creates a wrapper like this:
- </p>
- <div class="code"><pre>
- Vector *wrap_cross_product(Vector *v1, Vector *v2) {
- Vector x = *v1;
- Vector y = *v2;
- Vector *result;
- result = (Vector *) malloc(sizeof(Vector));
- *(result) = cross(x,y);
- return result;
- }
- </pre></div>
- <p>
- or if SWIG was run with the <tt>-c++</tt> option:</p>
- <div class="code"><pre>
- Vector *wrap_cross(Vector *v1, Vector *v2) {
- Vector x = *v1;
- Vector y = *v2;
- Vector *result = new Vector(cross(x,y)); // Uses default copy constructor
- return result;
- }
- </pre></div>
- <p>
- In both cases, SWIG allocates a new object and returns a reference to it. It
- is up to the user to delete the returned object when it is no longer
- in use. Clearly, this will leak memory if you are unaware of the implicit
- memory allocation and don't take steps to free the result. That said, it should be
- noted that some language modules can now automatically track newly created objects and
- reclaim memory for you. Consult the documentation for each language module for more details.
- </p>
- <p>
- It should also be noted that the handling of pass/return by value in
- C++ has some special cases. For example, the above code fragments
- don't work correctly if <tt>Vector</tt> doesn't define a default
- constructor. The section on SWIG and C++ has more information about this case.
- </p>
- <H3><a name="SWIG_nn24"></a>5.4.3 Linking to structure variables</H3>
- <p>
- When global variables or class members involving structures are
- encountered, SWIG handles them as pointers. For example, a global
- variable like this</p>
- <div class="code"><pre>
- Vector unit_i;
- </pre></div>
- <p>
- gets mapped to an underlying pair of set/get functions like this :</p>
- <div class="code"><pre>
- Vector *unit_i_get() {
- return &unit_i;
- }
- void unit_i_set(Vector *value) {
- unit_i = *value;
- }
- </pre></div>
- <p>
- Again some caution is in order. A global variable created in this
- manner will show up as a pointer in the target scripting language. It
- would be an extremely bad idea to free or destroy such a pointer. Also,
- C++ classes must supply a properly defined copy constructor in order for
- assignment to work correctly.
- </p>
- <H3><a name="SWIG_nn25"></a>5.4.4 Linking to <tt>char *</tt></H3>
- <p>
- When a global variable of type <tt>char *</tt> appears, SWIG uses <tt>malloc()</tt> or
- <tt>new</tt> to allocate memory for the new value. Specifically, if you have a variable
- like this
- </p>
- <div class="code">
- <pre>
- char *foo;
- </pre>
- </div>
- <p>
- SWIG generates the following code:
- </p>
- <div class="code">
- <pre>
- /* C mode */
- void foo_set(char *value) {
- if (foo) free(foo);
- foo = (char *) malloc(strlen(value)+1);
- strcpy(foo,value);
- }
- /* C++ mode. When -c++ option is used */
- void foo_set(char *value) {
- if (foo) delete [] foo;
- foo = new char[strlen(value)+1];
- strcpy(foo,value);
- }
- </pre>
- </div>
- <p>
- If this is not the behavior that you want, consider making the variable read-only using the
- <tt>%immutable</tt> directive. Alternatively, you might write a short assist-function to set the value
- exactly like you want. For example:
- </p>
- <div class="code">
- <pre>
- %inline %{
- void set_foo(char *value) {
- strncpy(foo,value, 50);
- }
- %}
- </pre>
- </div>
- <p>
- Note: If you write an assist function like this, you will have to call
- it as a function from the target scripting language (it does not work
- like a variable). For example, in Python you will have to write:
- </p>
- <div class="targetlang">
- <pre>
- >>> set_foo("Hello World")
- </pre>
- </div>
- <p>
- A common mistake with <tt>char *</tt> variables is to link to a variable declared like this:
- </p>
- <div class="code">
- <pre>
- char *VERSION = "1.0";
- </pre>
- </div>
- <p>
- In this case, the variable will be readable, but any attempt to change
- the value results in a segmentation or general protection fault. This
- is due to the fact that SWIG is trying to release the old value using
- <tt>free</tt> or <tt>delete</tt> when the string literal value currently assigned to the variable wasn't
- allocated using <tt>malloc()</tt> or <tt>new</tt>.
- To fix this behavior, you can
- either mark the variable as read-only, write a typemap (as described in Chapter 6),
- or write a special set function as shown. Another alternative is to declare the
- variable as an array:
- </p>
- <div class="code">
- <pre>
- char VERSION[64] = "1.0";
- </pre>
- </div>
- <p>
- When variables of type <tt>const char *</tt> are declared, SWIG still generates functions for setting and
- getting the value. However, the default behavior does <em>not</em> release the previous contents (resulting in
- a possible memory leak). In fact, you may get a warning message such as this when wrapping such a variable:
- </p>
- <div class="shell">
- <pre>
- example.i:20. Typemap warning. Setting const char * variable may leak memory
- </pre>
- </div>
- <p>
- The reason for this behavior is that <tt>const char *</tt> variables are often used to point to string literals.
- For example:
- </p>
- <div class="code">
- <pre>
- const char *foo = "Hello World\n";
- </pre>
- </div>
- <p>
- Therefore, it's a really bad idea to call <tt>free()</tt> on such a
- pointer. On the other hand, it <em>is</em> legal to change the
- pointer to point to some other value. When setting a variable of this
- type, SWIG allocates a new string (using malloc or new) and changes
- the pointer to point to the new value. However, repeated
- modifications of the value will result in a memory leak since the old
- value is not released.
- </p>
- <H3><a name="SWIG_nn26"></a>5.4.5 Arrays</H3>
- <p>
- Arrays are fully supported by SWIG, but they are always handled as pointers instead
- of mapping them to a special array object or list in the target language. Thus, the
- following declarations :</p>
- <div class="code"><pre>
- int foobar(int a[40]);
- void grok(char *argv[]);
- void transpose(double a[20][20]);
- </pre></div>
- <p>
- are processed as if they were really declared like this:
- </p>
- <div class="code"><pre>
- int foobar(int *a);
- void grok(char **argv);
- void transpose(double (*a)[20]);
- </pre></div>
- <p>
- Like C, SWIG does not perform array bounds checking.
- It is up to the
- user to make sure the pointer points a suitably allocated region of memory.
- </p>
- <p>
- Multi-dimensional arrays are transformed into a pointer to an array of one less
- dimension. For example:
- </p>
- <div class="code">
- <pre>
- int [10]; // Maps to int *
- int [10][20]; // Maps to int (*)[20]
- int [10][20][30]; // Maps to int (*)[20][30]
- </pre>
- </div>
- <p>
- It is important to note that in the C type system, a multidimensional
- array <tt>a[][]</tt> is <b>NOT</b> equivalent to a single pointer
- <tt>*a</tt> or a double pointer such as <tt>**a</tt>. Instead, a
- pointer to an array is used (as shown above) where the actual value of
- the pointer is the starting memory location of the array. The
- reader is strongly advised to dust off their C book and re-read the
- section on arrays before using them with SWIG.
- </p>
- <p>
- Array variables are supported, but are read-only by default. For example:
- </p>
- <div class="code">
- <pre>
- int a[100][200];
- </pre>
- </div>
- <p>
- In this case, reading the variable 'a' returns a pointer of type <tt>int (*)[200]</tt>
- that points to the first element of the array <tt>&a[0][0]</tt>. Trying to modify 'a' results
- in an error. This is because SWIG does not know how to copy data from the target
- language into the array. To work around this limitation, you may want to write
- a few simple assist functions like this:
- </p>
- <div class="code">
- <pre>
- %inline %{
- void a_set(int i, int j, int val) {
- a[i][j] = val;
- }
- int a_get(int i, int j) {
- return a[i][j];
- }
- %}
- </pre>
- </div>
- <p>
- To dynamically create arrays of various sizes and shapes, it may be useful to write
- some helper functions in your interface. For example:
- </p>
- <div class="code">
- <pre>
- // Some array helpers
- %inline %{
- /* Create any sort of [size] array */
- int *int_array(int size) {
- return (int *) malloc(size*sizeof(int));
- }
- /* Create a two-dimension array [size][10] */
- int (*int_array_10(int size))[10] {
- return (int (*)[10]) malloc(size*10*sizeof(int));
- }
- %}
- </pre>
- </div>
- <p>
- Arrays of <tt>char</tt> are handled as a special case by SWIG. In this case, strings in the
- target language can be stored in the array. For example, if you have a declaration like this,
- </p>
- <div class="code">
- <pre>
- char pathname[256];
- </pre>
- </div>
- <p>
- SWIG generates functions for both getting and setting the value that are equivalent to the following
- code:…
Large files files are truncated, but you can click here to view the full file