summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2015-08-09 07:31:09 -0700
committerIan Lance Taylor <iant@golang.org>2015-08-09 07:31:09 -0700
commit01edfef3b8bd63ad9041b8da9525e0dfb6b2101a (patch)
treef38c017e1731d32ca4eb5d74a466a251e7f93fca
parent19a20c794bea67fb7e3530da362473c05cf87cad (diff)
parent608ef60ecf7774533b3344622be5b8df64bf133e (diff)
downloadswig-01edfef3b8bd63ad9041b8da9525e0dfb6b2101a.tar.gz
Merge pull request #493 from michael-schaller/dir-examples
[Go] Undelete and updated the 'callback' and 'extend' examples.
-rw-r--r--Doc/Manual/Go.html196
-rw-r--r--Examples/go/callback/Makefile24
-rw-r--r--Examples/go/callback/callback.cxx4
-rw-r--r--Examples/go/callback/example.h22
-rw-r--r--Examples/go/callback/example.i11
-rw-r--r--Examples/go/callback/gocallback.go41
-rw-r--r--Examples/go/callback/index.html31
-rw-r--r--Examples/go/callback/runme.go33
-rw-r--r--Examples/go/check.list2
-rw-r--r--Examples/go/director/Makefile11
-rw-r--r--Examples/go/director/director.go74
-rw-r--r--Examples/go/director/director.h10
-rw-r--r--Examples/go/director/example.i2
-rw-r--r--Examples/go/director/index.html2
-rw-r--r--Examples/go/extend/Makefile24
-rw-r--r--Examples/go/extend/ceo.go37
-rw-r--r--Examples/go/extend/example.h56
-rw-r--r--Examples/go/extend/example.i15
-rw-r--r--Examples/go/extend/extend.cxx4
-rw-r--r--Examples/go/extend/index.html30
-rw-r--r--Examples/go/extend/runme.go66
-rw-r--r--Examples/go/index.html2
22 files changed, 552 insertions, 145 deletions
diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html
index c008ef22c..ca12410ad 100644
--- a/Doc/Manual/Go.html
+++ b/Doc/Manual/Go.html
@@ -606,22 +606,22 @@ completely to avoid common pitfalls with directors in Go.
<H4><a name="Go_director_example_cpp_code"></a>23.4.7.1 Example C++ code</H4>
<p>
-The step by step guide is based on two example C++ classes. FooBarAbs is an
-abstract C++ class and the FooBarCpp class inherits from it. This guide
+The step by step guide is based on two example C++ classes. FooBarAbstract is
+an abstract C++ class and the FooBarCpp class inherits from it. This guide
explains how to implement a FooBarGo class similar to the FooBarCpp class.
</p>
<p>
-<tt>FooBarAbs</tt> abstract C++ class:
+<tt>FooBarAbstract</tt> abstract C++ class:
</p>
<div class="code">
<pre>
-class FooBarAbs
+class FooBarAbstract
{
public:
- FooBarAbs() {};
- virtual ~FooBarAbs() {};
+ FooBarAbstract() {};
+ virtual ~FooBarAbstract() {};
std::string FooBar() {
return this->Foo() + ", " + this->Bar();
@@ -643,11 +643,11 @@ protected:
<div class="code">
<pre>
-class FooBarCpp : public FooBarAbs
+class FooBarCpp : public FooBarAbstract
{
protected:
virtual std::string Foo() {
- return "C++ " + FooBarAbs::Foo();
+ return "C++ " + FooBarAbstract::Foo();
}
virtual std::string Bar() {
@@ -691,14 +691,14 @@ directive, like this:
<p>
Second, you must use the %feature("director") directive to tell SWIG which
-classes should get directors. In the example the FooBarAbs class needs the
+classes should get directors. In the example the FooBarAbstract class needs the
director feature enabled so that the FooBarGo class can inherit from it, like
this:
</p>
<div class="code">
<pre>
-%feature("director") FooBarAbs;
+%feature("director") FooBarAbstract;
</pre>
</div>
@@ -782,21 +782,21 @@ As an example see part of the <tt>FooBarGo</tt> class:
<div class="code">
<pre>
-type overwrittenMethodsOnFooBarAbs struct {
- fb FooBarAbs
+type overwrittenMethodsOnFooBarAbstract struct {
+ fb FooBarAbstract
}
-func (om *overwrittenMethodsOnFooBarAbs) Foo() string {
+func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
...
}
-func (om *overwrittenMethodsOnFooBarAbs) Bar() string {
+func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
...
}
func NewFooBarGo() FooBarGo {
- om := &amp;overwrittenMethodsOnFooBarAbs{}
- fb := NewDirectorFooBarAbs(om)
+ om := &amp;overwrittenMethodsOnFooBarAbstract{}
+ fb := NewDirectorFooBarAbstract(om)
om.fb = fb
...
}
@@ -806,25 +806,25 @@ func NewFooBarGo() FooBarGo {
<p>
The complete example, including the <tt>FooBarGoo</tt> class implementation, can
be found in <a href="#Go_director_foobargo_class">the end of the guide</a>. In
-this part of the example the virtual methods <tt>FooBarAbs::Foo</tt> and
-<tt>FooBarAbs::Bar</tt> have been overwritten with Go methods similarly to how
-the <tt>FooBarAbs</tt> virtual methods are overwritten by the <tt>FooBarCpp</tt>
-class.
+this part of the example the virtual methods <tt>FooBarAbstract::Foo</tt> and
+<tt>FooBarAbstract::Bar</tt> have been overwritten with Go methods similarly to
+how the <tt>FooBarAbstract</tt> virtual methods are overwritten by the
+<tt>FooBarCpp</tt> class.
</p>
<p>
The <tt>DirectorInterface</tt> in the example is implemented by the
-<tt>overwrittenMethodsOnFooBarAbs</tt> Go struct type. A pointer to a
-<tt>overwrittenMethodsOnFooBarAbs</tt> struct instance will be given to the
-<tt>NewDirectorFooBarAbs</tt> constructor function. The constructor return
-value implements the <tt>FooBarAbs</tt> interface.
-<tt>overwrittenMethodsOnFooBarAbs</tt> could in theory be any Go type but in
-practice a struct is used as it typically contains at least a value of the
+<tt>overwrittenMethodsOnFooBarAbstract</tt> Go struct type. A pointer to a
+<tt>overwrittenMethodsOnFooBarAbstract</tt> struct instance will be given to the
+<tt>NewDirectorFooBarAbstract</tt> constructor function. The constructor return
+value implements the <tt>FooBarAbstract</tt> interface.
+<tt>overwrittenMethodsOnFooBarAbstract</tt> could in theory be any Go type but
+in practice a struct is used as it typically contains at least a value of the
C++ class interface so that the overwritten methods can use the rest of the
C++ class. If the <tt>FooBarGo</tt> class would receive additional constructor
arguments then these would also typically be stored in the
-<tt>overwrittenMethodsOnFooBarAbs</tt> struct so that they can be used by the
-Go methods.
+<tt>overwrittenMethodsOnFooBarAbstract</tt> struct so that they can be used by
+the Go methods.
</p>
@@ -840,7 +840,7 @@ the method in the base class. This is also the case for the
<div class="code">
<pre>
virtual std::string Foo() {
- return "C++ " + FooBarAbs::Foo();
+ return "C++ " + FooBarAbstract::Foo();
}
</pre>
</div>
@@ -853,8 +853,8 @@ The <tt>FooBarGo.Foo</tt> implementation in the example looks like this:
<div class="code">
<pre>
-func (om *overwrittenMethodsOnFooBarAbs) Foo() string {
- return "Go " + DirectorFooBarAbsFoo(om.fb)
+func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
+ return "Go " + DirectorFooBarAbstractFoo(om.fb)
}
</pre>
</div>
@@ -887,31 +887,31 @@ this:
<div class="code">
<pre>
type FooBarGo interface {
- FooBarAbs
- deleteFooBarAbs()
+ FooBarAbstract
+ deleteFooBarAbstract()
IsFooBarGo()
}
type fooBarGo struct {
- FooBarAbs
+ FooBarAbstract
}
-func (fbgs *fooBarGo) deleteFooBarAbs() {
- DeleteDirectorFooBarAbs(fbgs.FooBarAbs)
+func (fbgs *fooBarGo) deleteFooBarAbstract() {
+ DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
}
func (fbgs *fooBarGo) IsFooBarGo() {}
func NewFooBarGo() FooBarGo {
- om := &amp;overwrittenMethodsOnFooBarAbs{}
- fb := NewDirectorFooBarAbs(om)
+ om := &amp;overwrittenMethodsOnFooBarAbstract{}
+ fb := NewDirectorFooBarAbstract(om)
om.fb = fb
- return &amp;fooBarGo{FooBarAbs: fb}
+ return &amp;fooBarGo{FooBarAbstract: fb}
}
func DeleteFooBarGo(fbg FooBarGo) {
- fbg.deleteFooBarAbs()
+ fbg.deleteFooBarAbstract()
}
</pre>
</div>
@@ -921,12 +921,12 @@ func DeleteFooBarGo(fbg FooBarGo) {
The complete example, including the <tt>FooBarGoo</tt> class implementation, can
be found in <a href="#Go_director_foobargo_class">the end of the guide</a>. In
this part of the example the private <tt>fooBarGo</tt> struct embeds <tt>
-FooBarAbs</tt> which lets the <tt>fooBarGo</tt> Go type "inherit" all the
-methods of the <tt>FooBarAbs</tt> C++ class by means of embedding. The public
-<tt>FooBarGo</tt> interface type includes the <tt>FooBarAbs</tt> interface and
-hence <tt>FooBarGo</tt> can be used as a drop in replacement for
-<tt>FooBarAbs</tt> while the reverse isn't possible and would raise a compile
-time error. Furthemore the constructor and destructor functions <tt>
+FooBarAbstract</tt> which lets the <tt>fooBarGo</tt> Go type "inherit" all the
+methods of the <tt>FooBarAbstract</tt> C++ class by means of embedding. The
+public <tt>FooBarGo</tt> interface type includes the <tt>FooBarAbstract</tt>
+interface and hence <tt>FooBarGo</tt> can be used as a drop in replacement for
+<tt>FooBarAbstract</tt> while the reverse isn't possible and would raise a
+compile time error. Furthemore the constructor and destructor functions <tt>
NewFooBarGo</tt> and <tt>DeleteFooBarGo</tt> take care of all the director
specifics and to the user the class appears as any other SWIG wrapped C++
class.
@@ -946,13 +946,13 @@ in the <tt>FooBarGo</tt> class is here:
<div class="code">
<pre>
-type overwrittenMethodsOnFooBarAbs struct {
- fb FooBarAbs
+type overwrittenMethodsOnFooBarAbstract struct {
+ fb FooBarAbstract
}
func NewFooBarGo() FooBarGo {
- om := &amp;overwrittenMethodsOnFooBarAbs{}
- fb := NewDirectorFooBarAbs(om) // fb.v = om
+ om := &amp;overwrittenMethodsOnFooBarAbstract{}
+ fb := NewDirectorFooBarAbstract(om) // fb.v = om
om.fb = fb // Backlink causes cycle as fb.v = om!
...
}
@@ -963,27 +963,27 @@ func NewFooBarGo() FooBarGo {
In order to be able to use <tt>runtime.SetFinalizer</tt> nevertheless the
finalizer needs to be set on something that isn't in a cycle and that references
the director object instance. In the <tt>FooBarGo</tt> class example the <tt>
-FooBarAbs</tt> director instance can be automatically deleted by setting the
-finalizer on <tt>fooBarGo</tt>:
+FooBarAbstract</tt> director instance can be automatically deleted by setting
+the finalizer on <tt>fooBarGo</tt>:
</p>
<div class="code">
<pre>
type fooBarGo struct {
- FooBarAbs
+ FooBarAbstract
}
-type overwrittenMethodsOnFooBarAbs struct {
- fb FooBarAbs
+type overwrittenMethodsOnFooBarAbstract struct {
+ fb FooBarAbstract
}
func NewFooBarGo() FooBarGo {
- om := &amp;overwrittenMethodsOnFooBarAbs{}
- fb := NewDirectorFooBarAbs(om)
+ om := &amp;overwrittenMethodsOnFooBarAbstract{}
+ fb := NewDirectorFooBarAbstract(om)
om.fb = fb // Backlink causes cycle as fb.v = om!
- fbgs := &amp;fooBarGo{FooBarAbs: fb}
- runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbs)
+ fbgs := &amp;fooBarGo{FooBarAbstract: fb}
+ runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
return fbgs
}
</pre>
@@ -1007,73 +1007,75 @@ The complete and annotated <tt>FooBarGo</tt> class looks like this:
<div class="code">
<pre>
-// FooBarGo is a superset of FooBarAbs and hence FooBarGo can be used as a drop
-// in replacement for FooBarAbs but the reverse causes a compile time error.
+// FooBarGo is a superset of FooBarAbstract and hence FooBarGo can be used as a
+// drop in replacement for FooBarAbstract but the reverse causes a compile time
+// error.
type FooBarGo interface {
- FooBarAbs
- deleteFooBarAbs()
+ FooBarAbstract
+ deleteFooBarAbstract()
IsFooBarGo()
}
-// Via embedding fooBarGo "inherits" all methods of FooBarAbs.
+// Via embedding fooBarGo "inherits" all methods of FooBarAbstract.
type fooBarGo struct {
- FooBarAbs
+ FooBarAbstract
}
-func (fbgs *fooBarGo) deleteFooBarAbs() {
- DeleteDirectorFooBarAbs(fbgs.FooBarAbs)
+func (fbgs *fooBarGo) deleteFooBarAbstract() {
+ DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
}
-// The IsFooBarGo method ensures that FooBarGo is a superset of FooBarAbs.
+// The IsFooBarGo method ensures that FooBarGo is a superset of FooBarAbstract.
// This is also how the class hierarchy gets represented by the SWIG generated
-// wrapper code. For an instance FooBarCpp has the IsFooBarAbs and IsFooBarCpp
-// methods.
+// wrapper code. For an instance FooBarCpp has the IsFooBarAbstract and
+// IsFooBarCpp methods.
func (fbgs *fooBarGo) IsFooBarGo() {}
// Go type that defines the DirectorInterface. It contains the Foo and Bar
-// methods that overwrite the respective virtual C++ methods on FooBarAbs.
-type overwrittenMethodsOnFooBarAbs struct {
- // Backlink to FooBarAbs so that the rest of the class can be used by the
- // overridden methods.
- fb FooBarAbs
+// methods that overwrite the respective virtual C++ methods on FooBarAbstract.
+type overwrittenMethodsOnFooBarAbstract struct {
+ // Backlink to FooBarAbstract so that the rest of the class can be used by
+ // the overridden methods.
+ fb FooBarAbstract
// If additional constructor arguments have been given they are typically
// stored here so that the overriden methods can use them.
}
-func (om *overwrittenMethodsOnFooBarAbs) Foo() string {
- // DirectorFooBarAbsFoo calls the base method FooBarAbs::Foo.
- return "Go " + DirectorFooBarAbsFoo(om.fb)
+func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
+ // DirectorFooBarAbstractFoo calls the base method FooBarAbstract::Foo.
+ return "Go " + DirectorFooBarAbstractFoo(om.fb)
}
-func (om *overwrittenMethodsOnFooBarAbs) Bar() string {
+func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
return "Go Bar"
}
func NewFooBarGo() FooBarGo {
- // Instantiate FooBarAbs with selected methods overridden. The methods that
- // will be overwritten are defined on overwrittenMethodsOnFooBarAbs and have
- // a compatible signature to the respective virtual C++ methods.
- // Furthermore additional constructor arguments will be typically stored in
- // the overwrittenMethodsOnFooBarAbs struct.
- om := &amp;overwrittenMethodsOnFooBarAbs{}
- fb := NewDirectorFooBarAbs(om)
+ // Instantiate FooBarAbstract with selected methods overridden. The methods
+ // that will be overwritten are defined on
+ // overwrittenMethodsOnFooBarAbstract and have a compatible signature to the
+ // respective virtual C++ methods. Furthermore additional constructor
+ // arguments will be typically stored in the
+ // overwrittenMethodsOnFooBarAbstract struct.
+ om := &amp;overwrittenMethodsOnFooBarAbstract{}
+ fb := NewDirectorFooBarAbstract(om)
om.fb = fb // Backlink causes cycle as fb.v = om!
- fbgs := &amp;fooBarGo{FooBarAbs: fb}
- // The memory of the FooBarAbs director object instance can be automatically
- // freed once the FooBarGo instance is garbage collected by uncommenting the
- // following line. Please make sure to understand the runtime.SetFinalizer
- // specific gotchas before doing this. Furthemore DeleteFooBarGo should be
- // deleted if a finalizer is in use or the fooBarGo struct needs additional
- // data to prevent double deletion.
- // runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbs)
+ fbgs := &amp;fooBarGo{FooBarAbstract: fb}
+ // The memory of the FooBarAbstract director object instance can be
+ // automatically freed once the FooBarGo instance is garbage collected by
+ // uncommenting the following line. Please make sure to understand the
+ // runtime.SetFinalizer specific gotchas before doing this. Furthemore
+ // DeleteFooBarGo should be deleted if a finalizer is in use or the fooBarGo
+ // struct needs additional data to prevent double deletion.
+ // runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
return fbgs
}
// Recommended to be removed if runtime.SetFinalizer is in use.
func DeleteFooBarGo(fbg FooBarGo) {
- fbg.deleteFooBarAbs()
+ fbg.deleteFooBarAbstract()
}
</pre>
</div>
@@ -1094,11 +1096,11 @@ For comparison the <tt>FooBarCpp</tt> class looks like this:
<div class="code">
<pre>
-class FooBarCpp : public FooBarAbs
+class FooBarCpp : public FooBarAbstract
{
protected:
virtual std::string Foo() {
- return "C++ " + FooBarAbs::Foo();
+ return "C++ " + FooBarAbstract::Foo();
}
virtual std::string Bar() {
diff --git a/Examples/go/callback/Makefile b/Examples/go/callback/Makefile
new file mode 100644
index 000000000..7441e09bd
--- /dev/null
+++ b/Examples/go/callback/Makefile
@@ -0,0 +1,24 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = callback.cxx
+GOSRCS = gocallback.go
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+check: build
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
+
+build:
+ if [ -n '$(SRCDIR)' ]; then \
+ cp $(GOSRCS:%=$(SRCDIR)/%) .; \
+ fi
+ @# Note: example.go gets generated by SWIG
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' GOSRCS='example.go $(GOSRCS)' \
+ SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean:
+ if [ -n '$(SRCDIR)' ]; then \
+ rm $(GOSRCS) || true; \
+ fi
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean
diff --git a/Examples/go/callback/callback.cxx b/Examples/go/callback/callback.cxx
new file mode 100644
index 000000000..450d75608
--- /dev/null
+++ b/Examples/go/callback/callback.cxx
@@ -0,0 +1,4 @@
+/* File : example.cxx */
+
+#include "example.h"
+
diff --git a/Examples/go/callback/example.h b/Examples/go/callback/example.h
new file mode 100644
index 000000000..74ddad954
--- /dev/null
+++ b/Examples/go/callback/example.h
@@ -0,0 +1,22 @@
+/* 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(); }
+};
diff --git a/Examples/go/callback/example.i b/Examples/go/callback/example.i
new file mode 100644
index 000000000..cf61ef9d2
--- /dev/null
+++ b/Examples/go/callback/example.i
@@ -0,0 +1,11 @@
+/* File : example.i */
+%module(directors="1") example
+%{
+#include "example.h"
+%}
+
+/* turn on director wrapping Callback */
+%feature("director") Callback;
+
+%include "example.h"
+
diff --git a/Examples/go/callback/gocallback.go b/Examples/go/callback/gocallback.go
new file mode 100644
index 000000000..20fd0627a
--- /dev/null
+++ b/Examples/go/callback/gocallback.go
@@ -0,0 +1,41 @@
+package example
+
+import (
+ "fmt"
+)
+
+type GoCallback interface {
+ Callback
+ deleteCallback()
+ IsGoCallback()
+}
+
+type goCallback struct {
+ Callback
+}
+
+func (p *goCallback) deleteCallback() {
+ DeleteDirectorCallback(p.Callback)
+}
+
+func (p *goCallback) IsGoCallback() {}
+
+type overwrittenMethodsOnCallback struct {
+ p Callback
+}
+
+func NewGoCallback() GoCallback {
+ om := &overwrittenMethodsOnCallback{}
+ p := NewDirectorCallback(om)
+ om.p = p
+
+ return &goCallback{Callback: p}
+}
+
+func DeleteGoCallback(p GoCallback) {
+ p.deleteCallback()
+}
+
+func (p *goCallback) Run() {
+ fmt.Println("GoCallback.Run")
+}
diff --git a/Examples/go/callback/index.html b/Examples/go/callback/index.html
new file mode 100644
index 000000000..9a53065b0
--- /dev/null
+++ b/Examples/go/callback/index.html
@@ -0,0 +1,31 @@
+<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.
+See the <a href="../../../Doc/Manual/Go.html#Go_director_classes">Go Director
+Classes</a> documentation subsection for an in-depth explanation how to use the
+director feature.
+</p>
+
+<p>
+<ul>
+<li><a href="example.h">example.h</a>. Header with the definition of the Caller and Callback classes.
+<li><a href="example.i">example.i</a>. SWIG interface file.
+<li><a href="gocallback.go">gocallback.go</a>. Go source with the definition of the GoCallback class.
+<li><a href="runme.go">runme.go</a>. Sample Go program.
+</ul>
+
+<hr>
+</body>
+</html>
diff --git a/Examples/go/callback/runme.go b/Examples/go/callback/runme.go
new file mode 100644
index 000000000..03ab0c5e2
--- /dev/null
+++ b/Examples/go/callback/runme.go
@@ -0,0 +1,33 @@
+package main
+
+import (
+ . "./example"
+ "fmt"
+)
+
+func main() {
+ fmt.Println("Adding and calling a normal C++ callback")
+ fmt.Println("----------------------------------------")
+
+ caller := NewCaller()
+ callback := NewCallback()
+
+ caller.SetCallback(callback)
+ caller.Call()
+ caller.DelCallback()
+
+ go_callback := NewGoCallback()
+
+ fmt.Println()
+ fmt.Println("Adding and calling a Go callback")
+ fmt.Println("--------------------------------")
+
+ caller.SetCallback(go_callback)
+ caller.Call()
+ caller.DelCallback()
+
+ DeleteGoCallback(go_callback)
+
+ fmt.Println()
+ fmt.Println("Go exit")
+}
diff --git a/Examples/go/check.list b/Examples/go/check.list
index 25322352a..b3f34b306 100644
--- a/Examples/go/check.list
+++ b/Examples/go/check.list
@@ -1,8 +1,10 @@
# see top-level Makefile.in
+callback
class
constants
director
enum
+extend
funcptr
multimap
pointer
diff --git a/Examples/go/director/Makefile b/Examples/go/director/Makefile
index 84de5855d..2e9e87b89 100644
--- a/Examples/go/director/Makefile
+++ b/Examples/go/director/Makefile
@@ -1,7 +1,7 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
-CXXSRCS =
-GOSRCS = example.go director.go # example.go gets generated by SWIG
+CXXSRCS =
+GOSRCS = director.go
TARGET = example
INTERFACE = example.i
SWIGOPT =
@@ -11,13 +11,14 @@ check: build
build:
if [ -n '$(SRCDIR)' ]; then \
- cp $(SRCDIR)/director.go .; \
+ cp $(GOSRCS:%=$(SRCDIR)/%) .; \
fi
- $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' GOSRCS='$(GOSRCS)' \
+ @# Note: example.go gets generated by SWIG
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' GOSRCS='example.go $(GOSRCS)' \
SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
clean:
if [ -n '$(SRCDIR)' ]; then \
- rm director.go || true; \
+ rm $(GOSRCS) || true; \
fi
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean
diff --git a/Examples/go/director/director.go b/Examples/go/director/director.go
index a5078fe58..4f99bfc6d 100644
--- a/Examples/go/director/director.go
+++ b/Examples/go/director/director.go
@@ -1,70 +1,72 @@
package example
-// FooBarGo is a superset of FooBarAbs and hence FooBarGo can be used as a drop
-// in replacement for FooBarAbs but the reverse causes a compile time error.
+// FooBarGo is a superset of FooBarAbstract and hence FooBarGo can be used as a
+// drop in replacement for FooBarAbstract but the reverse causes a compile time
+// error.
type FooBarGo interface {
- FooBarAbs
- deleteFooBarAbs()
+ FooBarAbstract
+ deleteFooBarAbstract()
IsFooBarGo()
}
-// Via embedding fooBarGo "inherits" all methods of FooBarAbs.
+// Via embedding fooBarGo "inherits" all methods of FooBarAbstract.
type fooBarGo struct {
- FooBarAbs
+ FooBarAbstract
}
-func (fbgs *fooBarGo) deleteFooBarAbs() {
- DeleteDirectorFooBarAbs(fbgs.FooBarAbs)
+func (fbgs *fooBarGo) deleteFooBarAbstract() {
+ DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
}
-// The IsFooBarGo method ensures that FooBarGo is a superset of FooBarAbs.
+// The IsFooBarGo method ensures that FooBarGo is a superset of FooBarAbstract.
// This is also how the class hierarchy gets represented by the SWIG generated
-// wrapper code. For an instance FooBarCpp has the IsFooBarAbs and IsFooBarCpp
-// methods.
+// wrapper code. For an instance FooBarCpp has the IsFooBarAbstract and
+// IsFooBarCpp methods.
func (fbgs *fooBarGo) IsFooBarGo() {}
// Go type that defines the DirectorInterface. It contains the Foo and Bar
-// methods that overwrite the respective virtual C++ methods on FooBarAbs.
-type overwrittenMethodsOnFooBarAbs struct {
- // Backlink to FooBarAbs so that the rest of the class can be used by the
- // overridden methods.
- fb FooBarAbs
+// methods that overwrite the respective virtual C++ methods on FooBarAbstract.
+type overwrittenMethodsOnFooBarAbstract struct {
+ // Backlink to FooBarAbstract so that the rest of the class can be used by
+ // the overridden methods.
+ fb FooBarAbstract
// If additional constructor arguments have been given they are typically
// stored here so that the overriden methods can use them.
}
-func (om *overwrittenMethodsOnFooBarAbs) Foo() string {
- // DirectorFooBarAbsFoo calls the base method FooBarAbs::Foo.
- return "Go " + DirectorFooBarAbsFoo(om.fb)
+func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
+ // DirectorFooBarAbstractFoo calls the base method FooBarAbstract::Foo.
+ return "Go " + DirectorFooBarAbstractFoo(om.fb)
}
-func (om *overwrittenMethodsOnFooBarAbs) Bar() string {
+func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
return "Go Bar"
}
func NewFooBarGo() FooBarGo {
- // Instantiate FooBarAbs with selected methods overridden. The methods that
- // will be overwritten are defined on overwrittenMethodsOnFooBarAbs and have
- // a compatible signature to the respective virtual C++ methods.
- // Furthermore additional constructor arguments will be typically stored in
- // the overwrittenMethodsOnFooBarAbs struct.
- om := &overwrittenMethodsOnFooBarAbs{}
- fb := NewDirectorFooBarAbs(om)
+ // Instantiate FooBarAbstract with selected methods overridden. The methods
+ // that will be overwritten are defined on
+ // overwrittenMethodsOnFooBarAbstract and have a compatible signature to the
+ // respective virtual C++ methods. Furthermore additional constructor
+ // arguments will be typically stored in the
+ // overwrittenMethodsOnFooBarAbstract struct.
+ om := &overwrittenMethodsOnFooBarAbstract{}
+ fb := NewDirectorFooBarAbstract(om)
om.fb = fb // Backlink causes cycle as fb.v = om!
- fbgs := &fooBarGo{FooBarAbs: fb}
- // The memory of the FooBarAbs director object instance can be automatically
- // freed once the FooBarGo instance is garbage collected by uncommenting the
- // following line. Please make sure to understand the runtime.SetFinalizer
- // specific gotchas before doing this. Furthemore DeleteFooBarGo should be
- // deleted if a finalizer is in use or the fooBarGo struct needs additional
- // data to prevent double deletion.
- // runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbs)
+ fbgs := &fooBarGo{FooBarAbstract: fb}
+ // The memory of the FooBarAbstract director object instance can be
+ // automatically freed once the FooBarGo instance is garbage collected by
+ // uncommenting the following line. Please make sure to understand the
+ // runtime.SetFinalizer specific gotchas before doing this. Furthemore
+ // DeleteFooBarGo should be deleted if a finalizer is in use or the fooBarGo
+ // struct needs additional data to prevent double deletion.
+ // runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
return fbgs
}
// Recommended to be removed if runtime.SetFinalizer is in use.
func DeleteFooBarGo(fbg FooBarGo) {
- fbg.deleteFooBarAbs()
+ fbg.deleteFooBarAbstract()
}
diff --git a/Examples/go/director/director.h b/Examples/go/director/director.h
index e08c11594..339a9adcd 100644
--- a/Examples/go/director/director.h
+++ b/Examples/go/director/director.h
@@ -6,11 +6,11 @@
#include <string>
-class FooBarAbs
+class FooBarAbstract
{
public:
- FooBarAbs() {};
- virtual ~FooBarAbs() {};
+ FooBarAbstract() {};
+ virtual ~FooBarAbstract() {};
std::string FooBar() {
return this->Foo() + ", " + this->Bar();
@@ -25,11 +25,11 @@ protected:
};
-class FooBarCpp : public FooBarAbs
+class FooBarCpp : public FooBarAbstract
{
protected:
virtual std::string Foo() {
- return "C++ " + FooBarAbs::Foo();
+ return "C++ " + FooBarAbstract::Foo();
}
virtual std::string Bar() {
diff --git a/Examples/go/director/example.i b/Examples/go/director/example.i
index b56998e6d..e832bd8c6 100644
--- a/Examples/go/director/example.i
+++ b/Examples/go/director/example.i
@@ -7,5 +7,5 @@
#include "director.h"
%}
-%feature("director") FooBarAbs;
+%feature("director") FooBarAbstract;
%include "director.h"
diff --git a/Examples/go/director/index.html b/Examples/go/director/index.html
index d1d5a74bc..b93e780e5 100644
--- a/Examples/go/director/index.html
+++ b/Examples/go/director/index.html
@@ -18,7 +18,7 @@ Classes</a> documentation subsection for an explanation of this example.
<p>
<ul>
<li><a href="director.go">director.go</a>. Go source with the definition of the FooBarGo class.
-<li><a href="director.h">director.h</a>. Header with the definition of the FooBarAbs and FooBarCpp classes.
+<li><a href="director.h">director.h</a>. Header with the definition of the FooBarAbstract and FooBarCpp classes.
<li><a href="example.i">example.i</a>. SWIG interface file.
<li><a href="runme.go">runme.go</a>. Sample Go program.
</ul>
diff --git a/Examples/go/extend/Makefile b/Examples/go/extend/Makefile
new file mode 100644
index 000000000..a9f2d8d7d
--- /dev/null
+++ b/Examples/go/extend/Makefile
@@ -0,0 +1,24 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = extend.cxx
+GOSRCS = ceo.go
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+check: build
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
+
+build:
+ if [ -n '$(SRCDIR)' ]; then \
+ cp $(GOSRCS:%=$(SRCDIR)/%) .; \
+ fi
+ @# Note: example.go gets generated by SWIG
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' GOSRCS='example.go $(GOSRCS)' \
+ SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean:
+ if [ -n '$(SRCDIR)' ]; then \
+ rm $(GOSRCS) || true; \
+ fi
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean
diff --git a/Examples/go/extend/ceo.go b/Examples/go/extend/ceo.go
new file mode 100644
index 000000000..8f00c92f2
--- /dev/null
+++ b/Examples/go/extend/ceo.go
@@ -0,0 +1,37 @@
+package example
+
+type CEO interface {
+ Manager
+ deleteManager()
+ IsCEO()
+}
+
+type ceo struct {
+ Manager
+}
+
+func (p *ceo) deleteManager() {
+ DeleteDirectorManager(p.Manager)
+}
+
+func (p *ceo) IsCEO() {}
+
+type overwrittenMethodsOnManager struct {
+ p Manager
+}
+
+func NewCEO(name string) CEO {
+ om := &overwrittenMethodsOnManager{}
+ p := NewDirectorManager(om, name)
+ om.p = p
+
+ return &ceo{Manager: p}
+}
+
+func DeleteCEO(p CEO) {
+ p.deleteManager()
+}
+
+func (p *ceo) GetPosition() string {
+ return "CEO"
+}
diff --git a/Examples/go/extend/example.h b/Examples/go/extend/example.h
new file mode 100644
index 000000000..0c3b721bd
--- /dev/null
+++ b/Examples/go/extend/example.h
@@ -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", (void *)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;
+ }
+};
+
diff --git a/Examples/go/extend/example.i b/Examples/go/extend/example.i
new file mode 100644
index 000000000..c8ec32e09
--- /dev/null
+++ b/Examples/go/extend/example.i
@@ -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"
+
diff --git a/Examples/go/extend/extend.cxx b/Examples/go/extend/extend.cxx
new file mode 100644
index 000000000..450d75608
--- /dev/null
+++ b/Examples/go/extend/extend.cxx
@@ -0,0 +1,4 @@
+/* File : example.cxx */
+
+#include "example.h"
+
diff --git a/Examples/go/extend/index.html b/Examples/go/extend/index.html
new file mode 100644
index 000000000..31788b2aa
--- /dev/null
+++ b/Examples/go/extend/index.html
@@ -0,0 +1,30 @@
+<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 how to inherit from a C++ class in Go.
+See the <a href="../../../Doc/Manual/Go.html#Go_director_classes">Go Director
+Classes</a> documentation subsection for an in-depth explanation how to use the
+director feature.
+<p>
+
+<ul>
+<li><a href="ceo.go">ceo.go</a>. Go source with the definition of the CEO class.
+<li><a href="example.h">example.h</a>. Header with the definition of the Employee, Manager and EmployeeList classes.
+<li><a href="example.i">example.i</a>. SWIG interface file.
+<li><a href="runme.go">runme.go</a>. Sample Go program.
+</ul>
+
+<hr>
+</body>
+</html>
diff --git a/Examples/go/extend/runme.go b/Examples/go/extend/runme.go
new file mode 100644
index 000000000..a56968937
--- /dev/null
+++ b/Examples/go/extend/runme.go
@@ -0,0 +1,66 @@
+// This file illustrates the cross language polymorphism using directors.
+
+package main
+
+import (
+ . "./example"
+ "fmt"
+)
+
+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 := NewCEO("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 overridden
+ // 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 Go 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 Go 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 and hence there is no need to
+ // call DeleteCEO.
+ DeleteEmployeeList(list)
+ fmt.Println("----------------------")
+
+ // All done.
+ fmt.Println("Go exit")
+}
diff --git a/Examples/go/index.html b/Examples/go/index.html
index b7d7017d3..467f4ecb7 100644
--- a/Examples/go/index.html
+++ b/Examples/go/index.html
@@ -21,6 +21,8 @@ certain C declarations are turned into constants.
<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.
<li><a href="director/index.html">director</a>. Example how to utilize the director feature.
</ul>