aboutsummaryrefslogtreecommitdiff
path: root/Examples/go/reference/index.html
blob: ebf366bc075ee682492ce5b017ae7734f928612d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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:
 ...
   %extend {
    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>