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

463
Doc/Manual/Go.html Normal file
View file

@ -0,0 +1,463 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Go</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="Go"></a>20 SWIG and Go</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Go_overview">Overview</a>
<li><a href="#Go_running_swig">Running SWIG with Go</a>
<ul>
<li><a href="#Go_commandline">Additional Commandline Options</a>
<li><a href="#Go_outputs">Go Output Files</a>
</ul>
<li><a href="#Go_basic_tour">A tour of basic C/C++ wrapping</a>
<ul>
<li><a href="#Go_package">Go Package Name</a>
<li><a href="#Go_names">Go Names</a>
<li><a href="#Go_constants">Go Constants</a>
<li><a href="#Go_enumerations">Go Enumerations</a>
<li><a href="#Go_classes">Go Classes</a>
<ul>
<li><a href="#Go_nn12">Go Class Inheritance</a>
</ul>
<li><a href="#templates">Go Templates</a>
<li><a href="#Go_director_classes">Go Director Classes</a>
<li><a href="#Go_primitive_type_mappings">Default Go primitive type mappings</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG's support of Go. For more information on
the Go programming language
see <a href="http://golang.org/">golang.org</a>.
</p>
<H2><a name="Go_overview"></a>20.1 Overview</H2>
<p>
Go is a compiled language, not a scripting language. However, it does
not support direct calling of functions written in C/C++. The cgo
program may be used to generate wrappers to call C code from Go, but
there is no convenient way to call C++ code. SWIG fills this gap.
</p>
<p>
There are (at least) two different Go compilers. One is the gc
compiler, normally invoked under the names 6g, 8g, or 5g. The other
is the gccgo compiler, which is a frontend to the gcc compiler suite.
The interface to C/C++ code is completely different for the two Go
compilers. SWIG supports both, selected by a command line option.
</p>
<p>
Because Go is a type-safe compiled language, SWIG's runtime type
checking and runtime library are not used with Go. This should be
borne in mind when reading the rest of the SWIG documentation.
</p>
<H2><a name="Go_running_swig"></a>20.2 Running SWIG with Go</H2>
<p>
To generate Go code, use the <tt>-go</tt> option with SWIG. By
default SWIG will generate code for the gc compilers. To generate
code for gccgo, you should use the <tt>-gccgo</tt> option.
</p>
<H3><a name="Go_commandline"></a>20.2.1 Additional Commandline Options</H3>
<p>
These are the command line options for SWIG's GO module. They can
also be seen by using:
</p>
<div class="code"><pre>
swig -go -help
</pre></div>
<table summary="Go specific options">
<tr>
<th>Go specific options</th>
</tr>
<tr>
<td>-gccgo</td>
<td>Generate code for gccgo. The default is to generate code for
6g/8g/6g.</td>
</tr>
<tr>
<td>-package &lt;name&gt;</td>
<td>Set the name of the Go package to &lt;name&gt;. The default
package name is the SWIG module name.</td>
</tr>
<tr>
<td>-go-prefix &lt;prefix&gt;</td>
<td>When generating code for gccgo, set the prefix to use. This
corresponds to the <tt>-fgo-prefix</tt> option to gccgo.</td>
</tr>
<tr>
<td>-long-type-size &lt;s&gt;</td>
<td>Set the size for the C/C++ type <tt>long</tt>. This controls
whether <tt>long</tt> is converted to the Go type <tt>int32</tt>
or <tt>int64</tt>. The &lt;s&gt; argument should be 32 or 64.</td>
</tr>
<tr>
<td>-rename &lt;old&gt;=&lt;new&gt;</td>
<td>Rename &lt;old%gt; to &lt;new&gt; when processing the C/C++ code
and also the SWIG input file. This is a convenient way to rename
names in the C/C++ code which are the same expect for the first
letter, to avoid conflicts when applying the Go renaming rules
described below.</td>
</tr>
</table>
<H3><a name="Go_outputs"></a>20.2.2 Go Output Files</H3>
<p> When generating Go code, SWIG will generate the following
files:</p>
<ul>
<li>
MODULE.go will contain the Go functions that your Go code will call.
These functions will be wrappers for the C++ functions defined by your
module. This file should, of course, be compiled with the Go
compiler.
<li>
MODULE_wrap.c or MODULE_wrap.cxx will contain C/C++ functions will be
invoked by the Go wrapper code. This file should be compiled with the
usual C or C++ compiler and linked into a shared library.
<li>
MODULE_wrap.h will be generated if you use the directors feature. It
provides a definition of the generated C++ director classes. It is
generally not necessary to use this file, but in some special cases it
may be helpful to include it in your code, compiled with the usual C
or C++ compiler.
<li>
If using the gc compiler, MODULE_gc.c will contain C code which should
be compiled with the C compiler which part of the gc compiler: 6c, 8c,
or 5c. It should then be combined with the compiled MODULE.go using
gopack. This file will not be generated when using gccgo.
</ul>
<p>
A typical command sequence would look like this:
</p>
<div class="code"><pre>
% swig -go example.i
% gcc -c -fpic example.c
% gcc -c -fpic example_wrap.c
% gcc -shared example.o example_wrap.o -o example.so
% 6g example.go
% 6c example_gc.c
% gopack grc example.a example.6 example_gc.6
% 6g main.go # your code, not generated by SWIG
% 6l main.6
</pre></div>
<H2><a name="Go_basic_tour"></a>20.3 A tour of basic C/C++ wrapping</H2>
<p>
By default, SWIG attempts to build a natural Go interface to your
C/C++ code. However, the languages are somewhat different, so some
modifications have to occur. This section briefly covers the
essential aspects of this wrapping.
</p>
<H3><a name="Go_package"></a>20.3.1 Go Package Name</H3>
<p>
All Go source code lives in a package. The name of this package will
default to the name of the module from SWIG's <tt>%module</tt>
directive. You may override this by using SWIG's <tt>-package</tt>
command line option.
</p>
<H3><a name="Go_names"></a>20.3.2 Go Names</H3>
<p>
In Go, a function is only visible outside the current package if the
first letter of the name is uppercase. This is quite different from
C/C++. Because of this, C/C++ names are modified when generating the
Go interface: the first letter is forced to be uppercase if it is not
already. This affects the names of functions, methods, variables,
constants, enums, and classes.
</p>
<p>
C/C++ variables are wrapped with setter and getter functions in Go.
First the first letter of the variable name will be forced to
uppercase, and then <tt>Get</tt> or <tt>Set</tt> will be prepended.
For example, if the C/C++ variable is called <tt>var</tt>, then SWIG
will define the functions <tt>GetVar</tt> and <tt>SetVar</tt>. If a
variable is declared as <tt>const</tt>, or if
SWIG's <a href="SWIG.html#SWIG_readonly_variables">
<tt>%immutable</tt> directive</a> is used for the variable, then only
the getter will be defined.
</p>
<p>
C++ classes will be discussed further below. Here we'll note that the
first letter of the class name will be forced to uppercase to give the
name of a type in Go. A constructor will be named <tt>New</tt>
followed by that name, and the destructor will be
named <tt>Delete</tt> followed by that name.
</p>
<H3><a name="Go_constants"></a>20.3.3 Go Constants</H3>
<p>
C/C++ constants created via <tt>#define</tt> or the <tt>%constant</tt>
directive become Go constants, declared with a <tt>const</tt>
declaration.
<H3><a name="Go_enumerations"></a>20.3.4 Go Enumerations</H3>
<p>
C/C++ enumeration types will cause SWIG to define an integer type with
the name of the enumeration (with first letter forced to uppercase as
usual). The values of the enumeration will become variables in Go;
code should avoid modifying those variables.
</p>
<H3><a name="Go_classes"></a>20.3.5 Go Classes</H3>
<p>
Go has interfaces, methods and inheritance, but it does not have
classes in the same sense as C++. This sections describes how SWIG
represents C++ classes represented in Go.
</p>
<p>
For a C++ class <tt>ClassName</tt>, SWIG will define two types in Go:
an underlying type, which will just hold a pointer to the C++ type,
and an interface type. The interface type will be
named <tt>ClassName</tt>. SWIG will define a
function <tt>NewClassName</tt> which will take any constructor
arguments and return a value of the interface
type <tt>ClassName</tt>. SWIG will also define a
destructor <tt>DeleteClassName</tt>.
</p>
<p>
SWIG will represent any methods of the C++ class as methods on the
underlying type, and also as methods of the interface type. Thus C++
methods may be invoked directly using the
usual <tt>val.MethodName</tt> syntax. Public members of the C++ class
will be given getter and setter functions defined as methods of the
class.
</p>
<p>
SWIG will represent static methods of C++ classes as ordinary Go
functions. SWIG will use names like <tt>ClassName_MethodName</tt>.
SWIG will give static members getter and setter functions with names
like <tt>GetClassName_VarName</tt>.
</p>
<p>
Given a value of the interface type, Go code can retrieve the pointer
to the C++ type by calling the <tt>Swigcptr</tt> method. This will
return a value of type <tt>SwigcptrClassName</tt>, which is just a
name for <tt>uintptr</tt>. A Go type conversion can be used to
convert this value to a different C++ type, but note that this
conversion will not be type checked and is essentially equivalent
to <tt>reinterpret_cast</tt>. This should only be used for very
special cases, such as where C++ would use a <tt>dynamic_cast</tt>.
</p>
<H4><a name="Go_nn12"></a>20.3.5.1 Go Class Inheritance</H4>
<p>
C++ class inheritance is automatically represented in Go due to its
use of interfaces. The interface for a child class will be a superset
of the interface of its parent class. Thus a value of the child class
type in Go may be passed to a function which expects the parent class.
Doing the reverse will require an explicit type assertion, which will
be checked dynamically.
</p>
<H3><a name="templates"></a>20.3.6 Go Templates</H3>
<p>
In order to use C++ templates in Go, you must tell SWIG to create
wrappers for a particular template instantation. To do this, use
the <tt>%template</tt> directive.
<H3><a name="Go_director_classes"></a>20.3.7 Go Director Classes</H3>
<p>
SWIG's director feature permits a Go type to act as the subclass of a
C++ class with virtual methods. This is complicated by the fact that
C++ and Go define inheritance differently. In Go, structs can inherit
methods via anonymous field embedding. However, when a method is
called for an embedded struct, if that method calls any other methods,
they are called for the embedded struct, not for the original type.
Therefore, SWIG must use Go interfaces to represent C++ inheritance.
</p>
<p>
In order to use the director feature in Go, you must define a type in
your Go code. You must then add methods for the type. Define a
method in Go for each C++ virtual function that you want to override.
You must then create a value of your new type, and pass a pointer to
it to the function <tt>NewDirectorClassName</tt>,
where <tt>ClassName</tt> is the name of the C++ class. That will
return a value of type <tt>ClassName</tt>.
</p>
<p>
For example:
</p>
<div class="code">
<pre>
type GoClass struct { }
func (p *GoClass) VirtualFunction() { }
func MakeClass() ClassName {
return NewDirectorClassName(&GoClass{})
}
</pre>
</div>
<p>
Any call in C++ code to the virtual function will wind up calling the
method defined in Go. The Go code may of course call other methods on
itself, and those methods may be defined either in Go or in C++.
</p>
<H3><a name="Go_primitive_type_mappings"></a>20.3.8 Default Go primitive type mappings</H3>
<p>
The following table lists the default type mapping from C/C++ to Go.
This table will tell you which Go type to expect for a function which
uses a given C/C++ type.
</p>
<table BORDER summary="Go primitive type mappings">
<tr>
<td><b>C/C++ type</b></td>
<td><b>Go type</b></td>
</tr>
<tr>
<td>bool</td>
<td>bool</td>
</tr>
<tr>
<td>char</td>
<td>byte</td>
</tr>
<tr>
<td>signed char</td>
<td>int8</td>
</tr>
<tr>
<td>unsigned char</td>
<td>byte</td>
</tr>
<tr>
<td>short</td>
<td>int16</td>
</tr>
<tr>
<td>unsigned short</td>
<td>uint16</td>
</tr>
<tr>
<td>int</td>
<td>int</td>
</tr>
<tr>
<td>unsigned int</td>
<td>uint</td>
</tr>
<tr>
<td>long</td>
<td>int32 or int64, depending on <tt>-long-type-size</tt></td>
</tr>
<tr>
<td>unsigned long</td>
<td>uint32 or uint64, depending on <tt>-long-type-size</tt></td>
</tr>
<tr>
<td>long long</td>
<td>int64</td>
</tr>
<tr>
<td>unsigned long long</td>
<td>uint64</td>
</tr>
<tr>
<td>float</td>
<td>float32</td>
</tr>
<tr>
<td>double</td>
<td>float64</td>
</tr>
<tr>
<td>char *<br>char []</td>
<td>string</td>
</tr>
</table>
<p>
Note that SWIG wraps the C <tt>char</tt> type as a character. Pointers
and arrays of this type are wrapped as strings. The <tt>signed
char</tt> type can be used if you want to treat <tt>char</tt> as a
signed number rather than a character. Also note that all const
references to primitive types are treated as if they are passed by
value.
</p>
<p>
These type mappings are defined by the "go" typemap. You may change
that typemap, or add new values, to control how C/C++ types are mapped
into Go types.
</p>
</body>
</html>

View file

@ -113,6 +113,7 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
-clisp Generate CLISP wrappers
-cffi Generate CFFI wrappers
-csharp Generate C# wrappers
-go Generate Go wrappers
-guile Generate Guile wrappers
-java Generate Java wrappers
-lua Generate Lua wrappers

View file

@ -36,6 +36,7 @@ Last update : SWIG-2.0.1 (in progress)
<li><a href="Allegrocl.html#Allegrocl">Allegro CL support</a></li>
<li><a href="CSharp.html#CSharp">C# support</a></li>
<li><a href="Chicken.html#Chicken">Chicken support</a></li>
<li><a href="Go.html#Go">Go support</a></li>
<li><a href="Guile.html#Guile">Guile support</a></li>
<li><a href="Java.html#Java">Java support</a></li>
<li><a href="Lua.html#Lua">Lua support</a></li>

View file

@ -17,6 +17,7 @@ CCache.html
Allegrocl.html
CSharp.html
Chicken.html
Go.html
Guile.html
Java.html
Lisp.html

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

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