aboutsummaryrefslogtreecommitdiff
path: root/Examples/go/class
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2010-06-10 01:13:31 +0000
committerIan Lance Taylor <iant@google.com>2010-06-10 01:13:31 +0000
commit5af2978f77cad0eec048ba1ea09b07e8ad7abbfa (patch)
tree2a7c8d569dde6570e0a5baa907bb5b3084697a52 /Examples/go/class
parent09f14197ac1df83e9b428d84782238abec0500bd (diff)
downloadswig-5af2978f77cad0eec048ba1ea09b07e8ad7abbfa.tar.gz
Add support for the Go programming language.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12108 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Examples/go/class')
-rw-r--r--Examples/go/class/Makefile16
-rw-r--r--Examples/go/class/example.cxx28
-rw-r--r--Examples/go/class/example.go284
-rw-r--r--Examples/go/class/example.h39
-rw-r--r--Examples/go/class/example.i10
-rw-r--r--Examples/go/class/index.html203
-rw-r--r--Examples/go/class/runme.go63
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")
+}