diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2009-08-18 20:56:02 +0000 |
---|---|---|
committer | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-09-25 16:59:08 +0000 |
commit | 9f8a09ed743cedd9547bf0661d518647966ab114 (patch) | |
tree | 9c7803d3b27a8ec22e91792ac7f7932efa128b20 /Examples/python/reference | |
download | swig-tarball-master.tar.gz |
Imported from /srv/lorry/lorry-area/swig-tarball/swig-1.3.40.tar.gz.HEADswig-1.3.40master
Diffstat (limited to 'Examples/python/reference')
-rw-r--r-- | Examples/python/reference/Makefile | 21 | ||||
-rw-r--r-- | Examples/python/reference/example.cxx | 46 | ||||
-rw-r--r-- | Examples/python/reference/example.h | 26 | ||||
-rw-r--r-- | Examples/python/reference/example.i | 48 | ||||
-rw-r--r-- | Examples/python/reference/index.html | 147 | ||||
-rw-r--r-- | Examples/python/reference/runme.py | 63 |
6 files changed, 351 insertions, 0 deletions
diff --git a/Examples/python/reference/Makefile b/Examples/python/reference/Makefile new file mode 100644 index 0000000..74625b9 --- /dev/null +++ b/Examples/python/reference/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/Examples/python/reference/example.cxx b/Examples/python/reference/example.cxx new file mode 100644 index 0000000..8a513bf --- /dev/null +++ b/Examples/python/reference/example.cxx @@ -0,0 +1,46 @@ +/* File : example.cxx */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include "example.h" +#include <stdio.h> +#include <stdlib.h> + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/Examples/python/reference/example.h b/Examples/python/reference/example.h new file mode 100644 index 0000000..4915adb --- /dev/null +++ b/Examples/python/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/Examples/python/reference/example.i b/Examples/python/reference/example.i new file mode 100644 index 0000000..8c95b32 --- /dev/null +++ b/Examples/python/reference/example.i @@ -0,0 +1,48 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +%rename(cprint) print; + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { + return (*$self)[index]; + } + void set(int index, Vector &a) { + (*$self)[index] = a; + } + } +}; + + + + diff --git a/Examples/python/reference/index.html b/Examples/python/reference/index.html new file mode 100644 index 0000000..25d4029 --- /dev/null +++ b/Examples/python/reference/index.html @@ -0,0 +1,147 @@ +<html> +<head> +<title>SWIG:Examples:python:reference</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/python/reference/</tt> +<hr> + +<H2>C++ Reference Handling</H2> + +<p> +This example tests SWIG's handling of C++ references. Since C++ +references are closely related to pointers (as both refer to a +location in memory), SWIG simply collapses all references into +pointers when creating wrappers. + +<h2>Some examples</h2> + +References are most commonly used as function parameter. For example, +you might have an operator like this: + +<blockquote> +<pre> +Vector operator+(const Vector &a, const Vector &b) { + Vector result; + result.x = a.x + b.x; + result.y = a.y + b.y; + result.z = a.z + b.z; + return result; +} +</pre> +</blockquote> + +or a function: + +<blockquote> +<pre> +Vector addv(const Vector &a, const Vector &b) { + Vector result; + result.x = a.x + b.x; + result.y = a.y + b.y; + result.z = a.z + b.z; + return result; +} +</pre> +</blockquote> + +In these cases, SWIG transforms everything into a pointer and creates a wrapper +that looks like this: + +<blockquote> +<pre> +Vector wrap_addv(Vector *a, Vector *b) { + return addv(*a,*b); +} +</pre> +</blockquote> + +Occasionally, a reference is used as a return value of a function +when the return result is to be used as an lvalue in an expression. +The prototypical example is an operator like this: + +<blockquote> +<pre> +Vector &operator[](int index); +</pre> +</blockquote> + +or a method: + +<blockquote> +<pre> +Vector &get(int index); +</pre> +</blockquote> + +For functions returning references, a wrapper like this is created: + +<blockquote> +<pre> +Vector *wrap_Object_get(Object *self, int index) { + Vector &result = self->get(index); + return &result; +} +</pre> +</blockquote> + +The following <a href="example.h">header file</a> contains some class +definitions with some operators and use of references. + +<h2>SWIG Interface</h2> + +SWIG does NOT support overloaded operators so it can not directly build +an interface to the classes in the above file. However, a number of workarounds +can be made. For example, an overloaded operator can be stuck behind a function +call such as the <tt>addv()</tt> function above. Array access can be handled +with a pair of set/get functions like this: + +<blockquote> +<pre> +class VectorArray { +public: + ... + %addmethods { + Vector &get(int index) { + return (*self)[index]; + } + void set(int index, Vector &a) { + (*self)[index] = a; + } + } + ... +} +</pre> +</blockquote> + +Click <a href="example.i">here</a> to see a SWIG interface file with these additions. + +<h2>Sample Python script</h2> + +Click <a href="example.py">here</a> to see a script that manipulates some C++ references. + +<h2>Notes:</h2> + +<ul> +<li>C++ references primarily provide notational convenience for C++ +source code. However, Python only supports the 'x.a' +notation so it doesn't much matter. + +<p> +<li>When a program returns a reference, a pointer is returned. +Unlike return by value, memory is not allocated to hold the +return result. + +<p> +<li>SWIG has particular trouble handling various combinations of references +and pointers. This is side effect of an old parsing scheme and +type representation that will be replaced in future versions. + +</ul> + +<hr> +</body> +</html> diff --git a/Examples/python/reference/runme.py b/Examples/python/reference/runme.py new file mode 100644 index 0000000..a1f5336 --- /dev/null +++ b/Examples/python/reference/runme.py @@ -0,0 +1,63 @@ +# file: runme.py + +# This file illustrates the manipulation of C++ references in Python + +import example + +# ----- Object creation ----- + +print "Creating some objects:" +a = example.Vector(3,4,5) +b = example.Vector(10,11,12) + +print " Created",a.cprint() +print " Created",b.cprint() + +# ----- Call an overloaded operator ----- + +# This calls the wrapper we placed around +# +# operator+(const Vector &a, const Vector &) +# +# It returns a new allocated object. + +print "Adding a+b" +c = example.addv(a,b) +print " a+b =", c.cprint() + +# Note: Unless we free the result, a memory leak will occur +del c + +# ----- Create a vector array ----- + +# Note: Using the high-level interface here +print "Creating an array of vectors" +va = example.VectorArray(10) +print " va = ",va + +# ----- Set some values in the array ----- + +# These operators copy the value of $a and $b to the vector array +va.set(0,a) +va.set(1,b) + +va.set(2,example.addv(a,b)) + +# Get some values from the array + +print "Getting some array values" +for i in range(0,5): + print " va(%d) = %s" % (i, va.get(i).cprint()) + +# Watch under resource meter to check on this +print "Making sure we don't leak memory." +for i in xrange(0,1000000): + c = va.get(i % 10) + +# ----- Clean up ----- +print "Cleaning up" + +del va +del a +del b + |