Fleshed out Go's documentation about the director feature and added a director example.
Fixes issues #418.
This commit is contained in:
parent
5d363276f5
commit
a17c9727bd
8 changed files with 741 additions and 25 deletions
|
|
@ -2,6 +2,7 @@
|
|||
callback
|
||||
class
|
||||
constants
|
||||
director
|
||||
enum
|
||||
extend
|
||||
funcptr
|
||||
|
|
|
|||
17
Examples/go/director/Makefile
Normal file
17
Examples/go/director/Makefile
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS =
|
||||
GOSRCS = example.go director.go # example.go gets generated by SWIG
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
SWIGOPT =
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' GOSRCS='$(GOSRCS)' \
|
||||
SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean
|
||||
70
Examples/go/director/director.go
Normal file
70
Examples/go/director/director.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
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.
|
||||
type FooBarGo interface {
|
||||
FooBarAbs
|
||||
deleteFooBarAbs()
|
||||
IsFooBarGo()
|
||||
}
|
||||
|
||||
// Via embedding fooBarGo "inherits" all methods of FooBarAbs.
|
||||
type fooBarGo struct {
|
||||
FooBarAbs
|
||||
}
|
||||
|
||||
func (fbgs *fooBarGo) deleteFooBarAbs() {
|
||||
DeleteDirectorFooBarAbs(fbgs.FooBarAbs)
|
||||
}
|
||||
|
||||
// The IsFooBarGo method ensures that FooBarGo is a superset of FooBarAbs.
|
||||
// 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.
|
||||
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 overwritenMethodsOnFooBarAbs struct {
|
||||
// Backlink to FooBarAbs so that the rest of the class can be used by the
|
||||
// overridden methods.
|
||||
fb FooBarAbs
|
||||
|
||||
// If additional constructor arguments have been given they are typically
|
||||
// stored here so that the overriden methods can use them.
|
||||
}
|
||||
|
||||
func (om *overwritenMethodsOnFooBarAbs) Foo() string {
|
||||
// DirectorFooBarAbsFoo calls the base method FooBarAbs::Foo.
|
||||
return "Go " + DirectorFooBarAbsFoo(om.fb)
|
||||
}
|
||||
|
||||
func (om *overwritenMethodsOnFooBarAbs) Bar() string {
|
||||
return "Go Bar"
|
||||
}
|
||||
|
||||
func NewFooBarGo() FooBarGo {
|
||||
// Instantiate FooBarAbs with selected methods overridden. The methods that
|
||||
// will be overwritten are defined on overwritenMethodsOnFooBarAbs and have
|
||||
// a compatible signature to the respective virtual C++ methods.
|
||||
// Furthermore additional constructor arguments will be typically stored in
|
||||
// the overwritenMethodsOnFooBarAbs struct.
|
||||
om := &overwritenMethodsOnFooBarAbs{}
|
||||
fb := NewDirectorFooBarAbs(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)
|
||||
return fbgs
|
||||
}
|
||||
|
||||
// Recommended to be removed if runtime.SetFinalizer is in use.
|
||||
func DeleteFooBarGo(fbg FooBarGo) {
|
||||
fbg.deleteFooBarAbs()
|
||||
}
|
||||
41
Examples/go/director/director.h
Normal file
41
Examples/go/director/director.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef DIRECTOR_H
|
||||
#define DIRECTOR_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
class FooBarAbs
|
||||
{
|
||||
public:
|
||||
FooBarAbs() {};
|
||||
virtual ~FooBarAbs() {};
|
||||
|
||||
std::string FooBar() {
|
||||
return this->Foo() + ", " + this->Bar();
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual std::string Foo() {
|
||||
return "Foo";
|
||||
};
|
||||
|
||||
virtual std::string Bar() = 0;
|
||||
};
|
||||
|
||||
|
||||
class FooBarCpp : public FooBarAbs
|
||||
{
|
||||
protected:
|
||||
virtual std::string Foo() {
|
||||
return "C++ " + FooBarAbs::Foo();
|
||||
}
|
||||
|
||||
virtual std::string Bar() {
|
||||
return "C++ Bar";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
11
Examples/go/director/example.i
Normal file
11
Examples/go/director/example.i
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* File : example.i */
|
||||
%module(directors="1") example
|
||||
|
||||
%include "std_string.i"
|
||||
|
||||
%header %{
|
||||
#include "director.h"
|
||||
%}
|
||||
|
||||
%feature("director") FooBarAbs;
|
||||
%include "director.h"
|
||||
28
Examples/go/director/index.html
Normal file
28
Examples/go/director/index.html
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SWIG:Examples:go:director</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
|
||||
<tt>SWIG/Examples/go/director/</tt>
|
||||
<hr>
|
||||
|
||||
<H2>How to subclass a C++ class with a Go type</H2>
|
||||
|
||||
<p>
|
||||
See the <a href="../../../Doc/Manual/Go.html#Go_director_classes">Go Director
|
||||
Classes</a> documentation subsection for an explanation of this example.
|
||||
</p>
|
||||
|
||||
<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="example.i">example.i</a>. SWIG interface file.
|
||||
<li><a href="runme.go">runme.go</a>. Sample Go program.
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
||||
39
Examples/go/director/runme.go
Normal file
39
Examples/go/director/runme.go
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"./example"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func Compare(name string, got string, exp string) error {
|
||||
fmt.Printf("%s; Got: '%s'; Expected: '%s'\n", name, got, exp)
|
||||
if got != exp {
|
||||
return fmt.Errorf("%s returned unexpected string! Got: '%s'; Expected: '%s'\n", name, got, exp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestFooBarCpp() error {
|
||||
fb := example.NewFooBarCpp()
|
||||
defer example.DeleteFooBarCpp(fb)
|
||||
return Compare("FooBarCpp.FooBar()", fb.FooBar(), "C++ Foo, C++ Bar")
|
||||
}
|
||||
|
||||
func TestFooBarGo() error {
|
||||
fb := example.NewFooBarGo()
|
||||
defer example.DeleteFooBarGo(fb)
|
||||
return Compare("FooBarGo.FooBar()", fb.FooBar(), "Go Foo, Go Bar")
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Test output:")
|
||||
fmt.Println("------------")
|
||||
err := TestFooBarCpp()
|
||||
err = TestFooBarGo()
|
||||
fmt.Println("------------")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Tests failed! Last error: %s\n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue