summaryrefslogtreecommitdiff
path: root/Examples
diff options
context:
space:
mode:
authorMichael Schaller <michael@5challer.de>2015-08-08 19:44:41 +0200
committerMichael Schaller <michael@5challer.de>2015-08-09 14:36:58 +0200
commita941e5b605670a8b4686cec5f0d87562846552e2 (patch)
tree1b33255f68ec4d270b482a8d84f66179fed8d9c1 /Examples
parent19a20c794bea67fb7e3530da362473c05cf87cad (diff)
downloadswig-a941e5b605670a8b4686cec5f0d87562846552e2.tar.gz
[Go] Revert commit 5e88857 to undelete the 'callback' and 'extend' examples.
The 'callback' and 'extend' examples were presumed to be obsoleted by the new 'director' example. The examples are helpful though to have similar examples across target languages and hence the commit @5e88857 which removed these examples got reverted.
Diffstat (limited to 'Examples')
-rw-r--r--Examples/go/callback/Makefile16
-rw-r--r--Examples/go/callback/callback.cxx4
-rw-r--r--Examples/go/callback/example.h23
-rw-r--r--Examples/go/callback/example.i11
-rw-r--r--Examples/go/callback/index.html81
-rw-r--r--Examples/go/callback/runme.go41
-rw-r--r--Examples/go/check.list2
-rw-r--r--Examples/go/extend/Makefile16
-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.html27
-rw-r--r--Examples/go/extend/runme.go76
-rw-r--r--Examples/go/index.html3
14 files changed, 374 insertions, 1 deletions
diff --git a/Examples/go/callback/Makefile b/Examples/go/callback/Makefile
new file mode 100644
index 000000000..bf5275f14
--- /dev/null
+++ b/Examples/go/callback/Makefile
@@ -0,0 +1,16 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = callback.cxx
+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)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean:
+ $(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..1a0e8c432
--- /dev/null
+++ b/Examples/go/callback/example.h
@@ -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(); }
+};
+
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/index.html b/Examples/go/callback/index.html
new file mode 100644
index 000000000..b053cf547
--- /dev/null
+++ b/Examples/go/callback/index.html
@@ -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>
diff --git a/Examples/go/callback/runme.go b/Examples/go/callback/runme.go
new file mode 100644
index 000000000..2eef77fdb
--- /dev/null
+++ b/Examples/go/callback/runme.go
@@ -0,0 +1,41 @@
+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()
+
+ 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")
+}
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/extend/Makefile b/Examples/go/extend/Makefile
new file mode 100644
index 000000000..290694210
--- /dev/null
+++ b/Examples/go/extend/Makefile
@@ -0,0 +1,16 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = extend.cxx
+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)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean:
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean
diff --git a/Examples/go/extend/example.h b/Examples/go/extend/example.h
new file mode 100644
index 000000000..ca1aed28f
--- /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..471fa9cdc
--- /dev/null
+++ b/Examples/go/extend/index.html
@@ -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>
diff --git a/Examples/go/extend/runme.go b/Examples/go/extend/runme.go
new file mode 100644
index 000000000..770e27802
--- /dev/null
+++ b/Examples/go/extend/runme.go
@@ -0,0 +1,76 @@
+// This file illustrates the cross language polymorphism using directors.
+
+package main
+
+import (
+ . "./example"
+ "fmt"
+)
+
+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 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 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")
+}
diff --git a/Examples/go/index.html b/Examples/go/index.html
index b7d7017d3..ed6a6b707 100644
--- a/Examples/go/index.html
+++ b/Examples/go/index.html
@@ -21,7 +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="director/index.html">director</a>. Example how to utilize the director feature.
+<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>