Some improvements to the Go documentation. From Gary Holt

<gholt@google.com>.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12719 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Ian Lance Taylor 2011-05-27 00:04:32 +00:00
commit 49532b7181
2 changed files with 161 additions and 2 deletions

View file

@ -764,6 +764,8 @@
<li><a href="Go.html#Go_templates">Go Templates</a>
<li><a href="Go.html#Go_director_classes">Go Director Classes</a>
<li><a href="Go.html#Go_primitive_type_mappings">Default Go primitive type mappings</a>
<li><a href="#Go_output_arguments">Output arguments</a>
<li><a href="#Go_adding_additional_code">Adding additional go code</a>
</ul>
</ul>
</div>
@ -1689,4 +1691,3 @@
</BODY>
</HTML>

View file

@ -28,6 +28,8 @@
<li><a href="#Go_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>
<li><a href="#Go_output_arguments">Output arguments</a>
<li><a href="#Go_adding_additional_code">Adding additional go code</a>
</ul>
</ul>
</div>
@ -273,7 +275,7 @@ class.
<p>
SWIG will represent static methods of C++ classes as ordinary Go
functions. SWIG will use names like <tt>ClassName_MethodName</tt>.
functions. SWIG will use names like <tt>ClassNameMethodName</tt>.
SWIG will give static members getter and setter functions with names
like <tt>GetClassName_VarName</tt>.
</p>
@ -289,6 +291,37 @@ 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>
<p>Note that C++ pointers to compound objects are represented in go as objects
themselves, not as go pointers. So, for example, if you wrap the following
function:</p>
<div class="code">
<pre>
class MyClass {
int MyMethod();
static MyClass *MyFactoryFunction();
};
</pre>
</div>
<p>You will get go code that looks like this:</p>
<div class="code">
<pre>
type MyClass interface {
Swigcptr() uintptr
SwigIsMyClass()
MyMethod() int
}
MyClassMyFactoryFunction() MyClass {
// swig magic here
}
</pre>
</div>
<p>Note that the factory function does not return a go pointer; it actually
returns a go interface. If the returned pointer can be null, you can check
for this by calling the Swigcptr() method.
</p>
<H4><a name="Go_class_inheritance"></a>21.3.5.1 Go Class Inheritance</H4>
@ -459,5 +492,130 @@ that typemap, or add new values, to control how C/C++ types are mapped
into Go types.
</p>
<H3><a name="Go_output_arguments"></a>21.3.9 Output arguments</H3>
<p>Because of limitations in the way output arguments are processed in swig,
a function with output arguments will not have multiple return values.
Instead, you must pass a pointer into the C++ function to tell it where to
store the ouput value. In go, you supply a slice in the place of the output
argument.</p>
<p>For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
returns the integer part in one of its parameters):<p>
<div class="code">
<pre>
double modf(double x, double *ip);
</pre>
</div>
<p>You could wrap it with SWIG as follows:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
double modf(double x, double *OUTPUT);
</pre>
</div>
<p>or you can use the <code>%apply</code> directive:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
</pre>
</div>
<p>In Go you would use it like this:</p>
<div class="code">
<pre>
ptr := []float64{0.0}
fraction := modulename.Modf(5.0, ptr)
</pre>
</div>
<p>Since this is ugly, you may want to wrap the swig-generated API with
some <a href="#Embedded_go_code">additional functions written in go</a> that
hide the ugly details.</p>
<p>There are no <code>char&nbsp;*OUTPUT</code> typemaps. However you can
apply the <code>signed&nbsp;char&nbsp;*</code> typemaps instead:<p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
%apply signed char *OUTPUT {char *output};
void f(char *output);
</pre>
</div>
<H3><a name="Go_adding_additional_code"></a>21.3.10 Adding additional go code</H3>
<p>Often the APIs generated by swig are not very natural in go, especially if
there are output arguments. You can
insert additional go wrapping code to add new APIs
with <code>%insert(go_wrapper)</code>, like this:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
// Change name of what swig generates to Wrapped_modf. This function will
// have the following signature in go:
// func Wrapped_modf(float64, []float64) float64
%rename(wrapped_modf) modf(double x, double *ip);
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
%insert(go_wrapper) %{
// The improved go interface to this function, which has two return values,
// in the more natural go idiom:
func Modf(x float64) (fracPart float64, intPart float64) {
ip := []float64{0.0}
fracPart = Wrapped_modf(x, ip)
intPart = ip[0]
return
}
%}
</pre>
</div>
<p>For classes, since swig generates an interface, you can add additional
methods by defining another interface that includes the swig-generated
interface. For example,</p>
<div class="code">
<pre>
%rename(Wrapped_MyClass) MyClass;
%rename(Wrapped_GetAValue) MyClass::GetAValue(int *x);
%apply int *OUTPUT { int *x };
class MyClass {
public:
MyClass();
int AFineMethod(const char *arg); // Swig's wrapping is fine for this one.
bool GetAValue(int *x);
};
%insert(go_wrapper) %{
type MyClass interface {
Wrapped_MyClass
GetAValue() (int, bool)
}
func (arg SwigcptrWrapped_MyClass) GetAValue() (int, bool) {
ip := []int{0}
ok := arg.Wrapped_GetAValue(ip)
return ip[0], ok
}
%}
</pre>
</div>
<p>Of course, if you have to rewrite most of the methods, instead of just a
few, then you might as well define your own struct that includes the
swig-wrapped object, instead of adding methods to the swig-generated object.</p>
<p>This only works if your wrappers do not need to import other go modules.
There is at present no way to insert import statements in the correct place
in swig-generated go. If you need to do that, you must put your go code
in a separate file.</p>
</body>
</html>