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

@ -1141,3 +1141,74 @@ r_clean:
rm -f *.@OBJEXT@ *@SO@ NAMESPACE
rm -f $(RRSRC) runme.Rout .RData
##################################################################
##### Go ######
##################################################################
GO = @GO@
GOGCC = @GOGCC@
GOSWIGARG = `if $(GOGCC) ; then echo -gccgo; fi`
GOCOMPILEARG = `if $(GOGCC) ; then echo -c -g; fi`
GOSRCS = $(INTERFACE:.i=.go)
GOCSRCS = $(INTERFACE:.i=_gc.c)
GOC = $(GO:g=c)
GOLD = $(GO:g=l)
GOPACKAGE = $(INTERFACE:.i=.a)
GOOBJEXT = $(GO:g=)
GOGCOBJS = $(GOSRCS:.go=.$(GOOBJEXT))
GOGCCOBJS = $(GOSRCS:.go=.@OBJEXT@)
# ----------------------------------------------------------------
# Build a Go dynamically loadable module (C)
# ----------------------------------------------------------------
go: $(SRCS)
$(SWIG) -go $(GOSWIGARG) $(SWIGOPT) $(INTERFACEPATH)
$(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES)
$(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
$(GO) -I . $(GOCOMPILEARG) $(GOSRCS)
if ! $(GOGCC) ; then \
$(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS) && \
gopack grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \
fi
# ----------------------------------------------------------------
# Build a Go dynamically loadable module (C++)
# ----------------------------------------------------------------
go_cpp: $(SRCS)
$(SWIG) -go -c++ $(GOSWIGARG) $(SWIGOPT) $(INTERFACEPATH)
$(CXX) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES)
$(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
$(GO) -I . $(GOCOMPILEARG) $(GOSRCS)
if ! $(GOGCC) ; then \
$(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS) && \
gopack grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \
else true; fi
# -----------------------------------------------------------------
# Running a Go example
# -----------------------------------------------------------------
go_run: runme.go
$(GO) $(GOCOMPILEARG) runme.go
if $(GOGCC) ; then \
$(GO) -o runme runme.@OBJEXT@ $(GOGCCOBJS) $(LIBPREFIX)$(TARGET)$(SO); \
else \
$(GOLD) -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o runme runme.$(GOOBJEXT); \
fi
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./runme
# -----------------------------------------------------------------
# Cleaning the Go examples
# -----------------------------------------------------------------
go_clean:
rm -f *_wrap* *_gc* .~* runme
rm -f core @EXTRA_CLEAN@
rm -f *.@OBJEXT@ *.[568] *.a *@SO@

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,4 @@
/* File : example.cxx */
#include "example.h"

View file

@ -0,0 +1,188 @@
/* ----------------------------------------------------------------------------
* 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 _swig_DirectorCallback struct {
SwigcptrCallback
v interface{}
}
func (p *_swig_DirectorCallback) Swigcptr() uintptr {
return p.SwigcptrCallback.Swigcptr()
}
func (p *_swig_DirectorCallback) SwigIsCallback() {
}
func (p *_swig_DirectorCallback) DirectorInterface() interface{} {
return p.v
}
func _swig_NewDirectorCallbackCallback(*_swig_DirectorCallback) SwigcptrCallback
func NewDirectorCallback(v interface{}) Callback {
p := &_swig_DirectorCallback{0, v}
p.SwigcptrCallback = _swig_NewDirectorCallbackCallback(p)
return p
}
func _swig_wrap_DeleteDirectorCallback(uintptr)
func DeleteDirectorCallback(arg1 Callback) {
_swig_wrap_DeleteDirectorCallback(arg1.Swigcptr())
}
func Swiggo_DeleteDirector_Callback(p *_swig_DirectorCallback) {
p.SwigcptrCallback = 0
}
type _swig_DirectorInterfaceCallbackRun interface {
Run()
}
func _swig_wrap__swig_DirectorCallback_upcall_Run(SwigcptrCallback)
func (swig_p *_swig_DirectorCallback) Run() {
if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceCallbackRun); swig_ok {
swig_g.Run()
return
}
_swig_wrap__swig_DirectorCallback_upcall_Run(swig_p.SwigcptrCallback)
}
func DirectorCallbackRun(p Callback) {
_swig_wrap__swig_DirectorCallback_upcall_Run(p.(*_swig_DirectorCallback).SwigcptrCallback)
}
func Swig_DirectorCallback_callback_run(p *_swig_DirectorCallback) {
p.Run()
}
type SwigcptrCallback uintptr
func (p SwigcptrCallback) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrCallback) SwigIsCallback() {
}
func (p SwigcptrCallback) DirectorInterface() interface{} {
return nil
}
func _swig_wrap_delete_Callback(uintptr)
func DeleteCallback(arg1 Callback) {
_swig_wrap_delete_Callback(arg1.Swigcptr())
}
func _swig_wrap_Callback_run(SwigcptrCallback)
func (arg1 SwigcptrCallback) Run() {
_swig_wrap_Callback_run(arg1)
}
func _swig_wrap_new_Callback() SwigcptrCallback
func NewCallback() Callback {
return _swig_wrap_new_Callback()
}
type Callback interface {
Swigcptr() uintptr
SwigIsCallback()
DirectorInterface() interface{}
Run()
}
type SwigcptrCaller uintptr
func (p SwigcptrCaller) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrCaller) SwigIsCaller() {
}
func _swig_wrap_new_Caller() SwigcptrCaller
func NewCaller() Caller {
return _swig_wrap_new_Caller()
}
func _swig_wrap_delete_Caller(uintptr)
func DeleteCaller(arg1 Caller) {
_swig_wrap_delete_Caller(arg1.Swigcptr())
}
func _swig_wrap_Caller_delCallback(SwigcptrCaller)
func (arg1 SwigcptrCaller) DelCallback() {
_swig_wrap_Caller_delCallback(arg1)
}
func _swig_wrap_Caller_setCallback(SwigcptrCaller, uintptr)
func (arg1 SwigcptrCaller) SetCallback(arg2 Callback) {
_swig_wrap_Caller_setCallback(arg1, arg2.Swigcptr())
}
func _swig_wrap_Caller_call(SwigcptrCaller)
func (arg1 SwigcptrCaller) Call() {
_swig_wrap_Caller_call(arg1)
}
type Caller interface {
Swigcptr() uintptr
SwigIsCaller()
DelCallback()
SetCallback(arg2 Callback)
Call()
}
type SwigcptrSwigDirector_Callback uintptr
type SwigDirector_Callback interface {
Swigcptr() uintptr;
}
func (p SwigcptrSwigDirector_Callback) Swigcptr() uintptr {
return uintptr(p)
}
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,23 @@
/* File : example.h */
#include <cstdio>
#include <iostream>
class Callback {
public:
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
virtual void run() { std::cout << "Callback::run()" << std::endl; }
};
class Caller {
private:
Callback *_callback;
public:
Caller(): _callback(0) {}
~Caller() { delCallback(); }
void delCallback() { delete _callback; _callback = 0; }
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
void call() { if (_callback) _callback->run(); }
};

View file

@ -0,0 +1,13 @@
/* File : example.i */
%module(directors="1") example
%{
#include "example.h"
%}
%include "std_string.i"
/* turn on director wrapping Callback */
%feature("director") Callback;
%include "example.h"

View file

@ -0,0 +1,81 @@
<html>
<head>
<title>SWIG:Examples:go:callback</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/callback/</tt>
<hr>
<H2>Implementing C++ callbacks in Go</H2>
<p>
This example illustrates how to use directors to implement C++
callbacks in Go.
</p>
<p>
Because Go and C++ use inheritance differently, you must call a
different function to create a class which uses callbacks. Instead of
calling the usual constructor function whose name is <tt>New</tt>
followed by the capitalized name of the class, you call a function
named <tt>NewDirector</tt> followed by the capitalized name of the
class.
</p>
<p>
The first argument to the <tt>NewDirector</tt> function is an instance
of a type. The <tt>NewDirector</tt> function will return an interface
value as usual. However, when calling any method on the returned
value, the program will first check whether the value passed
to <tt>NewDirector</tt> implements that method. If it does, the
method will be called in Go. This is true whether the method is
called from Go code or C++ code.
</p>
<p>
Note that the Go code will be called with just the Go value, not the
C++ value. If the Go code needs to call a C++ method on itself, you
need to get a copy of the C++ object. This is typically done as
follows:
<blockquote>
<pre>
type Child struct { abi Parent }
func (p *Child) ChildMethod() {
p.abi.ParentMethod()
}
func f() {
p := &Child{nil}
d := NewDirectorParent(p)
p.abi = d
...
}
</pre>
</blockquote>
In other words, we first create the Go value. We pass that to
the <tt>NewDirector</tt> function to create the C++ value; this C++
value will be created with an association to the Go value. We then
store the C++ value in the Go value, giving us the reverse
association. That permits us to call parent methods from the child.
</p>
<p>
To delete a director object, use the function <tt>DeleteDirector</tt>
followed by the capitalized name of the class.
</p>
<p>
<ul>
<li><a href="example.h">example.h</a>. Header file containing some enums.
<li><a href="example.i">example.i</a>. Interface file.
<li><a href="runme.go">runme.go</a>. Sample Go program.
</ul>
<hr>
</body>
</html>

View file

@ -0,0 +1,41 @@
package main
import (
"fmt"
. "./example"
)
func main() {
fmt.Println("Adding and calling a normal C++ callback")
fmt.Println("----------------------------------------")
caller := NewCaller()
callback := NewCallback()
caller.SetCallback(callback)
caller.Call()
caller.DelCallback()
callback = NewDirectorCallback(new(GoCallback))
fmt.Println()
fmt.Println("Adding and calling a Go callback")
fmt.Println("------------------------------------")
caller.SetCallback(callback)
caller.Call()
caller.DelCallback()
// Test that a double delete does not occur as the object has
// already been deleted from the C++ layer.
DeleteDirectorCallback(callback)
fmt.Println()
fmt.Println("Go exit")
}
type GoCallback struct{}
func (p *GoCallback) Run() {
fmt.Println("GoCallback.Run")
}

13
Examples/go/check.list Normal file
View file

@ -0,0 +1,13 @@
# see top-level Makefile.in
callback
class
constants
enum
extend
funcptr
multimap
pointer
reference
simple
template
variables

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,10 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"

View file

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

View file

@ -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")
}

View file

@ -0,0 +1,16 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS =
TARGET = example
INTERFACE = example.i
SWIGOPT =
all::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
clean::
$(MAKE) -f $(TOP)/Makefile go_clean
check: all
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run

View file

@ -0,0 +1,44 @@
/* ----------------------------------------------------------------------------
* 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))
}
const ICONST int = 42
const FCONST float64 = 2.1828
const CCONST byte = 'x'
func _swig_getCCONST2() byte
var CCONST2 byte = _swig_getCCONST2()
const SCONST string = "Hello World"
func _swig_getSCONST2() string
var SCONST2 string = _swig_getSCONST2()
func _swig_getEXPR() float64
var EXPR float64 = _swig_getEXPR()
const Iconst int = 37
const Fconst float64 = 3.14

View file

@ -0,0 +1,25 @@
/* File : example.i */
%module example
/* A few preprocessor macros */
#define ICONST 42
#define FCONST 2.1828
#define CCONST 'x'
#define CCONST2 '\n'
#define SCONST "Hello World"
#define SCONST2 "\"Hello World\""
/* This should work just fine */
#define EXPR ICONST + 3*(FCONST)
/* This shouldn't do anything */
#define EXTERN extern
/* Neither should this (BAR isn't defined) */
#define FOO (ICONST + BAR)
/* The following directives also produce constants */
%constant int iconst = 37;
%constant double fconst = 3.14;

View file

@ -0,0 +1,55 @@
<html>
<head>
<title>SWIG:Examples:go:constants</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/constants/</tt>
<hr>
<H2>Wrapping C Constants</H2>
<p>
When SWIG encounters C preprocessor macros and C declarations that
look like constants, it creates a Go constant with an identical value.
Click <a href="example.i">here</a> to see a SWIG interface with some
constant declarations in it.
<h2>Accessing Constants from Go</h2>
Click <a href="../../../Doc/Manual/Go.html#go_constants">here</a> for
the section on constants in the SWIG and Go documentation.
<p>
Click <a href="runme.go">here</a> to see a Go program that prints out
the values of the constants contained in the above file.</p>
<h2>Key points</h2>
<ul>
<li>All names are capitalized to make them visible.
<li>The values of preprocessor macros are converted into Go constants.
<li>C string literals such as "Hello World" are converted into Go strings.
<li>Macros that are not fully defined are simply ignored. For example:
<blockquote>
<pre>
#define EXTERN extern
</pre>
</blockquote>
is ignored because SWIG has no idea what type of variable this would be.
<p>
<li>Expressions are allowed provided that all of their components are
defined. Otherwise, the constant is ignored.
<li>Certain C declarations involving 'const' are also turned into Go
constants.
<li>The constants that appear in a SWIG interface file do not have to
appear in any sort of matching C source file since the creation of a
constant does not require linkage to a stored value (i.e., a value
held in a C global variable or memory location).
</ul>
<hr>
</body>
</html>

View file

@ -0,0 +1,18 @@
package main
import (
"fmt"
"./example"
)
func main() {
fmt.Println("ICONST = ", example.ICONST, " (should be 42)")
fmt.Println("FCONST = ", example.FCONST, " (should be 2.1828)")
fmt.Printf("CCONST = %c (should be 'x')\n", example.CCONST)
fmt.Printf("CCONST2 = %c(this should be on a new line)\n", example.CCONST2)
fmt.Println("SCONST = ", example.SCONST, " (should be 'Hello World')")
fmt.Println("SCONST2 = ", example.SCONST2, " (should be '\"Hello World\"')")
fmt.Println("EXPR = ", example.EXPR, " (should be 48.5484)")
fmt.Println("iconst = ", example.Iconst, " (should be 37)")
fmt.Println("fconst = ", example.Fconst, " (should be 3.14)")
}

18
Examples/go/enum/Makefile Normal file
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,37 @@
/* File : example.cxx */
#include "example.h"
#include <stdio.h>
void Foo::enum_test(speed s) {
if (s == IMPULSE) {
printf("IMPULSE speed\n");
} else if (s == WARP) {
printf("WARP speed\n");
} else if (s == LUDICROUS) {
printf("LUDICROUS speed\n");
} else {
printf("Unknown speed\n");
}
}
void enum_test(color c, Foo::speed s) {
if (c == RED) {
printf("color = RED, ");
} else if (c == BLUE) {
printf("color = BLUE, ");
} else if (c == GREEN) {
printf("color = GREEN, ");
} else {
printf("color = Unknown color!, ");
}
if (s == Foo::IMPULSE) {
printf("speed = IMPULSE speed\n");
} else if (s == Foo::WARP) {
printf("speed = WARP speed\n");
} else if (s == Foo::LUDICROUS) {
printf("speed = LUDICROUS speed\n");
} else {
printf("speed = Unknown speed!\n");
}
}

View file

@ -0,0 +1,93 @@
/* ----------------------------------------------------------------------------
* 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 Color int
func _swig_getRED() Color
var RED Color = _swig_getRED()
func _swig_getBLUE() Color
var BLUE Color = _swig_getBLUE()
func _swig_getGREEN() Color
var GREEN Color = _swig_getGREEN()
type SwigcptrFoo uintptr
func (p SwigcptrFoo) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrFoo) SwigIsFoo() {
}
func _swig_wrap_new_Foo() SwigcptrFoo
func NewFoo() Foo {
return _swig_wrap_new_Foo()
}
type FooSpeed int
func _swig_getFoo_IMPULSE_Foo() FooSpeed
var FooIMPULSE FooSpeed = _swig_getFoo_IMPULSE_Foo()
func _swig_getFoo_WARP_Foo() FooSpeed
var FooWARP FooSpeed = _swig_getFoo_WARP_Foo()
func _swig_getFoo_LUDICROUS_Foo() FooSpeed
var FooLUDICROUS FooSpeed = _swig_getFoo_LUDICROUS_Foo()
func _swig_wrap_Foo_enum_test(SwigcptrFoo, FooSpeed)
func (arg1 SwigcptrFoo) Enum_test(arg2 FooSpeed) {
_swig_wrap_Foo_enum_test(arg1, arg2)
}
func _swig_wrap_delete_Foo(uintptr)
func DeleteFoo(arg1 Foo) {
_swig_wrap_delete_Foo(arg1.Swigcptr())
}
type Foo interface {
Swigcptr() uintptr
SwigIsFoo()
Enum_test(arg2 FooSpeed)
}
func _swig_wrap_enum_test(Color, FooSpeed)
func Enum_test(arg1 Color, arg2 FooSpeed) {
_swig_wrap_enum_test(arg1, arg2)
}
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,13 @@
/* File : example.h */
enum color { RED, BLUE, GREEN };
class Foo {
public:
Foo() { }
enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 };
void enum_test(speed s);
};
void enum_test(color c, Foo::speed s);

View file

@ -0,0 +1,11 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"

View file

@ -0,0 +1,42 @@
<html>
<head>
<title>SWIG:Examples:go:enum</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/enum/</tt>
<hr>
<H2>Wrapping enumerations</H2>
<p>
This example tests SWIG's ability to wrap enumerations.
<ul>
<li>
Enum values are expressed as constants or variables in GO.
<li>
If the enum is named, then that name, capitalized, as defined as a new
type name for <tt>int</tt>. All the enum values will be defined to
have that type.
<li>
If the enum is declared at global level, then the name in Go is simply
the enum value, capitalized.
<li>
If the enum is declared within a C++ class or struct, then the name in
Go is the capitalized name of the class or struct followed by the
capitalized name of the enum value.
<li>
</ul>
<p>
<ul>
<li><a href="example.h">example.h</a>. Header file containing some enums.
<li><a href="example.i">example.i</a>. Interface file.
<li><a href="runme.go">runme.go</a>. Sample Go program.
</ul>
<hr>
</body>
</html>

32
Examples/go/enum/runme.go Normal file
View file

@ -0,0 +1,32 @@
package main
import (
"fmt"
. "./example"
)
func main() {
// Print out the value of some enums
fmt.Println("*** color ***")
fmt.Println(" RED = ", RED)
fmt.Println(" BLUE = ", BLUE)
fmt.Println(" GREEN = ", GREEN)
fmt.Println("\n*** Foo::speed ***")
fmt.Println(" Foo::IMPULSE = ", FooIMPULSE)
fmt.Println(" Foo::WARP = ", FooWARP)
fmt.Println(" Foo::LUDICROUS = ", FooLUDICROUS)
fmt.Println("\nTesting use of enums with functions\n")
Enum_test(RED, FooIMPULSE)
Enum_test(BLUE, FooWARP)
Enum_test(GREEN, FooLUDICROUS)
fmt.Println("\nTesting use of enum with class method")
f := NewFoo()
f.Enum_test(FooIMPULSE)
f.Enum_test(FooWARP)
f.Enum_test(FooLUDICROUS)
}

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,4 @@
/* File : example.cxx */
#include "example.h"

View file

@ -0,0 +1,397 @@
/* ----------------------------------------------------------------------------
* 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 _swig_DirectorEmployee struct {
SwigcptrEmployee
v interface{}
}
func (p *_swig_DirectorEmployee) Swigcptr() uintptr {
return p.SwigcptrEmployee.Swigcptr()
}
func (p *_swig_DirectorEmployee) SwigIsEmployee() {
}
func (p *_swig_DirectorEmployee) DirectorInterface() interface{} {
return p.v
}
func _swig_NewDirectorEmployeeEmployee(*_swig_DirectorEmployee, string) SwigcptrEmployee
func NewDirectorEmployee(v interface{}, arg1 string) Employee {
p := &_swig_DirectorEmployee{0, v}
p.SwigcptrEmployee = _swig_NewDirectorEmployeeEmployee(p, arg1)
return p
}
type _swig_DirectorInterfaceEmployeeGetTitle interface {
GetTitle() string
}
func _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(SwigcptrEmployee) string
func (swig_p *_swig_DirectorEmployee) GetTitle() string {
if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetTitle); swig_ok {
return swig_g.GetTitle()
}
return _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(swig_p.SwigcptrEmployee)
}
func DirectorEmployeeGetTitle(p Employee) string {
return _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(p.(*_swig_DirectorEmployee).SwigcptrEmployee)
}
func Swig_DirectorEmployee_callback_getTitle(p *_swig_DirectorEmployee) (swig_result string) {
return p.GetTitle()
}
type _swig_DirectorInterfaceEmployeeGetName interface {
GetName() string
}
func _swig_wrap__swig_DirectorEmployee_upcall_GetName(SwigcptrEmployee) string
func (swig_p *_swig_DirectorEmployee) GetName() string {
if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetName); swig_ok {
return swig_g.GetName()
}
return _swig_wrap__swig_DirectorEmployee_upcall_GetName(swig_p.SwigcptrEmployee)
}
func DirectorEmployeeGetName(p Employee) string {
return _swig_wrap__swig_DirectorEmployee_upcall_GetName(p.(*_swig_DirectorEmployee).SwigcptrEmployee)
}
func Swig_DirectorEmployee_callback_getName(p *_swig_DirectorEmployee) (swig_result string) {
return p.GetName()
}
type _swig_DirectorInterfaceEmployeeGetPosition interface {
GetPosition() string
}
func _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(SwigcptrEmployee) string
func (swig_p *_swig_DirectorEmployee) GetPosition() string {
if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetPosition); swig_ok {
return swig_g.GetPosition()
}
return _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(swig_p.SwigcptrEmployee)
}
func DirectorEmployeeGetPosition(p Employee) string {
return _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(p.(*_swig_DirectorEmployee).SwigcptrEmployee)
}
func Swig_DirectorEmployee_callback_getPosition(p *_swig_DirectorEmployee) (swig_result string) {
return p.GetPosition()
}
func _swig_wrap_DeleteDirectorEmployee(uintptr)
func DeleteDirectorEmployee(arg1 Employee) {
_swig_wrap_DeleteDirectorEmployee(arg1.Swigcptr())
}
func Swiggo_DeleteDirector_Employee(p *_swig_DirectorEmployee) {
p.SwigcptrEmployee = 0
}
type SwigcptrEmployee uintptr
func (p SwigcptrEmployee) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrEmployee) SwigIsEmployee() {
}
func (p SwigcptrEmployee) DirectorInterface() interface{} {
return nil
}
func _swig_wrap_new_Employee(string) SwigcptrEmployee
func NewEmployee(arg1 string) Employee {
return _swig_wrap_new_Employee(arg1)
}
func _swig_wrap_Employee_getTitle(SwigcptrEmployee) string
func (arg1 SwigcptrEmployee) GetTitle() string {
return _swig_wrap_Employee_getTitle(arg1)
}
func _swig_wrap_Employee_getName(SwigcptrEmployee) string
func (arg1 SwigcptrEmployee) GetName() string {
return _swig_wrap_Employee_getName(arg1)
}
func _swig_wrap_Employee_getPosition(SwigcptrEmployee) string
func (arg1 SwigcptrEmployee) GetPosition() string {
return _swig_wrap_Employee_getPosition(arg1)
}
func _swig_wrap_delete_Employee(uintptr)
func DeleteEmployee(arg1 Employee) {
_swig_wrap_delete_Employee(arg1.Swigcptr())
}
type Employee interface {
Swigcptr() uintptr
SwigIsEmployee()
DirectorInterface() interface{}
GetTitle() string
GetName() string
GetPosition() string
}
type _swig_DirectorManager struct {
SwigcptrManager
v interface{}
}
func (p *_swig_DirectorManager) Swigcptr() uintptr {
return p.SwigcptrManager.Swigcptr()
}
func (p *_swig_DirectorManager) SwigIsManager() {
}
func (p *_swig_DirectorManager) DirectorInterface() interface{} {
return p.v
}
func _swig_NewDirectorManagerManager(*_swig_DirectorManager, string) SwigcptrManager
func NewDirectorManager(v interface{}, arg1 string) Manager {
p := &_swig_DirectorManager{0, v}
p.SwigcptrManager = _swig_NewDirectorManagerManager(p, arg1)
return p
}
type _swig_DirectorInterfaceManagerGetTitle interface {
GetTitle() string
}
func _swig_wrap__swig_DirectorManager_upcall_GetTitle(SwigcptrManager) string
func (swig_p *_swig_DirectorManager) GetTitle() string {
if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetTitle); swig_ok {
return swig_g.GetTitle()
}
return _swig_wrap__swig_DirectorManager_upcall_GetTitle(swig_p.SwigcptrManager)
}
func DirectorManagerGetTitle(p Manager) string {
return _swig_wrap__swig_DirectorManager_upcall_GetTitle(p.(*_swig_DirectorManager).SwigcptrManager)
}
func Swig_DirectorManager_callback_getTitle(p *_swig_DirectorManager) (swig_result string) {
return p.GetTitle()
}
type _swig_DirectorInterfaceManagerGetName interface {
GetName() string
}
func _swig_wrap__swig_DirectorManager_upcall_GetName(SwigcptrManager) string
func (swig_p *_swig_DirectorManager) GetName() string {
if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetName); swig_ok {
return swig_g.GetName()
}
return _swig_wrap__swig_DirectorManager_upcall_GetName(swig_p.SwigcptrManager)
}
func DirectorManagerGetName(p Manager) string {
return _swig_wrap__swig_DirectorManager_upcall_GetName(p.(*_swig_DirectorManager).SwigcptrManager)
}
func Swig_DirectorManager_callback_getName(p *_swig_DirectorManager) (swig_result string) {
return p.GetName()
}
type _swig_DirectorInterfaceManagerGetPosition interface {
GetPosition() string
}
func _swig_wrap__swig_DirectorManager_upcall_GetPosition(SwigcptrManager) string
func (swig_p *_swig_DirectorManager) GetPosition() string {
if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetPosition); swig_ok {
return swig_g.GetPosition()
}
return _swig_wrap__swig_DirectorManager_upcall_GetPosition(swig_p.SwigcptrManager)
}
func DirectorManagerGetPosition(p Manager) string {
return _swig_wrap__swig_DirectorManager_upcall_GetPosition(p.(*_swig_DirectorManager).SwigcptrManager)
}
func Swig_DirectorManager_callback_getPosition(p *_swig_DirectorManager) (swig_result string) {
return p.GetPosition()
}
func _swig_wrap_DeleteDirectorManager(uintptr)
func DeleteDirectorManager(arg1 Manager) {
_swig_wrap_DeleteDirectorManager(arg1.Swigcptr())
}
func Swiggo_DeleteDirector_Manager(p *_swig_DirectorManager) {
p.SwigcptrManager = 0
}
type SwigcptrManager uintptr
func (p SwigcptrManager) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrManager) SwigIsManager() {
}
func (p SwigcptrManager) DirectorInterface() interface{} {
return nil
}
func _swig_wrap_new_Manager(string) SwigcptrManager
func NewManager(arg1 string) Manager {
return _swig_wrap_new_Manager(arg1)
}
func _swig_wrap_Manager_getPosition(SwigcptrManager) string
func (arg1 SwigcptrManager) GetPosition() string {
return _swig_wrap_Manager_getPosition(arg1)
}
func _swig_wrap_delete_Manager(uintptr)
func DeleteManager(arg1 Manager) {
_swig_wrap_delete_Manager(arg1.Swigcptr())
}
func _swig_wrap_Manager_getTitle(SwigcptrManager) string
func (_swig_base SwigcptrManager) GetTitle() string {
return _swig_wrap_Manager_getTitle(_swig_base)
}
func _swig_wrap_Manager_getName(SwigcptrManager) string
func (_swig_base SwigcptrManager) GetName() string {
return _swig_wrap_Manager_getName(_swig_base)
}
func (p SwigcptrManager) SwigIsEmployee() {
}
func (p SwigcptrManager) SwigGetEmployee() Employee {
return SwigcptrEmployee(p.Swigcptr())
}
type Manager interface {
Swigcptr() uintptr
SwigIsManager()
DirectorInterface() interface{}
GetPosition() string
GetTitle() string
GetName() string
SwigIsEmployee()
SwigGetEmployee() Employee
}
type SwigcptrEmployeeList uintptr
func (p SwigcptrEmployeeList) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrEmployeeList) SwigIsEmployeeList() {
}
func _swig_wrap_new_EmployeeList() SwigcptrEmployeeList
func NewEmployeeList() EmployeeList {
return _swig_wrap_new_EmployeeList()
}
func _swig_wrap_EmployeeList_addEmployee(SwigcptrEmployeeList, uintptr)
func (arg1 SwigcptrEmployeeList) AddEmployee(arg2 Employee) {
_swig_wrap_EmployeeList_addEmployee(arg1, arg2.Swigcptr())
}
func _swig_wrap_EmployeeList_get_item(SwigcptrEmployeeList, int) SwigcptrEmployee
func (arg1 SwigcptrEmployeeList) Get_item(arg2 int) Employee {
return _swig_wrap_EmployeeList_get_item(arg1, arg2)
}
func _swig_wrap_delete_EmployeeList(uintptr)
func DeleteEmployeeList(arg1 EmployeeList) {
_swig_wrap_delete_EmployeeList(arg1.Swigcptr())
}
type EmployeeList interface {
Swigcptr() uintptr
SwigIsEmployeeList()
AddEmployee(arg2 Employee)
Get_item(arg2 int) Employee
}
type SwigcptrSwigDirector_Manager uintptr
type SwigDirector_Manager interface {
Swigcptr() uintptr;
}
func (p SwigcptrSwigDirector_Manager) Swigcptr() uintptr {
return uintptr(p)
}
type SwigcptrSwigDirector_Employee uintptr
type SwigDirector_Employee interface {
Swigcptr() uintptr;
}
func (p SwigcptrSwigDirector_Employee) Swigcptr() uintptr {
return uintptr(p)
}
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,56 @@
/* File : example.h */
#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
class Employee {
private:
std::string name;
public:
Employee(const char* n): name(n) {}
virtual std::string getTitle() { return getPosition() + " " + getName(); }
virtual std::string getName() { return name; }
virtual std::string getPosition() const { return "Employee"; }
virtual ~Employee() { printf("~Employee() @ %p\n", this); }
};
class Manager: public Employee {
public:
Manager(const char* n): Employee(n) {}
virtual std::string getPosition() const { return "Manager"; }
};
class EmployeeList {
std::vector<Employee*> list;
public:
EmployeeList() {
list.push_back(new Employee("Bob"));
list.push_back(new Employee("Jane"));
list.push_back(new Manager("Ted"));
}
void addEmployee(Employee *p) {
list.push_back(p);
std::cout << "New employee added. Current employees are:" << std::endl;
std::vector<Employee*>::iterator i;
for (i=list.begin(); i!=list.end(); i++) {
std::cout << " " << (*i)->getTitle() << std::endl;
}
}
const Employee *get_item(int i) {
return list[i];
}
~EmployeeList() {
std::vector<Employee*>::iterator i;
std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl;
for (i=list.begin(); i!=list.end(); i++) {
delete *i;
}
std::cout << "~EmployeeList empty." << std::endl;
}
};

View file

@ -0,0 +1,15 @@
/* File : example.i */
%module(directors="1") example
%{
#include "example.h"
%}
%include "std_vector.i"
%include "std_string.i"
/* turn on director wrapping for Manager */
%feature("director") Employee;
%feature("director") Manager;
%include "example.h"

View file

@ -0,0 +1,27 @@
<html>
<head>
<title>SWIG:Examples:go:extend</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/extend/</tt>
<hr>
<H2>Extending a simple C++ class in Go</H2>
<p>
This example illustrates the extending of a C++ class with cross
language polymorphism.
<p>
<ul>
<li><a href="example.h">example.h</a>. Header file containing some enums.
<li><a href="example.i">example.i</a>. Interface file.
<li><a href="runme.go">runme.go</a>. Sample Go program.
</ul>
<hr>
</body>
</html>

View file

@ -0,0 +1,77 @@
// This file illustrates the cross language polymorphism using directors.
package main
import (
"fmt"
. "./example"
)
type CEO struct{}
func (p *CEO) GetPosition() string {
return "CEO"
}
func main() {
// Create an instance of CEO, a class derived from the Go
// proxy of the underlying C++ class. The calls to getName()
// and getPosition() are standard, the call to getTitle() uses
// the director wrappers to call CEO.getPosition().
e := NewDirectorManager(new(CEO), "Alice")
fmt.Println(e.GetName(), " is a ", e.GetPosition())
fmt.Println("Just call her \"", e.GetTitle(), "\"")
fmt.Println("----------------------")
// Create a new EmployeeList instance. This class does not
// have a C++ director wrapper, but can be used freely with
// other classes that do.
list := NewEmployeeList()
// EmployeeList owns its items, so we must surrender ownership
// of objects we add.
// e.DisownMemory()
list.AddEmployee(e)
fmt.Println("----------------------")
// Now we access the first four items in list (three are C++
// objects that EmployeeList's constructor adds, the last is
// our CEO). The virtual methods of all these instances are
// treated the same. For items 0, 1, and 2, all methods
// resolve in C++. For item 3, our CEO, GetTitle calls
// GetPosition which resolves in Go. The call to GetPosition
// is slightly different, however, because of the overidden
// GetPosition() call, since now the object reference has been
// "laundered" by passing through EmployeeList as an
// Employee*. Previously, Go resolved the call immediately in
// CEO, but now Go thinks the object is an instance of class
// Employee. So the call passes through the Employee proxy
// class and on to the C wrappers and C++ director, eventually
// ending up back at the Java CEO implementation of
// getPosition(). The call to GetTitle() for item 3 runs the
// C++ Employee::getTitle() method, which in turn calls
// GetPosition(). This virtual method call passes down
// through the C++ director class to the Java implementation
// in CEO. All this routing takes place transparently.
fmt.Println("(position, title) for items 0-3:")
fmt.Println(" ", list.Get_item(0).GetPosition(), ", \"", list.Get_item(0).GetTitle(), "\"")
fmt.Println(" ", list.Get_item(1).GetPosition(), ", \"", list.Get_item(1).GetTitle(), "\"")
fmt.Println(" ", list.Get_item(2).GetPosition(), ", \"", list.Get_item(2).GetTitle(), "\"")
fmt.Println(" ", list.Get_item(3).GetPosition(), ", \"", list.Get_item(3).GetTitle(), "\"")
fmt.Println("----------------------")
// Time to delete the EmployeeList, which will delete all the
// Employee* items it contains. The last item is our CEO,
// which gets destroyed as well.
DeleteEmployeeList(list)
fmt.Println("----------------------")
// All done.
fmt.Println("Go exit")
}

View file

@ -0,0 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
SWIGOPT =
all:: go
go::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
clean::
$(MAKE) -f $(TOP)/Makefile go_clean
check: all
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run

View file

@ -0,0 +1,19 @@
/* File : example.c */
int do_op(int a, int b, int (*op)(int,int)) {
return (*op)(a,b);
}
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
int mul(int a, int b) {
return a*b;
}
int (*funcvar)(int,int) = add;

View file

@ -0,0 +1,54 @@
/* ----------------------------------------------------------------------------
* 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))
}
func Do_op(int, int, _swig_fnptr) int
func _swig_getADD() _swig_fnptr
var ADD _swig_fnptr = _swig_getADD()
func _swig_getSUB() _swig_fnptr
var SUB _swig_fnptr = _swig_getSUB()
func _swig_getMUL() _swig_fnptr
var MUL _swig_fnptr = _swig_getMUL()
func _swig_wrap_funcvar_set(_swig_fnptr)
func SetFuncvar(arg1 _swig_fnptr) {
_swig_wrap_funcvar_set(arg1)
}
func GetFuncvar() _swig_fnptr
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,9 @@
/* file: example.h */
extern int do_op(int,int, int (*op)(int,int));
extern int add(int,int);
extern int sub(int,int);
extern int mul(int,int);
extern int (*funcvar)(int,int);

View file

@ -0,0 +1,16 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Wrap a function taking a pointer to a function */
extern int do_op(int a, int b, int (*op)(int, int));
/* Now install a bunch of "ops" as constants */
%constant int (*ADD)(int,int) = add;
%constant int (*SUB)(int,int) = sub;
%constant int (*MUL)(int,int) = mul;
extern int (*funcvar)(int,int);

View file

@ -0,0 +1,89 @@
<html>
<head>
<title>SWIG:Examples:go:funcptr</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/funcptr/</tt>
<hr>
<H2>Pointers to Functions</H2>
<p>
Okay, just what in the heck does SWIG do with a declaration like this?
<blockquote>
<pre>
int do_op(int a, int b, int (*op)(int, int));
</pre>
</blockquote>
Well, it creates a wrapper as usual. Of course, that does raise some
questions about the third argument (the pointer to a function).
<p>
In this case, SWIG will wrap the function pointer as it does for all
other pointers. However, in order to actually call this function from
a Go program, you will need to pass some kind of C function pointer
object. In C, this is easy, you just supply a function name as an
argument like this:
<blockquote>
<pre>
/* Some callback function */
int add(int a, int b) {
return a+b;
}
...
int r = do_op(x,y,add);
</pre>
</blockquote>
To make this work with SWIG, you will need to do a little extra work.
Specifically, you need to create some function pointer objects using
the %constant directive like this:
<blockquote>
<pre>
%constant(int (*)(int,int)) ADD = add;
</pre>
</blockquote>
Now, in a Go program, you would do this:
<blockquote>
<pre>
int r = do_op(x,y, example.ADD)
</pre>
</blockquote>
where <tt>example</tt> is the module name.
<h2>An Example</h2>
Here are some files that illustrate this with a simple example:
<ul>
<li><a href="example.c">example.c</a>
<li><a href="example.h">example.h</a>
<li><a href="example.i">example.i</a> (SWIG interface)
<li><a href="runme.go">runme.go</a> (Sample program)
</ul>
<h2>Notes</h2>
<ul>
<li>The value of a function pointer must correspond to a function
written in C or C++. It is not possible to pass an arbitrary Go
function in as a substitute for a C function pointer.
</ul>
<hr>
</body>
</html>

View file

@ -0,0 +1,25 @@
package main
import (
"fmt"
. "./example"
)
func main() {
a := 37
b := 42
// Now call our C function with a bunch of callbacks
fmt.Println("Trying some C callback functions")
fmt.Println(" a = ", a)
fmt.Println(" b = ", b)
fmt.Println(" ADD(a,b) = ", Do_op(a, b, ADD))
fmt.Println(" SUB(a,b) = ", Do_op(a, b, SUB))
fmt.Println(" MUL(a,b) = ", Do_op(a, b, MUL))
fmt.Println("Here is what the C callback function classes are called in Go")
fmt.Println(" ADD = ", ADD)
fmt.Println(" SUB = ", SUB)
fmt.Println(" MUL = ", MUL)
}

89
Examples/go/index.html Normal file
View file

@ -0,0 +1,89 @@
<html>
<head>
<title>SWIG:Examples:Go</title>
</head>
<body bgcolor="#ffffff">
<H1>SWIG Go Examples</H1>
<p>
The following examples illustrate the use of SWIG with Go.
<ul>
<li><a href="simple/index.html">simple</a>. A minimal example showing how SWIG can
be used to wrap a C function, a global variable, and a constant.
<li><a href="constants/index.html">constants</a>. This shows how preprocessor macros and
certain C declarations are turned into constants.
<li><a href="variables/index.html">variables</a>. An example showing how to access C global variables from Go.
<li><a href="enum/index.html">enum</a>. Wrapping enumerations.
<li><a href="class/index.html">class</a>. Wrapping a simple C++ class.
<li><a href="reference/index.html">reference</a>. C++ references.
<li><a href="pointer/index.html">pointer</a>. Simple pointer handling.
<li><a href="funcptr/index.html">funcptr</a>. Pointers to functions.
<li><a href="template/index.html">template</a>. C++ templates.
<li><a href="callback/index.html">callback</a>. C++ callbacks using directors.
<li><a href="extend/index.html">extend</a>. Polymorphism using directors.
</ul>
<h2>Compilation Issues</h2>
<ul>
<li>To create a Go extension, SWIG is run with the following options:
<blockquote>
<pre>
% swig -go interface.i
</pre>
</blockquote>
<li>On Unix the compilation of examples is done using the
file <tt>Example/Makefile</tt>. This makefile performs a manual
module compilation which is platform specific. When using
the <tt>6g</tt> or <tt>8g</tt> compiler, the steps look like this
(GNU/Linux):
<blockquote>
<pre>
% swig -go interface.i
% gcc -fpic -c interface_wrap.c
% gcc -shared interface_wrap.o $(OBJS) -o interfacemodule.so
% 6g interface.go
% 6c interface_gc.c
% gopack grc interface.a interface.6 interface_gc.6
% 6l program.6
</pre>
</blockquote>
<li>When using the <tt>gccgo</tt> compiler, the steps look like this:
<blockquote>
<pre>
% swig -go interface.i
% gcc -c interface_wrap.c
% gccgo -c interface.go
% gccgo program.o interface.o interface_wrap.o
</pre>
</blockquote
</ul>
<h2>Compatibility</h2>
The examples have been extensively tested on the following platforms:
<ul>
<li>GNU/Linux
</ul>
All of the examples were last tested with the following configuration
(10 May 2010):
<ul>
<li>Ubuntu Hardy
<li>gcc-4.2.4
</ul>
Your mileage may vary. If you experience a problem, please let us know by
contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
</body>
</html>

View file

@ -0,0 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
SWIGOPT =
all:: go
go::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
clean::
$(MAKE) -f $(TOP)/Makefile go_clean
check: all
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run

View file

@ -0,0 +1,53 @@
/* File : example.c */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
int gcdmain(int argc, char *argv[]) {
int x,y;
if (argc != 3) {
printf("usage: gcd x y\n");
return -1;
}
x = atoi(argv[1]);
y = atoi(argv[2]);
printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y));
return 0;
}
int count(char *bytes, int len, char c) {
int i;
int count = 0;
for (i = 0; i < len; i++) {
if (bytes[i] == c) count++;
}
return count;
}
void capitalize(char *str, int len) {
int i;
for (i = 0; i < len; i++) {
str[i] = (char)toupper(str[i]);
}
}
void circle(double x, double y) {
double a = x*x + y*y;
if (a > 1.0) {
printf("Bad points %g, %g\n", x,y);
} else {
printf("Good points %g, %g\n", x,y);
}
}

View file

@ -0,0 +1,55 @@
/* ----------------------------------------------------------------------------
* 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))
}
func Gcd(int, int) int
func Gcdmain([]string) int
func Count(string, byte) int
func _swig_wrap_capitalize([]string)
func Capitalize(arg1 []string) {
_swig_wrap_capitalize(arg1)
}
func _swig_wrap_circle(float64, float64)
func Circle(arg1 float64, arg2 float64) {
_swig_wrap_circle(arg1, arg2)
}
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,110 @@
/* File : example.i */
%module example
%{
extern int gcd(int x, int y);
extern int gcdmain(int argc, char *argv[]);
extern int count(char *bytes, int len, char c);
extern void capitalize (char *str, int len);
extern void circle (double cx, double cy);
extern int squareCubed (int n, int *OUTPUT);
%}
extern int gcd(int x, int y);
%typemap(go) (int argc, char *argv[]) "[]string"
%typemap(in) (int argc, char *argv[])
%{
{
int i;
_gostring_* a;
$1 = $input.len;
a = (_gostring_*) $input.array;
$2 = (char **) malloc (($1 + 1) * sizeof (char *));
for (i = 0; i < $1; i++) {
_gostring_ *ps = &a[i];
$2[i] = (char *) ps->p;
}
$2[i] = NULL;
}
%}
%typemap(argout) (int argc, char *argv[]) "" /* override char *[] default */
%typemap(freearg) (int argc, char *argv[])
%{
free($2);
%}
extern int gcdmain(int argc, char *argv[]);
%typemap(go) (char *bytes, int len) "string"
%typemap(in) (char *bytes, int len)
%{
$1 = $input.p;
$2 = $input.n;
%}
extern int count(char *bytes, int len, char c);
/* This example shows how to wrap a function that mutates a c string. A one
* element Go string slice is used so that the string can be returned
* modified.
*/
%typemap(go) (char *str, int len) "[]string"
%typemap(in) (char *str, int len)
%{
{
_gostring_ *a;
char *p;
int n;
a = (_gostring_*) $input.array;
p = a[0].p;
n = a[0].n;
$1 = malloc(n + 1);
$2 = n;
memcpy($1, p, n);
}
%}
/* Return the mutated string as a modified element in the array. */
%typemap(argout) (char *str, int len)
%{
{
_gostring_ *a;
a = (_gostring_*) $input.array;
a[0] = _swig_makegostring($1, $2);
}
%}
%typemap(freearg) (char *str, int len)
%{
free($1);
%}
extern void capitalize(char *str, int len);
/* A multi-valued constraint. Force two arguments to lie
inside the unit circle */
%typemap(check) (double cx, double cy)
%{
{
double a = $1*$1 + $2*$2;
if (a > 1.0) {
_swig_gopanic("$1_name and $2_name must be in unit circle");
return;
}
}
%}
extern void circle(double cx, double cy);

View file

@ -0,0 +1,26 @@
package main
import (
"fmt"
. "./example"
)
func main() {
// Call our gcd() function
x := 42
y := 105
g := Gcd(x, y)
fmt.Println("The gcd of ", x, " and ", y, " is ", g)
// Call the gcdmain() function
args := []string{"gcdmain", "42", "105"}
Gcdmain(args)
// Call the count function
fmt.Println(Count("Hello World", 'l'))
// Call the capitalize function
capitalizeMe := []string{"hello world"}
Capitalize(capitalizeMe)
fmt.Println(capitalizeMe[0])
}

View file

@ -0,0 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
SWIGOPT =
all:: go
go::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
clean::
$(MAKE) -f $(TOP)/Makefile go_clean
check: all
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run

View file

@ -0,0 +1,16 @@
/* File : example.c */
void add(int *x, int *y, int *result) {
*result = *x + *y;
}
void sub(int *x, int *y, int *result) {
*result = *x - *y;
}
int divide(int n, int d, int *r) {
int q;
q = n/d;
*r = n - q*d;
return q;
}

View file

@ -0,0 +1,68 @@
/* ----------------------------------------------------------------------------
* 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))
}
func _swig_wrap_add(*int, *int, *int)
func Add(arg1 *int, arg2 *int, arg3 *int) {
_swig_wrap_add(arg1, arg2, arg3)
}
func New_intp() *int
func Copy_intp(int) *int
func _swig_wrap_delete_intp(*int)
func Delete_intp(arg1 *int) {
_swig_wrap_delete_intp(arg1)
}
func _swig_wrap_intp_assign(*int, int)
func Intp_assign(arg1 *int, arg2 int) {
_swig_wrap_intp_assign(arg1, arg2)
}
func Intp_value(*int) int
func _swig_wrap_sub(int, int, []int)
func Sub(arg1 int, arg2 int, arg3 []int) {
_swig_wrap_sub(arg1, arg2, arg3)
}
func Divide(int, int, []int) int
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,30 @@
/* File : example.i */
%module example
%{
extern void add(int *, int *, int *);
extern void sub(int *, int *, int *);
extern int divide(int, int, int *);
%}
/* This example illustrates a couple of different techniques
for manipulating C pointers */
/* First we'll use the pointer library */
extern void add(int *x, int *y, int *result);
%include cpointer.i
%pointer_functions(int, intp);
/* Next we'll use some typemaps */
%include typemaps.i
extern void sub(int *INPUT, int *INPUT, int *OUTPUT);
/* Next we'll use typemaps and the %apply directive */
%apply int *OUTPUT { int *r };
extern int divide(int n, int d, int *r);

View file

@ -0,0 +1,143 @@
<html>
<head>
<title>SWIG:Examples:go:pointer</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/pointer/</tt>
<hr>
<H2>Simple Pointer Handling</H2>
<p>
This example illustrates a couple of techniques for handling simple
pointers in SWIG. The prototypical example is a C function that
operates on pointers such as this:
<blockquote>
<pre>
void add(int *x, int *y, int *r) {
*r = *x + *y;
}
</pre>
</blockquote>
By default, SWIG wraps this function exactly as specified and creates
an interface that expects pointer objects for arguments. This only
works when there is a precise correspondence between the C type and
some Go type.
<p>
<h2>Other approaches</h2>
<p>
<li>The SWIG pointer library provides a different, safer, way to
handle pointers. For example, in the interface file you would do
this:
<blockquote>
<pre>
%include cpointer.i
%pointer_functions(int, intp);
</pre>
</blockquote>
and from Go you would use pointers like this:
<blockquote>
<pre>
a := example.New_intp()
b := example.New_intp()
c := example.New_intp()
Intp_Assign(a, 37)
Intp_Assign(b, 42)
fmt.Println(" a =", a)
fmt.Println(" b =", b)
fmt.Println(" c =", c)
// Call the add() function with some pointers
example.Add(a,b,c)
// Now get the result
res := example.Intp_value(c)
fmt.Println(" 37 + 42 =", res)
// Clean up the pointers
example.Delete_intp(a)
example.Delete_intp(b)
example.Delete_intp(c)
</pre>
</blockquote>
<p>
<li>Use the SWIG typemap library. This library allows you to
completely change the way arguments are processed by SWIG. For
example:
<blockquote>
<pre>
%include "typemaps.i"
void add(int *INPUT, int *INPUT, int *OUTPUT);
</pre>
</blockquote>
And in a Go program:
<blockquote>
<pre>
r := []int{0}
example.Sub(37,42,r)
fmt.Println("Result =", r[0])
</pre>
</blockquote>
Needless to say, this is substantially easier although a bit unusual.
<p>
<li>A final alternative is to use the typemaps library in combination
with the %apply directive. This allows you to change the names of parameters
that behave as input or output parameters. For example:
<blockquote>
<pre>
%include "typemaps.i"
%apply int *INPUT {int *x, int *y};
%apply int *OUTPUT {int *r};
void add(int *x, int *y, int *r);
void sub(int *x, int *y, int *r);
void mul(int *x, int *y, int *r);
... etc ...
</pre>
</blockquote>
</ul>
<h2>Example</h2>
The following example illustrates the use of these features for pointer
extraction.
<ul>
<li> <a href="example.c">example.c</a> (C Source)
<li> <a href="example.i">example.i</a> (SWIG interface)
<li> <a href="runme.go">runme.go</a> (Go program)
</ul>
<h2>Notes</h2>
<ul>
<li>Since pointers are used for so many different things (arrays, output values,
etc...) the complexity of pointer handling can be as complicated as you want to
make it.
<p>
<li>More documentation on the typemaps.i and cpointer.i library files can be
found in the SWIG user manual. The files also contain documentation.
</ul>
<hr>
</body>
</html>

View file

@ -0,0 +1,47 @@
package main
import (
"fmt"
. "./example"
)
func main() {
// First create some objects using the pointer library.
fmt.Println("Testing the pointer library")
a := New_intp()
b := New_intp()
c := New_intp()
Intp_assign(a, 37)
Intp_assign(b, 42)
fmt.Println(" a =", a)
fmt.Println(" b =", b)
fmt.Println(" c =", c)
// Call the add() function with some pointers
Add(a, b, c)
// Now get the result
res := Intp_value(c)
fmt.Println(" 37 + 42 =", res)
// Clean up the pointers
Delete_intp(a)
Delete_intp(b)
Delete_intp(c)
// Now try the typemap library
// Now it is no longer necessary to manufacture pointers.
// Instead we use a single element array which in Java is modifiable.
fmt.Println("Trying the typemap library")
r := []int{0}
Sub(37, 42, r)
fmt.Println(" 37 - 42 = ", r[0])
// Now try the version with return value
fmt.Println("Testing return value")
q := Divide(42, 37, r)
fmt.Println(" 42/37 = ", q, " remainder ", r[0])
}

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)
}

View file

@ -0,0 +1,15 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
clean::
$(MAKE) -f $(TOP)/Makefile go_clean
check: all
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run

View file

@ -0,0 +1,18 @@
/* File : example.c */
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}

View file

@ -0,0 +1,48 @@
/* ----------------------------------------------------------------------------
* 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))
}
func Gcd(int, int) int
func _swig_wrap_Foo_set(float64)
func SetFoo(arg1 float64) {
_swig_wrap_Foo_set(arg1)
}
func GetFoo() float64
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,7 @@
/* File : example.i */
%module example
%inline %{
extern int gcd(int x, int y);
extern double Foo;
%}

View file

@ -0,0 +1,126 @@
<html>
<head>
<title>SWIG:Examples:go:simple</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/simple/</tt>
<hr>
<H2>Simple Go Example</H2>
<p>
This example illustrates how you can hook Go to a very simple C program containing
a function and a global variable.
<h2>The C Code</h2>
Suppose you have the following C code:
<blockquote>
<pre>
/* File : example.c */
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x &gt; 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
</pre>
</blockquote>
<h2>The SWIG interface</h2>
Here is a simple SWIG interface file:
<blockquote>
<pre>
/* File: example.i */
%module example
extern int gcd(int x, int y);
extern double Foo;
</pre>
</blockquote>
<h2>Compilation</h2>
These are the instructions if you are using <tt>6g</tt>/<tt>8g</tt>
rather than <tt>gccgo</tt>.
<ol>
<li>Run <tt>swig -go <a href="example.i">example.i</a></tt>. This
will create the three
files <tt>example.go</tt>, <tt>example_gc.c</tt>,
and <tt>example_wrap.c</tt>.
<li>Compile <tt><a href="example.go">example.go</a></tt>
using <tt>6g</tt> or <tt>8g</tt>; e.g., <tt>6g example.go</tt>.
<li>Compile <tt><a href="example_gc.c">example_gc.c</a></tt>
using <tt>6c</tt> or <tt>8c</tt>; e.g., <tt>6c example_gc.c</tt>.
<li>Put the two object files together into an archive
named <tt>example.a</tt>; e.g., <tt>gopack grc example.a example.6
example_gc.6</tt>.
<li>Compile the <tt><a href="example_wrap.c">example_wrap.c</a></tt>
file using your standard C compiler with the <tt>-fpic</tt> option;
e.g., <tt>gcc -c -O -fpic example_wrap.c</tt>.
<li>Put the gcc compiled object file into a shared library;
e.g., <tt>gcc -shared -o example.so example_wrap.o</tt>.
<li>Compile the program which demonstrates how to use the library;
e.g., <tt>6g runme.go</tt>.
<li>Link the program; e.g., <tt>6l -o runme runme.6</tt>.
<li>Now you should have a program <tt>runme</tt>.
</ol>
<h2>Using the extension</h2>
The Go program which demonstrates calling the C functions from Go
is <a href="runme.go">runme.go</a>.
<h2>Key points</h2>
<ul>
<li>Use the <tt>import</tt> statement to load your extension module from Go. For example:
<blockquote>
<pre>
import "example"
</pre>
</blockquote>
<li>C functions work just like Go functions. However, the function
names are automatically capitalized in order to make the names
visible from other Go packages. For example:
<blockquote>
<pre>
g := example.Gcd(42,105)
</pre>
</blockquote>
(If there are name conflicts, you can use the <tt>%rename</tt>
directive in the .i file or the <tt>-rename</tt> option to Go to
rename one or the other symbol).
<li>C global variables are accessed using getter and setter
functions. The getter function is named <tt>Get</tt> followed by
the capitalized name of the C variable. The Setter function
uses <tt>Set</tt> instead of <tt>Get</tt>.
<blockquote>
<pre>
a = example.GetFoo()
</pre>
</blockquote>
</ul>
<hr>
</body>
</html>

View file

@ -0,0 +1,25 @@
package main
import (
"fmt"
"./example"
)
func main() {
// Call our gcd() function
x := 42
y := 105
g := example.Gcd(x, y)
fmt.Println("The gcd of", x, "and", y, "is", g)
// Manipulate the Foo global variable
// Output its current value
fmt.Println("Foo =", example.GetFoo())
// Change its value
example.SetFoo(3.1415926)
// See if the change took effect
fmt.Println("Foo =", example.GetFoo())
}

View file

@ -0,0 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS =
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,150 @@
/* ----------------------------------------------------------------------------
* 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))
}
func Maxint(int, int) int
func Maxdouble(float64, float64) float64
type SwigcptrVecint uintptr
func (p SwigcptrVecint) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrVecint) SwigIsVecint() {
}
func _swig_wrap_new_vecint(int) SwigcptrVecint
func NewVecint(arg1 int) Vecint {
return _swig_wrap_new_vecint(arg1)
}
func _swig_wrap_vecint_get(SwigcptrVecint, int) *int
func (arg1 SwigcptrVecint) Get(arg2 int) *int {
return _swig_wrap_vecint_get(arg1, arg2)
}
func _swig_wrap_vecint_set(SwigcptrVecint, int, *int)
func (arg1 SwigcptrVecint) Set(arg2 int, arg3 *int) {
_swig_wrap_vecint_set(arg1, arg2, arg3)
}
func _swig_wrap_vecint_getitem(SwigcptrVecint, int) int
func (arg1 SwigcptrVecint) Getitem(arg2 int) int {
return _swig_wrap_vecint_getitem(arg1, arg2)
}
func _swig_wrap_vecint_setitem(SwigcptrVecint, int, int)
func (arg1 SwigcptrVecint) Setitem(arg2 int, arg3 int) {
_swig_wrap_vecint_setitem(arg1, arg2, arg3)
}
func _swig_wrap_delete_vecint(uintptr)
func DeleteVecint(arg1 Vecint) {
_swig_wrap_delete_vecint(arg1.Swigcptr())
}
type Vecint interface {
Swigcptr() uintptr
SwigIsVecint()
Get(arg2 int) *int
Set(arg2 int, arg3 *int)
Getitem(arg2 int) int
Setitem(arg2 int, arg3 int)
}
type SwigcptrVecdouble uintptr
func (p SwigcptrVecdouble) Swigcptr() uintptr {
return (uintptr)(p)
}
func (p SwigcptrVecdouble) SwigIsVecdouble() {
}
func _swig_wrap_new_vecdouble(int) SwigcptrVecdouble
func NewVecdouble(arg1 int) Vecdouble {
return _swig_wrap_new_vecdouble(arg1)
}
func _swig_wrap_vecdouble_get(SwigcptrVecdouble, int) *float64
func (arg1 SwigcptrVecdouble) Get(arg2 int) *float64 {
return _swig_wrap_vecdouble_get(arg1, arg2)
}
func _swig_wrap_vecdouble_set(SwigcptrVecdouble, int, *float64)
func (arg1 SwigcptrVecdouble) Set(arg2 int, arg3 *float64) {
_swig_wrap_vecdouble_set(arg1, arg2, arg3)
}
func _swig_wrap_vecdouble_getitem(SwigcptrVecdouble, int) float64
func (arg1 SwigcptrVecdouble) Getitem(arg2 int) float64 {
return _swig_wrap_vecdouble_getitem(arg1, arg2)
}
func _swig_wrap_vecdouble_setitem(SwigcptrVecdouble, int, float64)
func (arg1 SwigcptrVecdouble) Setitem(arg2 int, arg3 float64) {
_swig_wrap_vecdouble_setitem(arg1, arg2, arg3)
}
func _swig_wrap_delete_vecdouble(uintptr)
func DeleteVecdouble(arg1 Vecdouble) {
_swig_wrap_delete_vecdouble(arg1.Swigcptr())
}
type Vecdouble interface {
Swigcptr() uintptr
SwigIsVecdouble()
Get(arg2 int) *float64
Set(arg2 int, arg3 *float64)
Getitem(arg2 int) float64
Setitem(arg2 int, arg3 float64)
}
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,32 @@
/* File : example.h */
// Some template definitions
template<class T> T max(T a, T b) { return a>b ? a : b; }
template<class T> class vector {
T *v;
int sz;
public:
vector(int _sz) {
v = new T[_sz];
sz = _sz;
}
T &get(int index) {
return v[index];
}
void set(int index, T &val) {
v[index] = val;
}
#ifdef SWIG
%extend {
T getitem(int index) {
return $self->get(index);
}
void setitem(int index, T val) {
$self->set(index,val);
}
}
#endif
};

View file

@ -0,0 +1,17 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"
/* Now instantiate some specific template declarations */
%template(maxint) max<int>;
%template(maxdouble) max<double>;
%template(vecint) vector<int>;
%template(vecdouble) vector<double>;

View file

@ -0,0 +1,113 @@
<html>
<head>
<title>SWIG:Examples:go:template</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/template/</tt>
<hr>
<H2>C++ template support</H2>
<p>
This example illustrates how C++ templates can be used from Go using
SWIG.
<h2>The C++ Code</h2>
Lets take a templated function and a templated class as follows:
<blockquote>
<pre>
/* File : example.h */
// Some template definitions
template<class T> T max(T a, T b) { return a&gt;b ? a : b; }
template<class T> class vector {
T *v;
int sz;
public:
vector(int _sz) {
v = new T[_sz];
sz = _sz;
}
T &amp;get(int index) {
return v[index];
}
void set(int index, T &amp;val) {
v[index] = val;
}
#ifdef SWIG
%addmethods {
T getitem(int index) {
return self-&gt;get(index);
}
void setitem(int index, T val) {
self-&gt;set(index,val);
}
}
#endif
};
</pre>
</blockquote>
The %addmethods is used for a neater interface from Go as the
functions <tt>get</tt> and <tt>set</tt> use C++ references to
primitive types. These are tricky to use from Go as they end up as
pointers, which only work when the C++ and Go types correspond
precisely.
<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"
/* Now instantiate some specific template declarations */
%template(maxint) max<int>;
%template(maxdouble) max<double>;
%template(vecint) vector<int>;
%template(vecdouble) vector<double>;
</pre>
</blockquote>
Note that SWIG parses the templated function <tt>max</tt> and
templated class <tt>vector</tt> and so knows about them. However to
generate code for use from Go, SWIG has to be told which class/type to
use as the template parameter. The SWIG directive %template is used
for this.
<h2>A sample Go program</h2>
Click <a href="runme.go">here</a> to see a Go program that calls the
C++ functions from Go.
<h2>Notes</h2> Use templated classes just like you would any other
SWIG generated Go class. Use the classnames specified by the %template
directive.
<blockquote>
<pre>
vecdouble dv = new vecdouble(1000);
dv.setitem(i, 12.34));
</pre>
</blockquote>
<hr>
</body>
</html>

View file

@ -0,0 +1,43 @@
// This example illustrates how C++ templates can be used from Go.
package main
import (
"fmt"
. "./example"
)
func main() {
// Call some templated functions
fmt.Println(Maxint(3, 7))
fmt.Println(Maxdouble(3.14, 2.18))
// Create some class
iv := NewVecint(100)
dv := NewVecdouble(1000)
for i := 0; i < 100; i++ {
iv.Setitem(i, 2*i)
}
for i := 0; i < 1000; i++ {
dv.Setitem(i, 1.0/float64(i+1))
}
{
sum := 0
for i := 0; i < 100; i++ {
sum = sum + iv.Getitem(i)
}
fmt.Println(sum)
}
{
sum := float64(0.0)
for i := 0; i < 1000; i++ {
sum = sum + dv.Getitem(i)
}
fmt.Println(sum)
}
}

View file

@ -0,0 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
SWIGOPT =
all:: go
go::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
clean::
$(MAKE) -f $(TOP)/Makefile go_clean
check: all
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run

View file

@ -0,0 +1,91 @@
/* File : example.c */
/* I'm a file containing some C global variables */
/* 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 <stdio.h>
#include <stdlib.h>
#include "example.h"
int ivar = 0;
short svar = 0;
long lvar = 0;
unsigned int uivar = 0;
unsigned short usvar = 0;
unsigned long ulvar = 0;
signed char scvar = 0;
unsigned char ucvar = 0;
char cvar = 0;
float fvar = 0;
double dvar = 0;
char *strvar = 0;
const char cstrvar[] = "Goodbye";
int *iptrvar = 0;
char name[256] = "Dave";
char path[256] = "/home/beazley";
/* Global variables involving a structure */
Point *ptptr = 0;
Point pt = { 10, 20 };
/* A variable that we will make read-only in the interface */
int status = 1;
/* A debugging function to print out their values */
void print_vars() {
printf("ivar = %d\n", ivar);
printf("svar = %d\n", svar);
printf("lvar = %ld\n", lvar);
printf("uivar = %u\n", uivar);
printf("usvar = %u\n", usvar);
printf("ulvar = %lu\n", ulvar);
printf("scvar = %d\n", scvar);
printf("ucvar = %u\n", ucvar);
printf("fvar = %g\n", fvar);
printf("dvar = %g\n", dvar);
printf("cvar = %c\n", cvar);
printf("strvar = %s\n", strvar ? strvar : "(null)");
printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)");
printf("iptrvar = %p\n", iptrvar);
printf("name = %s\n", name);
printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0);
printf("pt = (%d, %d)\n", pt.x, pt.y);
printf("status = %d\n", status);
}
/* A function to create an integer (to test iptrvar) */
int *new_int(int value) {
int *ip = (int *) malloc(sizeof(int));
*ip = value;
return ip;
}
/* A function to create a point */
Point *new_Point(int x, int y) {
Point *p = (Point *) malloc(sizeof(Point));
p->x = x;
p->y = y;
return p;
}
char * Point_print(Point *p) {
static char buffer[256];
if (p) {
sprintf(buffer,"(%d,%d)", p->x,p->y);
} else {
sprintf(buffer,"null");
}
return buffer;
}
void pt_print() {
printf("(%d, %d)\n", pt.x, pt.y);
}

View file

@ -0,0 +1,198 @@
/* ----------------------------------------------------------------------------
* 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))
}
func _swig_wrap_ivar_set(int)
func SetIvar(arg1 int) {
_swig_wrap_ivar_set(arg1)
}
func GetIvar() int
func _swig_wrap_svar_set(int16)
func SetSvar(arg1 int16) {
_swig_wrap_svar_set(arg1)
}
func GetSvar() int16
func _swig_wrap_lvar_set(int32)
func SetLvar(arg1 int32) {
_swig_wrap_lvar_set(arg1)
}
func GetLvar() int32
func _swig_wrap_uivar_set(uint)
func SetUivar(arg1 uint) {
_swig_wrap_uivar_set(arg1)
}
func GetUivar() uint
func _swig_wrap_usvar_set(uint16)
func SetUsvar(arg1 uint16) {
_swig_wrap_usvar_set(arg1)
}
func GetUsvar() uint16
func _swig_wrap_ulvar_set(uint32)
func SetUlvar(arg1 uint32) {
_swig_wrap_ulvar_set(arg1)
}
func GetUlvar() uint32
func _swig_wrap_scvar_set(int8)
func SetScvar(arg1 int8) {
_swig_wrap_scvar_set(arg1)
}
func GetScvar() int8
func _swig_wrap_ucvar_set(byte)
func SetUcvar(arg1 byte) {
_swig_wrap_ucvar_set(arg1)
}
func GetUcvar() byte
func _swig_wrap_cvar_set(byte)
func SetCvar(arg1 byte) {
_swig_wrap_cvar_set(arg1)
}
func GetCvar() byte
func _swig_wrap_fvar_set(float32)
func SetFvar(arg1 float32) {
_swig_wrap_fvar_set(arg1)
}
func GetFvar() float32
func _swig_wrap_dvar_set(float64)
func SetDvar(arg1 float64) {
_swig_wrap_dvar_set(arg1)
}
func GetDvar() float64
func _swig_wrap_strvar_set(string)
func SetStrvar(arg1 string) {
_swig_wrap_strvar_set(arg1)
}
func GetStrvar() string
func GetCstrvar() string
func _swig_wrap_iptrvar_set(*int)
func SetIptrvar(arg1 *int) {
_swig_wrap_iptrvar_set(arg1)
}
func GetIptrvar() *int
func _swig_wrap_name_set(string)
func SetName(arg1 string) {
_swig_wrap_name_set(arg1)
}
func GetName() string
func _swig_wrap_ptptr_set(uintptr)
func SetPtptr(arg1 Point) {
_swig_wrap_ptptr_set(arg1.Swigcptr())
}
func _swig_wrap_ptptr_get() SwigcptrPoint
func GetPtptr() Point {
return _swig_wrap_ptptr_get()
}
func _swig_wrap_pt_set(uintptr)
func SetPt(arg1 Point) {
_swig_wrap_pt_set(arg1.Swigcptr())
}
func _swig_wrap_pt_get() SwigcptrPoint
func GetPt() Point {
return _swig_wrap_pt_get()
}
func GetStatus() int
func GetPath() string
func _swig_wrap_print_vars()
func Print_vars() {
_swig_wrap_print_vars()
}
func New_int(int) *int
func _swig_wrap_new_Point(int, int) SwigcptrPoint
func New_Point(arg1 int, arg2 int) Point {
return _swig_wrap_new_Point(arg1, arg2)
}
func _swig_wrap_Point_print(uintptr) string
func Point_print(arg1 Point) string {
return _swig_wrap_Point_print(arg1.Swigcptr())
}
func _swig_wrap_pt_print()
func Pt_print() {
_swig_wrap_pt_print()
}
type SwigcptrPoint uintptr
type Point interface {
Swigcptr() uintptr;
}
func (p SwigcptrPoint) Swigcptr() uintptr {
return uintptr(p)
}
type SwigcptrVoid uintptr
type Void interface {
Swigcptr() uintptr;
}
func (p SwigcptrVoid) Swigcptr() uintptr {
return uintptr(p)
}

View file

@ -0,0 +1,6 @@
/* File: example.h */
typedef struct {
int x,y;
} Point;

View file

@ -0,0 +1,49 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Some global variable declarations */
%inline %{
extern int ivar;
extern short svar;
extern long lvar;
extern unsigned int uivar;
extern unsigned short usvar;
extern unsigned long ulvar;
extern signed char scvar;
extern unsigned char ucvar;
extern char cvar;
extern float fvar;
extern double dvar;
extern char *strvar;
extern const char cstrvar[];
extern int *iptrvar;
extern char name[256];
extern Point *ptptr;
extern Point pt;
%}
/* Some read-only variables */
%immutable;
%inline %{
extern int status;
extern char path[256];
%}
%mutable;
/* Some helper functions to make it easier to test */
%inline %{
extern void print_vars();
extern int *new_int(int value);
extern Point *new_Point(int x, int y);
extern char *Point_print(Point *p);
extern void pt_print();
%}

View file

@ -0,0 +1,87 @@
<html>
<head>
<title>SWIG:Examples:go:variables</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/variables/</tt>
<hr>
<H2>Wrapping C Global Variables</H2>
<p>
When a C global variable appears in an interface file, SWIG provides
getter and setter functions for the variable. The getter function is
named <tt>Get</tt> followed by the capitalized name of the variable.
The setter variable starts with <tt>Set</tt> instead. The getter
function takes no parameters and returns the value of the variable.
The setter function takes a single parameter with the same type as the
variable, and returns nothing.
<p>Click <a href="example.i">here</a> to see a SWIG interface with
some variable declarations in it.
<h2>Manipulating Variables from Go</h2>
For example, if the package is called <tt>example</tt>, the global
variable
<blockquote>
<pre>
double foo;
</pre>
</blockquote>
will be accessed from Go as
<blockquote>
<pre>
example.GetFoo();
example.SetFoo(12.3);
</pre>
</blockquote>
Click <a href="runme.go">here</a> to see the example program that
updates and prints out the values of the variables using this
technique.
<h2>Key points</h2>
<ul>
<li>The name of the variable is capitalized.
<li>When a global variable has the type "<tt>char *</tt>", SWIG
manages it as a character string.
<li><tt>signed char</tt> and <tt>unsigned char</tt> are handled as
small 8-bit integers.
<li>String array variables such as '<tt>char name[256]</tt>' are
managed as Go strings, but when setting the value, the result is
truncated to the maximum length of the array. Furthermore, the string
is assumed to be null-terminated.
<li>When structures and classes are used as global variables, they are
mapped into pointers. Getting the "value" returns a pointer to the
global variable. Setting the value of a structure results in a memory
copy from a pointer to the global.
</ul>
<h2>Creating read-only variables</h2>
The <tt>%immutable</tt> and <tt>%mutable</tt> directives can be used
to specify a collection of read-only variables. A read only variable
will have a getter function but no setter function. For example:
<blockquote>
<pre>
%immutable;
int status;
double blah;
...
%mutable;
</pre>
</blockquote>
The <tt>%immutable</tt> directive remains in effect until it is
explicitly disabled using the <tt>%mutable</tt> directive.
</body>
</html>
<hr>

View file

@ -0,0 +1,67 @@
// This example illustrates global variable access from Go.
package main
import (
"fmt"
"./example"
)
func main() {
// Try to set the values of some global variables
example.SetIvar(42)
example.SetSvar(-31000)
example.SetLvar(65537)
example.SetUivar(123456)
example.SetUsvar(61000)
example.SetUlvar(654321)
example.SetScvar(-13)
example.SetUcvar(251)
example.SetCvar('S')
example.SetFvar(3.14159)
example.SetDvar(2.1828)
example.SetStrvar("Hello World")
example.SetIptrvar(example.New_int(37))
example.SetPtptr(example.New_Point(37, 42))
example.SetName("Bill")
// Now print out the values of the variables
fmt.Println("Variables (values printed from Go)")
fmt.Println("ivar =", example.GetIvar())
fmt.Println("svar =", example.GetSvar())
fmt.Println("lvar =", example.GetLvar())
fmt.Println("uivar =", example.GetUivar())
fmt.Println("usvar =", example.GetUsvar())
fmt.Println("ulvar =", example.GetUlvar())
fmt.Println("scvar =", example.GetScvar())
fmt.Println("ucvar =", example.GetUcvar())
fmt.Println("fvar =", example.GetFvar())
fmt.Println("dvar =", example.GetDvar())
fmt.Printf("cvar = %c\n", example.GetCvar())
fmt.Println("strvar =", example.GetStrvar())
fmt.Println("cstrvar =", example.GetCstrvar())
fmt.Println("iptrvar =", example.GetIptrvar())
fmt.Println("name =", example.GetName())
fmt.Println("ptptr =", example.GetPtptr(), example.Point_print(example.GetPtptr()))
fmt.Println("pt =", example.GetPt(), example.Point_print(example.GetPt()))
fmt.Println("\nVariables (values printed from C)")
example.Print_vars()
// This line would not compile: since status is marked with
// %immutable, there is no SetStatus function.
// fmt.Println("\nNow I'm going to try and modify some read only variables")
// example.SetStatus(0)
fmt.Println("\nI'm going to try and update a structure variable.\n")
example.SetPt(example.GetPtptr())
fmt.Println("The new value is")
example.Pt_print()
fmt.Println("You should see the value", example.Point_print(example.GetPtptr()))
}

View file

@ -1,7 +1,7 @@
/* File : example.i */
%module dynamic_cast
#if !defined(SWIGJAVA) && !defined(SWIGCSHARP)
#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO)
%apply SWIGTYPE *DYNAMIC { Foo * };
#endif
@ -17,7 +17,7 @@ public:
};
%}
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGO)
%typemap(out) Foo *blah {
Bar *downcast = dynamic_cast<Bar *>($1);
*(Bar **)&$result = downcast;
@ -37,6 +37,14 @@ public:
}
#endif
#if defined(SWIGGO)
%insert(go_runtime) %{
func FooToBar(f Foo) Bar {
return SwigcptrBar(f.Swigcptr())
}
%}
#endif
%inline %{
class Bar : public Foo {
@ -54,7 +62,7 @@ char *do_test(Bar *b) {
}
%}
#if !defined(SWIGJAVA) && !defined(SWIGCSHARP)
#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO)
// A general purpose function for dynamic casting of a Foo *
%{
static swig_type_info *

View file

@ -0,0 +1,110 @@
#######################################################################
# Makefile for Go test-suite
#######################################################################
LANGUAGE = go
GO = 6g
GOGCC = false
SCRIPTSUFFIX = _runme.go
GOCOMPILEARG = `if $(GOGCC) ; then echo -c -g; fi`
GOC = $(GO:g=c)
GOLD = $(GO:g=l)
GOOBJEXT = $(GO:g=)
SO = @SO@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
include $(srcdir)/../common.mk
# Custom tests - tests with additional commandline options
constant_pointers.cpptest: SWIGOPT += -rename foo=foofn
director_enum.cpptest: SWIGOPT += -rename Hello=Helloe
director_finalizer.cpptest: SWIGOPT += -rename deleteFoo=deleteFooFn
enum_thorough.cpptest: SWIGOPT += -rename One=Onee -rename Two=Twoe
mixed_types.cpptest: SWIGOPT += -rename Hello=Helloe
overload_simple.cpptest: SWIGOPT += -rename foo=foofn
smart_pointer_extend.cpptest: SWIGOPT += -rename CPtrFoo=CPtrFoos
smart_pointer_member.cpptest: SWIGOPT += -rename Foo=Foos
special_variable_macros.cpptest: SWIGOPT += -rename Name=Names
template_partial_specialization.cpptest: SWIGOPT += -rename b=bfn
template_partial_specialization_typedef.cpptest: SWIGOPT += -rename b=bfn
template_specialization_enum.cpptest: SWIGOPT += -rename Hello=Helloe
preproc.ctest: SWIGOPT += -rename a5=a5c -rename a6=a6c
mod.multicpptest: SWIGOPT += -rename GetC=GetCFn
.SUFFIXES: .cpptest .ctest .multicpptest
# Rules for the different types of tests
%.cpptest:
$(setup)
+$(swig_and_compile_cpp)
$(run_testcase)
%.ctest:
$(setup)
+$(swig_and_compile_c)
$(run_testcase)
%.multicpptest:
$(setup)
+$(swig_and_compile_multi_cpp)
$(run_multi_testcase)
multi_import.multicpptest:
$(setup)
for f in multi_import_b multi_import_a; do \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile CXXSRCS="$(CXXSRCS)" \
SWIG_LIB="$(SWIG_LIB)" SWIG="$(SWIG)" LIBS='$(LIBS)' \
INCLUDES="$(INCLUDES)" SWIGOPT="$(SWIGOPT)" NOLINK=true \
TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR="$(INTERFACEDIR)" INTERFACE="$$f.i" \
$(LANGUAGE)$(VARIANT)_cpp; \
done
$(run_multi_testcase)
# Runs the testcase.
run_testcase = \
if test -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
$(GO) -I . $(GOCOMPILEARG) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) && \
if $(GOGCC) ; then \
$(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ $*.@OBJEXT@ $*$(SO); \
else \
$(GOLD) -L . -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
fi && \
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./$*_runme; \
fi
run_multi_testcase = \
if test -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
$(GO) -I . $(GOCOMPILEARG) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) && \
if $(GOGCC) ; then \
files=`cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list`; \
$(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ `for f in $$files; do echo $$f.@OBJEXT@ $$f$(SO); done`; \
else \
$(GOLD) -L . -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
fi && \
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./$*_runme; \
fi
%.clean:
@rm -f $*.go $*_gc.c $*_wrap.* $*_runme
clean:
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile go_clean
rm -f mod_a.go mod_b.go imports_a.go imports_b.go
rm -f clientdata_prop_a.go clientdata_prop_b.go
rm -f multi_import_a.go multi_import_b.go
rm -f packageoption_a.go packageoption_b.go packageoption_c.go
cvsignore:
@echo '*_gc.c *_wrap.* *.so *.dll *.exp *.lib'
@echo Makefile
@echo mod_a.go mod_b.go imports_a.go imports_b.go
@echo clientdata_prop_a.go clientdata_prop_b.go
@echo multi_import_a.go multi_import_b.go
@echo packageoption_a.go packageoption_b.go packageoption_c.go
@for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.go; done

View file

@ -0,0 +1,10 @@
package main
import "./abstract_access"
func main() {
d := abstract_access.NewD()
if d.Do_x() != 1 {
panic(d.Do_x())
}
}

View file

@ -0,0 +1,7 @@
package main
import "./abstract_typedef2"
func main() {
abstract_typedef2.NewA_UF()
}

View file

@ -0,0 +1,11 @@
package main
import "./abstract_typedef"
func main() {
e := abstract_typedef.NewEngine()
a := abstract_typedef.NewA()
if !a.Write(e) {
panic("failed")
}
}

View file

@ -0,0 +1,8 @@
package main
import "./abstract_virtual"
func main() {
abstract_virtual.NewD()
abstract_virtual.NewE()
}

View file

@ -0,0 +1,26 @@
package main
import . "./array_member"
func main() {
f := NewFoo()
f.SetData(GetGlobal_data())
for i := 0; i < 8; i++ {
if Get_value(f.GetData(), i) != Get_value(GetGlobal_data(), i) {
panic("Bad array assignment")
}
}
for i := 0; i < 8; i++ {
Set_value(f.GetData(), i, -i)
}
SetGlobal_data(f.GetData())
for i := 0; i < 8; i++ {
if Get_value(f.GetData(), i) != Get_value(GetGlobal_data(), i) {
panic("Bad array assignment")
}
}
}

View file

@ -0,0 +1,22 @@
package main
import . "./arrays_global"
func main() {
SetArray_i(GetArray_const_i())
GetBeginString_FIX44a()
GetBeginString_FIX44b()
GetBeginString_FIX44c()
GetBeginString_FIX44d()
GetBeginString_FIX44d()
SetBeginString_FIX44b("12\00045")
GetBeginString_FIX44b()
GetBeginString_FIX44d()
GetBeginString_FIX44e()
GetBeginString_FIX44f()
Test_a("hello", "hi", "chello", "chi")
Test_b("1234567", "hi")
}

View file

@ -0,0 +1,10 @@
package main
import "./class_ignore"
func main() {
a := class_ignore.NewBar()
if class_ignore.Do_blah(a) != "Bar::blah" {
panic(class_ignore.Do_blah(a))
}
}

View file

@ -0,0 +1,11 @@
package main
import "./class_scope_weird"
func main() {
f := class_scope_weird.NewFoo()
class_scope_weird.NewFoo(3)
if f.Bar(3) != 3 {
panic(f.Bar(3))
}
}

View file

@ -0,0 +1,29 @@
package main
import . "./compactdefaultargs"
func main() {
defaults1 := NewDefaults1(1000)
defaults1 = NewDefaults1()
if defaults1.Ret(float64(10.0)) != 10.0 {
println(1, defaults1.Ret(float64(10.0)))
panic(defaults1.Ret(float64(10.0)))
}
if defaults1.Ret() != -1.0 {
println(2, defaults1.Ret())
panic(defaults1.Ret())
}
defaults2 := NewDefaults2(1000)
defaults2 = NewDefaults2()
if defaults2.Ret(float64(10.0)) != 10.0 {
panic(defaults2.Ret(float64(10.0)))
}
if defaults2.Ret() != -1.0 {
panic(defaults2.Ret())
}
}

View file

@ -0,0 +1,50 @@
package main
import (
"fmt"
"os"
"./constover"
)
func main() {
error := 0
p := constover.Test("test")
if p != "test" {
fmt.Println("test failed!")
error = 1
}
p = constover.Test_pconst("test")
if p != "test_pconst" {
fmt.Println("test_pconst failed!")
error = 1
}
f := constover.NewFoo()
p = f.Test("test")
if p != "test" {
fmt.Println("member-test failed!")
error = 1
}
p = f.Test_pconst("test")
if p != "test_pconst" {
fmt.Println("member-test_pconst failed!")
error = 1
}
p = f.Test_constm("test")
if p != "test_constmethod" {
fmt.Println("member-test_constm failed!")
error = 1
}
p = f.Test_pconstm("test")
if p != "test_pconstmethod" {
fmt.Println("member-test_pconstm failed!")
error = 1
}
os.Exit(error)
}

View file

@ -0,0 +1,34 @@
package main
import . "./constructor_copy"
func main() {
f1 := NewFoo1(3)
f11 := NewFoo1(f1)
if f1.GetX() != f11.GetX() {
panic("f1/f11 x mismatch")
}
bi := NewBari(5)
bc := NewBari(bi)
if bi.GetX() != bc.GetX() {
panic("bi/bc x mismatch")
}
bd := NewBard(5)
good := false
func() {
defer func() {
if recover() != nil {
good = true
}
}()
NewBard(bd)
}()
if !good {
panic("bd !good")
}
}

View file

@ -0,0 +1,208 @@
package main
import "./contract"
func main() {
contract.Test_preassert(1, 2)
contract.Test_postassert(3)
func() {
defer func() {
if recover() == nil {
panic("Failed! Postassertions are broken")
}
}()
contract.Test_postassert(-3)
}()
contract.Test_prepost(2, 3)
contract.Test_prepost(5, -4)
func() {
defer func() {
if recover() == nil {
panic("Failed! Preassertions are broken")
}
}()
contract.Test_prepost(-3, 4)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Postassertions are broken")
}
}()
contract.Test_prepost(4, -10)
}()
f := contract.NewFoo()
f.Test_preassert(4, 5)
func() {
defer func() {
if recover() == nil {
panic("Failed! Method preassertion.")
}
}()
f.Test_preassert(-2, 3)
}()
f.Test_postassert(4)
func() {
defer func() {
if recover() == nil {
panic("Failed! Method postassertion")
}
}()
f.Test_postassert(-4)
}()
f.Test_prepost(3, 4)
f.Test_prepost(4, -3)
func() {
defer func() {
if recover() == nil {
panic("Failed! Method preassertion.")
}
}()
f.Test_prepost(-4, 2)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Method postassertion.")
}
}()
f.Test_prepost(4, -10)
}()
contract.FooStest_prepost(4, 0)
func() {
defer func() {
if recover() == nil {
panic("Failed! Static method preassertion")
}
}()
contract.FooStest_prepost(-4, 2)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Static method posteassertion")
}
}()
contract.FooStest_prepost(4, -10)
}()
b := contract.NewBar()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion.")
}
}()
b.Test_prepost(2, -4)
}()
d := contract.NewD()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Foo(-1, 1, 1, 1, 1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Foo(1, -1, 1, 1, 1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Foo(1, 1, -1, 1, 1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Foo(1, 1, 1, -1, 1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Foo(1, 1, 1, 1, -1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Bar(-1, 1, 1, 1, 1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Bar(1, -1, 1, 1, 1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Bar(1, 1, -1, 1, 1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Bar(1, 1, 1, -1, 1)
}()
func() {
defer func() {
if recover() == nil {
panic("Failed! Inherited preassertion (D).")
}
}()
d.Bar(1, 1, 1, 1, -1)
}()
//Namespace
my := contract.NewMyClass(1)
func() {
defer func() {
if recover() == nil {
panic("Failed! constructor preassertion")
}
}()
my = contract.NewMyClass(0)
}()
}

View file

@ -0,0 +1,27 @@
package main
import "./cpp_enum"
func main() {
f := cpp_enum.NewFoo()
if f.GetHola() != cpp_enum.FooHello {
panic(f.GetHola())
}
f.SetHola(cpp_enum.FooHi)
if f.GetHola() != cpp_enum.FooHi {
panic(f.GetHola())
}
f.SetHola(cpp_enum.FooHello)
if f.GetHola() != cpp_enum.FooHello {
panic(f.GetHola())
}
cpp_enum.SetHi(cpp_enum.Hello)
if cpp_enum.GetHi() != cpp_enum.Hello {
panic(cpp_enum.Hi)
}
}

View file

@ -0,0 +1,57 @@
// Note: This example assumes that namespaces are flattened
package main
import "./cpp_namespace"
func main() {
n := cpp_namespace.Fact(4)
if n != 24 {
panic("Bad return value!")
}
if cpp_namespace.GetFoo() != 42 {
panic("Bad variable value!")
}
t := cpp_namespace.NewTest()
if t.Method() != "Test::method" {
panic("Bad method return value!")
}
if cpp_namespace.Do_method(t) != "Test::method" {
panic("Bad return value!")
}
if cpp_namespace.Do_method2(t) != "Test::method" {
panic("Bad return value!")
}
cpp_namespace.Weird("hello", 4)
cpp_namespace.DeleteTest(t)
t2 := cpp_namespace.NewTest2()
t3 := cpp_namespace.NewTest3()
t4 := cpp_namespace.NewTest4()
t5 := cpp_namespace.NewTest5()
if cpp_namespace.Foo3(42) != 42 {
panic("Bad return value!")
}
if cpp_namespace.Do_method3(t2, 40) != "Test2::method" {
panic("Bad return value!")
}
if cpp_namespace.Do_method3(t3, 40) != "Test3::method" {
panic("Bad return value!")
}
if cpp_namespace.Do_method3(t4, 40) != "Test4::method" {
panic("Bad return value!")
}
if cpp_namespace.Do_method3(t5, 40) != "Test5::method" {
panic("Bad return value!")
}
}

View file

@ -0,0 +1,13 @@
package main
import . "./cpp_static"
func main() {
StaticFunctionTestStatic_func()
StaticFunctionTestStatic_func_2(1)
StaticFunctionTestStatic_func_3(1, 2)
SetStaticMemberTestStatic_int(10)
if GetStaticMemberTestStatic_int() != 10 {
panic(GetStaticMemberTestStatic_int())
}
}

View file

@ -0,0 +1,26 @@
package main
import "./default_args"
func main() {
if default_args.StaticsStaticmethod() != 60 {
panic(0)
}
if default_args.Cfunc1(1) != 2 {
panic(0)
}
if default_args.Cfunc2(1) != 3 {
panic(0)
}
if default_args.Cfunc3(1) != 4 {
panic(0)
}
f := default_args.NewFoo()
f.Newname()
f.Newname(1)
}

View file

@ -0,0 +1,35 @@
package main
import dc "./default_constructor"
func main() {
a := dc.NewA()
dc.DeleteA(a)
aa := dc.NewAA()
dc.DeleteAA(aa)
cc := dc.NewCC()
dc.DeleteCC(cc)
e := dc.NewE()
dc.DeleteE(e)
ee := dc.NewEE()
dc.DeleteEE(ee)
f := dc.NewF()
f.Destroy()
ff := dc.NewFFF()
ff.Destroy()
g := dc.NewG()
dc.GDestroy(g)
gg := dc.NewGG()
dc.DeleteGG(gg)
dc.NewHH(1, 1)
}

View file

@ -0,0 +1,62 @@
package main
import "./director_abstract"
type MyFoo struct{}
func (p *MyFoo) Ping() string {
return "MyFoo::ping()"
}
func f1() {
a := director_abstract.NewDirectorFoo(&MyFoo{})
if a.Ping() != "MyFoo::ping()" {
panic(a.Ping())
}
if a.Pong() != "Foo::pong();MyFoo::ping()" {
panic(a.Pong())
}
}
type MyExample1 struct{}
func (p *MyExample1) Color(r, g, b byte) int {
return int(r)
}
type MyExample2 struct{}
func (p *MyExample2) Color(r, g, b byte) int {
return int(g)
}
type MyExample3 struct{}
func (p *MyExample3) Color(r, g, b byte) int {
return int(b)
}
func f2() {
me1 := director_abstract.NewDirectorExample1(&MyExample1{})
if director_abstract.Example1Get_color(me1, 1, 2, 3) != 1 {
println(director_abstract.Example1Get_color(me1, 1, 2, 3))
panic(0)
}
me2 := director_abstract.NewDirectorExample2(&MyExample2{}, 1, 2)
if director_abstract.Example2Get_color(me2, 1, 2, 3) != 2 {
panic(0)
}
me3 := director_abstract.NewDirectorExample3_i(&MyExample3{})
if director_abstract.Example3_iGet_color(me3, 1, 2, 3) != 3 {
panic(0)
}
}
func main() {
f1()
f2()
}

Some files were not shown because too many files have changed in this diff Show more