Add support for the Go programming language.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12108 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Ian Lance Taylor 2010-06-10 01:13:31 +00:00
commit 5af2978f77
259 changed files with 16159 additions and 14 deletions

View file

@ -0,0 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
SWIGOPT =
all:: go
go::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
SWIGOPT='$(SWIGOPT)' 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

View file

@ -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;
}

View file

@ -0,0 +1,126 @@
/* ----------------------------------------------------------------------------
* 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 SwigcptrVector uintptr
func (p SwigcptrVector) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrVector) SwigIsVector() {
}
func _swig_wrap_new_Vector(float64, float64, float64) SwigcptrVector
func NewVector(arg1 float64, arg2 float64, arg3 float64) Vector {
return _swig_wrap_new_Vector(arg1, arg2, arg3)
}
func _swig_wrap_delete_Vector(uintptr)
func DeleteVector(arg1 Vector) {
_swig_wrap_delete_Vector(arg1.Swigcptr())
}
func _swig_wrap_Vector_print(SwigcptrVector) string
func (arg1 SwigcptrVector) Print() string {
return _swig_wrap_Vector_print(arg1)
}
type Vector interface {
Swigcptr() uintptr
SwigIsVector()
Print() string
}
func _swig_wrap_addv(uintptr, uintptr) SwigcptrVector
func Addv(arg1 Vector, arg2 Vector) Vector {
return _swig_wrap_addv(arg1.Swigcptr(), arg2.Swigcptr())
}
type SwigcptrVectorArray uintptr
func (p SwigcptrVectorArray) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrVectorArray) SwigIsVectorArray() {
}
func _swig_wrap_new_VectorArray(int) SwigcptrVectorArray
func NewVectorArray(arg1 int) VectorArray {
return _swig_wrap_new_VectorArray(arg1)
}
func _swig_wrap_delete_VectorArray(uintptr)
func DeleteVectorArray(arg1 VectorArray) {
_swig_wrap_delete_VectorArray(arg1.Swigcptr())
}
func _swig_wrap_VectorArray_size(SwigcptrVectorArray) int
func (arg1 SwigcptrVectorArray) Size() int {
return _swig_wrap_VectorArray_size(arg1)
}
func _swig_wrap_VectorArray_get(SwigcptrVectorArray, int) SwigcptrVector
func (arg1 SwigcptrVectorArray) Get(arg2 int) Vector {
return _swig_wrap_VectorArray_get(arg1, arg2)
}
func _swig_wrap_VectorArray_set(SwigcptrVectorArray, int, uintptr)
func (arg1 SwigcptrVectorArray) Set(arg2 int, arg3 Vector) {
_swig_wrap_VectorArray_set(arg1, arg2, arg3.Swigcptr())
}
type VectorArray interface {
Swigcptr() uintptr
SwigIsVectorArray()
Size() int
Get(arg2 int) Vector
Set(arg2 int, arg3 Vector)
}
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -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();
};

View file

@ -0,0 +1,42 @@
/* File : example.i */
/* This file has a few "typical" uses of C++ references. */
%module example
%{
#include "example.h"
%}
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;
}
}
};

View file

@ -0,0 +1,143 @@
<html>
<head>
<title>SWIG:Examples:go:reference</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/reference/</tt>
<hr>
<H2>C++ Reference Handling</H2>
<p>
This example tests SWIG's handling of C++ references. A reference in
C++ is much like a pointer. Go represents C++ classes as pointers
which are stored in interface values. Therefore, a reference to a
class in C++ simply becomes an object of the class type in Go. For
types which are not classes, a reference in C++ is represented as a
pointer in Go.
<h2>Some examples</h2>
References are most commonly used as function parameters. For
example, you might have a function like this:
<blockquote>
<pre>
Vector addv(const Vector &amp;a, const Vector &amp;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 in C++.
<blockquote>
<pre>
Vector wrap_addv(Vector *a, Vector *b);
</pre>
</blockquote>
or like this in Go:
<blockquote>
<pre>
func Addv(arg1 Vector, arg2 Vector) Vector
</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 &amp;operator[](int index);
</pre>
</blockquote>
or a method:
<blockquote>
<pre>
Vector &amp;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 &amp;result = self-&gt;get(index);
return &amp;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 &amp;get(int index) {
return (*self)[index];
}
void set(int index, Vector &amp;a) {
(*self)[index] = a;
}
}
...
}
</pre>
</blockquote>
Click <a href="example.i">here</a> to see a SWIG interface file with
these additions.
<h2>Sample Go program</h2>
Click <a href="runme.go">here</a> to see a Go program that manipulates
some C++ references.
<h2>Notes:</h2>
<ul>
<li>C++ references primarily provide notational convenience for C++
source code. However, Go 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>

View file

@ -0,0 +1,71 @@
// This example illustrates the manipulation of C++ references in Java.
package main
import (
"fmt"
. "./example"
)
func main() {
fmt.Println("Creating some objects:")
a := NewVector(3, 4, 5)
b := NewVector(10, 11, 12)
fmt.Println(" Created ", a.Print())
fmt.Println(" Created ", b.Print())
// ----- Call an overloaded operator -----
// This calls the wrapper we placed around
//
// operator+(const Vector &a, const Vector &)
//
// It returns a new allocated object.
fmt.Println("Adding a+b")
c := Addv(a, b)
fmt.Println(" a+b = " + c.Print())
// Because addv returns a reference, Addv will return a
// pointer allocated using Go's memory allocator. That means
// that it will be freed by Go's garbage collector, and we can
// not use DeleteVector to release it.
c = nil
// ----- Create a vector array -----
fmt.Println("Creating an array of vectors")
va := NewVectorArray(10)
fmt.Println(" va = ", va)
// ----- Set some values in the array -----
// These operators copy the value of Vector a and Vector b to
// the vector array
va.Set(0, a)
va.Set(1, b)
va.Set(2, Addv(a, b))
// Get some values from the array
fmt.Println("Getting some array values")
for i := 0; i < 5; i++ {
fmt.Println(" va(", i, ") = ", va.Get(i).Print())
}
// Watch under resource meter to check on this
fmt.Println("Making sure we don't leak memory.")
for i := 0; i < 1000000; i++ {
c = va.Get(i % 10)
}
// ----- Clean up ----- This could be omitted. The garbage
// collector would then clean up for us.
fmt.Println("Cleaning up")
DeleteVectorArray(va)
DeleteVector(a)
DeleteVector(b)
}