diff options
Diffstat (limited to 'Examples/go/class')
-rw-r--r-- | Examples/go/class/Makefile | 16 | ||||
-rw-r--r-- | Examples/go/class/example.cxx | 28 | ||||
-rw-r--r-- | Examples/go/class/example.go | 284 | ||||
-rw-r--r-- | Examples/go/class/example.h | 39 | ||||
-rw-r--r-- | Examples/go/class/example.i | 10 | ||||
-rw-r--r-- | Examples/go/class/index.html | 203 | ||||
-rw-r--r-- | Examples/go/class/runme.go | 63 |
7 files changed, 643 insertions, 0 deletions
diff --git a/Examples/go/class/Makefile b/Examples/go/class/Makefile new file mode 100644 index 000000000..53d31d1a4 --- /dev/null +++ b/Examples/go/class/Makefile @@ -0,0 +1,16 @@ +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)' go_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/class/example.cxx b/Examples/go/class/example.cxx new file mode 100644 index 000000000..1e8e203dd --- /dev/null +++ b/Examples/go/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#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(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/go/class/example.go b/Examples/go/class/example.go new file mode 100644 index 000000000..ec8113ad4 --- /dev/null +++ b/Examples/go/class/example.go @@ -0,0 +1,284 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +type SwigcptrShape uintptr + +func (p SwigcptrShape) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrShape) SwigIsShape() { +} + +func _swig_wrap_delete_Shape(uintptr) + +func DeleteShape(arg1 Shape) { + _swig_wrap_delete_Shape(arg1.Swigcptr()) +} + +func _swig_wrap_Shape_x_set(SwigcptrShape, float64) + +func (arg1 SwigcptrShape) SetX(arg2 float64) { + _swig_wrap_Shape_x_set(arg1, arg2) +} + +func _swig_wrap_Shape_x_get(SwigcptrShape) float64 + +func (arg1 SwigcptrShape) GetX() float64 { + return _swig_wrap_Shape_x_get(arg1) +} + +func _swig_wrap_Shape_y_set(SwigcptrShape, float64) + +func (arg1 SwigcptrShape) SetY(arg2 float64) { + _swig_wrap_Shape_y_set(arg1, arg2) +} + +func _swig_wrap_Shape_y_get(SwigcptrShape) float64 + +func (arg1 SwigcptrShape) GetY() float64 { + return _swig_wrap_Shape_y_get(arg1) +} + +func _swig_wrap_Shape_move(SwigcptrShape, float64, float64) + +func (arg1 SwigcptrShape) Move(arg2 float64, arg3 float64) { + _swig_wrap_Shape_move(arg1, arg2, arg3) +} + +func _swig_wrap_Shape_area(SwigcptrShape) float64 + +func (arg1 SwigcptrShape) Area() float64 { + return _swig_wrap_Shape_area(arg1) +} + +func _swig_wrap_Shape_perimeter(SwigcptrShape) float64 + +func (arg1 SwigcptrShape) Perimeter() float64 { + return _swig_wrap_Shape_perimeter(arg1) +} + +func _swig_wrap_Shape_nshapes_set(int) + +func SetShapeNshapes(arg1 int) { + _swig_wrap_Shape_nshapes_set(arg1) +} + +func GetShapeNshapes() int +type Shape interface { + Swigcptr() uintptr + SwigIsShape() + SetX(arg2 float64) + GetX() float64 + SetY(arg2 float64) + GetY() float64 + Move(arg2 float64, arg3 float64) + Area() float64 + Perimeter() float64 +} + +type SwigcptrCircle uintptr + +func (p SwigcptrCircle) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrCircle) SwigIsCircle() { +} + +func _swig_wrap_new_Circle(float64) SwigcptrCircle + +func NewCircle(arg1 float64) Circle { + return _swig_wrap_new_Circle(arg1) +} + +func _swig_wrap_Circle_area(SwigcptrCircle) float64 + +func (arg1 SwigcptrCircle) Area() float64 { + return _swig_wrap_Circle_area(arg1) +} + +func _swig_wrap_Circle_perimeter(SwigcptrCircle) float64 + +func (arg1 SwigcptrCircle) Perimeter() float64 { + return _swig_wrap_Circle_perimeter(arg1) +} + +func _swig_wrap_delete_Circle(uintptr) + +func DeleteCircle(arg1 Circle) { + _swig_wrap_delete_Circle(arg1.Swigcptr()) +} + +func _swig_wrap_SetCircle_X(SwigcptrCircle, float64) + +func (_swig_base SwigcptrCircle) SetX(arg1 float64) { + _swig_wrap_SetCircle_X(_swig_base, arg1) +} + +func _swig_wrap_GetCircle_X(SwigcptrCircle) float64 + +func (_swig_base SwigcptrCircle) GetX() float64 { + return _swig_wrap_GetCircle_X(_swig_base) +} + +func _swig_wrap_SetCircle_Y(SwigcptrCircle, float64) + +func (_swig_base SwigcptrCircle) SetY(arg1 float64) { + _swig_wrap_SetCircle_Y(_swig_base, arg1) +} + +func _swig_wrap_GetCircle_Y(SwigcptrCircle) float64 + +func (_swig_base SwigcptrCircle) GetY() float64 { + return _swig_wrap_GetCircle_Y(_swig_base) +} + +func _swig_wrap_Circle_move(SwigcptrCircle, float64, float64) + +func (_swig_base SwigcptrCircle) Move(arg1 float64, arg2 float64) { + _swig_wrap_Circle_move(_swig_base, arg1, arg2) +} + +func (p SwigcptrCircle) SwigIsShape() { +} + +func (p SwigcptrCircle) SwigGetShape() Shape { + return SwigcptrShape(p.Swigcptr()) +} + +type Circle interface { + Swigcptr() uintptr + SwigIsCircle() + Area() float64 + Perimeter() float64 + SetX(arg1 float64) + GetX() float64 + SetY(arg1 float64) + GetY() float64 + Move(arg1 float64, arg2 float64) + SwigIsShape() + SwigGetShape() Shape +} + +type SwigcptrSquare uintptr + +func (p SwigcptrSquare) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrSquare) SwigIsSquare() { +} + +func _swig_wrap_new_Square(float64) SwigcptrSquare + +func NewSquare(arg1 float64) Square { + return _swig_wrap_new_Square(arg1) +} + +func _swig_wrap_Square_area(SwigcptrSquare) float64 + +func (arg1 SwigcptrSquare) Area() float64 { + return _swig_wrap_Square_area(arg1) +} + +func _swig_wrap_Square_perimeter(SwigcptrSquare) float64 + +func (arg1 SwigcptrSquare) Perimeter() float64 { + return _swig_wrap_Square_perimeter(arg1) +} + +func _swig_wrap_delete_Square(uintptr) + +func DeleteSquare(arg1 Square) { + _swig_wrap_delete_Square(arg1.Swigcptr()) +} + +func _swig_wrap_SetSquare_X(SwigcptrSquare, float64) + +func (_swig_base SwigcptrSquare) SetX(arg1 float64) { + _swig_wrap_SetSquare_X(_swig_base, arg1) +} + +func _swig_wrap_GetSquare_X(SwigcptrSquare) float64 + +func (_swig_base SwigcptrSquare) GetX() float64 { + return _swig_wrap_GetSquare_X(_swig_base) +} + +func _swig_wrap_SetSquare_Y(SwigcptrSquare, float64) + +func (_swig_base SwigcptrSquare) SetY(arg1 float64) { + _swig_wrap_SetSquare_Y(_swig_base, arg1) +} + +func _swig_wrap_GetSquare_Y(SwigcptrSquare) float64 + +func (_swig_base SwigcptrSquare) GetY() float64 { + return _swig_wrap_GetSquare_Y(_swig_base) +} + +func _swig_wrap_Square_move(SwigcptrSquare, float64, float64) + +func (_swig_base SwigcptrSquare) Move(arg1 float64, arg2 float64) { + _swig_wrap_Square_move(_swig_base, arg1, arg2) +} + +func (p SwigcptrSquare) SwigIsShape() { +} + +func (p SwigcptrSquare) SwigGetShape() Shape { + return SwigcptrShape(p.Swigcptr()) +} + +type Square interface { + Swigcptr() uintptr + SwigIsSquare() + Area() float64 + Perimeter() float64 + SetX(arg1 float64) + GetX() float64 + SetY(arg1 float64) + GetY() float64 + Move(arg1 float64, arg2 float64) + SwigIsShape() + SwigGetShape() Shape +} + + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/class/example.h b/Examples/go/class/example.h new file mode 100644 index 000000000..46d901361 --- /dev/null +++ b/Examples/go/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(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); +}; + + + + + diff --git a/Examples/go/class/example.i b/Examples/go/class/example.i new file mode 100644 index 000000000..75700b305 --- /dev/null +++ b/Examples/go/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/go/class/index.html b/Examples/go/class/index.html new file mode 100644 index 000000000..b39119d12 --- /dev/null +++ b/Examples/go/class/index.html @@ -0,0 +1,203 @@ +<html> +<head> +<title>SWIG:Examples:go:class</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/go/class/</tt> +<hr> + +<H2>Wrapping a simple C++ class</H2> + +<p> +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. + +<h2>The C++ Code</h2> + +Suppose you have some C++ classes described by the following (and +admittedly lame) header file: + +<blockquote> +<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> +</blockquote> + +<h2>The SWIG interface</h2> + +A simple SWIG interface for this can be built by simply grabbing the +header file like this: + +<blockquote> +<pre> +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" +</pre> +</blockquote> + +Note: when creating a C++ extension, you must run SWIG with +the <tt>-c++</tt> option like this: +<blockquote> +<pre> +% swig -c++ -go example.i +</pre> +</blockquote> + +<h2>A sample Go script</h2> + +See <a href="example.go">example.go</a> for a program that calls the +C++ functions from Go. + +<h2>Key points</h2> + +<ul> +<li>To create a new object, you call a constructor like this: + +<blockquote> +<pre> +c := example.NewCircle(10.0) +</pre> +</blockquote> + +The name of the constructor is <tt>New</tt> followed by the name of +the class, capitalized. + +<p> +<li> +The constructor returns a value of interface type. The methods of the +interface will be the methods of the C++ class, plus member accessor +functions. + +<p> +<li>To access member data, a pair of accessor methods are used. For +example: + +<blockquote> +<pre> +c.SetX(15) # Set member data +x := c.GetX() # Get member data. +</pre> +</blockquote> + +These are methods on the type returned by the constructor. The getter +is named <tt>Get</tt> followed by the name of the member, +capitalized. The setter is similar but uses <tt>Set</tt>. + +<p> +<li>To invoke a member function, you simply do this + +<blockquote> +<pre> +fmt.Println("The area is", example.c.Area()) +</pre> +</blockquote> + +<li>To invoke a destructor, simply do this + +<blockquote> +<pre> +example.DeleteShape(c) # Deletes a shape +</pre> +</blockquote> + +The name of the destructor is <tt>Delete</tt> followed by the name of +the class, capitalized. (Note: destructors are currently not +inherited. This might change later). + +<p> +<li>Static member variables are wrapped much like C global variables. +For example: + +<blockquote> +<pre> +n := GetShapeNshapes() # Get a static data member +SetShapeNshapes(13) # Set a static data member +</pre> +</blockquote> + +The name is <tt>Get</tt> or <tt>Set</tt>, followed by the name of the +class, capitalized, followed by the name of the member, capitalized. + +</ul> + +<h2>General Comments</h2> + +<ul> +<li>This low-level interface is not the only way to handle C++ code. +Director classes provide a much higher-level interface. + +<p> +<li>Because C++ and Go implement inheritance quite differently, you +can not simply upcast an object in Go code when using multiple +inheritance. When using only single inheritance, you can simply pass +a class to a function expecting a parent class. When using multiple +inheritance, you have to call an automatically generated getter +function named <tt>Get</tt> followed by the capitalized name of the +immediate parent. This will return the same object converted to the + parent class. + +<p> +<li> +Overloaded methods should normally work. However, when calling an +overloaded method you must explicitly convert constants to the +expected type when it is not <tt>int</tt> or <tt>float</tt>. In +particular, a floating point constant will default to +type <tt>float</tt>, but C++ functions typically expect the C++ +type <tt>double</tt> which is equivalent to the Go +type <tt>float64</tt> So calling an overloaded method with a floating +point constant typically requires an explicit conversion +to <tt>float64</tt>. + +<p> +<li>Namespaces are not supported in any very coherent way. + +</ul> + +<hr> +</body> +</html> diff --git a/Examples/go/class/runme.go b/Examples/go/class/runme.go new file mode 100644 index 000000000..ff64bb4be --- /dev/null +++ b/Examples/go/class/runme.go @@ -0,0 +1,63 @@ +// This example illustrates how C++ classes can be used from Go using SWIG. + +package main + +import ( + "fmt" + . "./example" +) + +func main() { + // ----- Object creation ----- + + fmt.Println("Creating some objects:") + c := NewCircle(10) + fmt.Println(" Created circle", c) + s := NewSquare(10) + fmt.Println(" Created square", s) + + // ----- Access a static member ----- + + fmt.Println("\nA total of", GetShapeNshapes(), "shapes were created") + + // ----- 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 + var shape Shape = s + shape.SetX(-10) + shape.SetY(5) + + fmt.Println("\nHere is their current position:") + fmt.Println(" Circle = (", c.GetX(), " ", c.GetY(), ")") + fmt.Println(" Square = (", s.GetX(), " ", s.GetY(), ")") + + // ----- Call some methods ----- + + fmt.Println("\nHere are some properties of the shapes:") + shapes := []Shape{c, s} + for i := 0; i < len(shapes); i++ { + fmt.Println(" ", shapes[i]) + fmt.Println(" area = ", shapes[i].Area()) + fmt.Println(" perimeter = ", shapes[i].Perimeter()) + } + + // Notice how the area() and perimeter() functions really + // invoke the appropriate virtual method on each object. + + // ----- Delete everything ----- + + fmt.Println("\nGuess I'll clean up now") + + // Note: this invokes the virtual destructor + // You could leave this to the garbage collector + DeleteCircle(c) + DeleteSquare(s) + + fmt.Println(GetShapeNshapes(), " shapes remain") + fmt.Println("Goodbye") +} |