diff --git a/Examples/python/class/Makefile b/Examples/python/class/Makefile new file mode 100644 index 000000000..71af176f9 --- /dev/null +++ b/Examples/python/class/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../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:: + rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + +check: all diff --git a/Examples/python/class/example.cxx b/Examples/python/class/example.cxx new file mode 100644 index 000000000..21582f4d1 --- /dev/null +++ b/Examples/python/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#include + +/* 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; +} diff --git a/Examples/python/class/example.h b/Examples/python/class/example.h new file mode 100644 index 000000000..849071dd3 --- /dev/null +++ b/Examples/python/class/example.h @@ -0,0 +1,39 @@ +/* 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(); +}; + + + + + diff --git a/Examples/python/class/example.i b/Examples/python/class/example.i new file mode 100644 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/python/class/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/python/class/example.py b/Examples/python/class/example.py new file mode 100644 index 000000000..0e578da7b --- /dev/null +++ b/Examples/python/class/example.py @@ -0,0 +1,70 @@ +# file: example.py + +# This file illustrates the low-level C++ interface +# created by SWIG. In this case, all of our C++ classes +# get converted into function calls. + +import example + +# ----- Object creation ----- + +print "Creating some objects:" +c = example.new_Circle(10) +print " Created circle", c +s = example.new_Square(10) +print " Created square", s + +# ----- Access a static member ----- + +print "\nA total of", example.cvar.Shape_nshapes,"shapes were created" + +# ----- Member data access ----- + +# Set the location of the object + +# Notice how we can do this using functions specific to +# the 'Circle' class. +example.Circle_x_set(c, 20) +example.Circle_y_set(c, 30) + +# Now use the same functions in the base class +example.Shape_x_set(s,-10) +example.Shape_y_set(s,5) + +print "\nHere is their current position:" +print " Circle = (%f, %f)" % (example.Shape_x_get(c), example.Shape_y_get(c)) +print " Square = (%f, %f)" % (example.Shape_x_get(s), example.Shape_y_get(s)) + +# ----- Call some methods ----- + +print "\nHere are some properties of the shapes:" +for o in [c,s]: + print " ", o + print " area = ", example.Shape_area(o) + print " perimeter = ", example.Shape_perimeter(o) + +# Notice how the Shape_area() and Shape_perimeter() functions really +# invoke the appropriate virtual method on each object. + +# ----- Try to cause a type error ----- + +print "\nI'm going to try and break the type system" +try: + # Bad script! + Square_area(c) # Try to invoke Square method on a Circle + print " Bad bad SWIG!" +except: + print " Well, it didn't work. Good SWIG." + + +# ----- Delete everything ----- + +print "\nGuess I'll clean up now" + +# Note: this invokes the virtual destructor +example.delete_Shape(c) +example.delete_Shape(s) + +print example.cvar.Shape_nshapes,"shapes remain" +print "Goodbye" + diff --git a/Examples/python/class/index.html b/Examples/python/class/index.html new file mode 100644 index 000000000..3529b3ca9 --- /dev/null +++ b/Examples/python/class/index.html @@ -0,0 +1,239 @@ + + +SWIG:Examples:python:class + + + + + +SWIG/Examples/python/class/ +
+ +

Wrapping a simple C++ class

+ +$Header$
+ +

+This example illustrates the most primitive form of C++ class wrapping performed +by SWIG. In this case, C++ classes are simply transformed into a collection of +C-style functions that provide access to class members. + +

The C++ Code

+ +Suppose you have some C++ classes described by the following (and admittedly lame) +header file: + +
+
+/* 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();
+};
+
+
+ +

The SWIG interface

+ +A simple SWIG interface for this can be built by simply grabbing the header file +like this: + +
+
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+%include "example.h"
+
+
+ +Note: when creating a C++ extension, you must run SWIG with the -c++ option like this: +
+
+% swig -c++ -python example.i
+
+
+ +

A sample Python script

+ +Click here to see a script that calls the C++ functions from Python. + +

Key points

+ + + +

General Comments

+ + + +
+ + diff --git a/Examples/python/index.html b/Examples/python/index.html index 802db9b75..68b0bdfa1 100644 --- a/Examples/python/index.html +++ b/Examples/python/index.html @@ -18,6 +18,7 @@ be used to wrap a C function, a global variable, and a constant. certain C declarations are turned into constants.
  • variables. An example showing how to access C global variables from Python.
  • value. How to pass and return structures by value. +
  • class. Wrapping a simple C++ class.

    Compilation Issues