From 01795d2075cecfe037c0f717445ba65fd449224d Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Thu, 31 Aug 2000 21:53:26 +0000 Subject: [PATCH] New example git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@778 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/tcl/class/Makefile | 19 ++ Examples/tcl/class/example.cxx | 28 +++ Examples/tcl/class/example.h | 39 +++++ Examples/tcl/class/example.i | 11 ++ Examples/tcl/class/example1.tcl | 73 ++++++++ Examples/tcl/class/example2.tcl | 51 ++++++ Examples/tcl/class/index.html | 299 ++++++++++++++++++++++++++++++++ Examples/tcl/index.html | 1 + 8 files changed, 521 insertions(+) create mode 100644 Examples/tcl/class/Makefile create mode 100644 Examples/tcl/class/example.cxx create mode 100644 Examples/tcl/class/example.h create mode 100644 Examples/tcl/class/example.i create mode 100644 Examples/tcl/class/example1.tcl create mode 100644 Examples/tcl/class/example2.tcl create mode 100644 Examples/tcl/class/index.html diff --git a/Examples/tcl/class/Makefile b/Examples/tcl/class/Makefile new file mode 100644 index 000000000..942f4cf8f --- /dev/null +++ b/Examples/tcl/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)' tcl_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mytclsh' INTERFACE='$(INTERFACE)' tclsh_cpp_static + +clean:: + rm -f *_wrap* *.o *~ *.so mytclsh *.pyc .~* core + +check: all diff --git a/Examples/tcl/class/example.cxx b/Examples/tcl/class/example.cxx new file mode 100644 index 000000000..21582f4d1 --- /dev/null +++ b/Examples/tcl/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/tcl/class/example.h b/Examples/tcl/class/example.h new file mode 100644 index 000000000..849071dd3 --- /dev/null +++ b/Examples/tcl/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/tcl/class/example.i b/Examples/tcl/class/example.i new file mode 100644 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/tcl/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/tcl/class/example1.tcl b/Examples/tcl/class/example1.tcl new file mode 100644 index 000000000..9700d01e2 --- /dev/null +++ b/Examples/tcl/class/example1.tcl @@ -0,0 +1,73 @@ +# file: example1.tcl + +# This file illustrates the low-level C++ interface +# created by SWIG. In this case, all of our C++ classes +# get converted into function calls. + +catch { load ./example.so example} +catch { load ./example.dll example} ;# Windows + +# ----- Object creation ----- + +puts "Creating some objects:" +set c [new_Circle 10] +puts " Created circle $c" +set s [new_Square 10] +puts " Created square $s" + +# ----- Access a static member ----- + +puts "\nA total of $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. +Circle_x_set $c 20 +Circle_y_set $c 30 + +# Now use the same functions in the base class +Shape_x_set $s -10 +Shape_y_set $s 5 + +puts "\nHere is their current position:" +puts " Circle = ([Shape_x_get $c], [Shape_y_get $c])" +puts " Square = ([Shape_x_get $s], [Shape_y_get $s])" + +# ----- Call some methods ----- + +puts "\nHere are some properties of the shapes:" +foreach o "$c $s" { + puts " $o" + puts " area = [Shape_area $o]" + puts " perimeter = [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 ----- + +puts "\nI'm going to try and break the type system" + +if { [catch { + # Bad script! + Square_area $c # Try to invoke Square method on a Circle + puts " Bad bad SWIG!" + +}]} { + puts " Well, it didn't work. Good SWIG." +} + +# ----- Delete everything ----- + +puts "\nGuess I'll clean up now" + +# Note: this invokes the virtual destructor +delete_Shape $c +delete_Shape $s + +puts "$Shape_nshapes shapes remain" +puts "Goodbye" + diff --git a/Examples/tcl/class/example2.tcl b/Examples/tcl/class/example2.tcl new file mode 100644 index 000000000..6ea166df6 --- /dev/null +++ b/Examples/tcl/class/example2.tcl @@ -0,0 +1,51 @@ +# file: example1.tcl + +# This file illustrates the high level C++ interface. +# In this case C++ classes work kind of like Tk widgets + +catch { load ./example.so example} +catch { load ./example.dll example} ;# Windows + +# ----- Object creation ----- + +puts "Creating some objects:" +Circle c 10 +puts " Created circle [c cget -this]" +Circle s 10 +puts " Created square [s cget -this]" + +# ----- Access a static member ----- + +puts "\nA total of $Shape_nshapes shapes were created" + +# ----- Member data access ----- + +# Set the location of the object + +c configure -x 20 -y 30 +s configure -x -10 -y 5 + +puts "\nHere is their current position:" +puts " Circle = ([c cget -x], [c cget -y])" +puts " Square = ([s cget -x], [s cget -y])" + +# ----- Call some methods ----- + +puts "\nHere are some properties of the shapes:" +foreach o "c s" { + puts " [$o cget -this]" + puts " area = [$o area]" + puts " perimeter = [$o perimeter]" +} + +# ----- Delete everything ----- + +puts "\nGuess I'll clean up now" + +# Note: this invokes the virtual destructor +rename c "" +rename s "" + +puts "$Shape_nshapes shapes remain" +puts "Goodbye" + diff --git a/Examples/tcl/class/index.html b/Examples/tcl/class/index.html new file mode 100644 index 000000000..00bd4e870 --- /dev/null +++ b/Examples/tcl/class/index.html @@ -0,0 +1,299 @@ + + +SWIG:Examples:tcl:class + + + + + +SWIG/Examples/tcl/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++ -tcl example.i
+
+
+ +

Some sample Tcl scripts

+ +SWIG performs two forms of C++ wrapping-- a low level interface and a high level widget-like interface. + + +

Key points

+ + + +

General Comments

+ + + +
+ + diff --git a/Examples/tcl/index.html b/Examples/tcl/index.html index cc24e3192..ae804385a 100644 --- a/Examples/tcl/index.html +++ b/Examples/tcl/index.html @@ -18,6 +18,7 @@ be used to wrap a C function and a global variable. certain C declarations are turned into constants.
  • variables. How SWIG can be used to wrap C global variables.
  • value. How to pass and return structures by value. +
  • class. How wrap a simple C++ class.

    Compilation Issues