mirror of https://github.com/swig/swig
1533 lines
44 KiB
HTML
1533 lines
44 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>SWIG and Go</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
</head>
|
|
<body bgcolor="#FFFFFF">
|
|
<H1><a name="Go">25 SWIG and Go</a></H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Go_overview">Overview</a>
|
|
<li><a href="#Go_examples">Examples</a>
|
|
<li><a href="#Go_running_swig">Running SWIG with Go</a>
|
|
<ul>
|
|
<li><a href="#Go_commandline">Go-specific Commandline Options</a>
|
|
<li><a href="#Go_outputs">Generated Wrapper Files</a>
|
|
</ul>
|
|
<li><a href="#Go_basic_tour">A tour of basic C/C++ wrapping</a>
|
|
<ul>
|
|
<li><a href="#Go_package">Go Package Name</a>
|
|
<li><a href="#Go_names">Go Names</a>
|
|
<li><a href="#Go_constants">Go Constants</a>
|
|
<li><a href="#Go_enumerations">Go Enumerations</a>
|
|
<li><a href="#Go_classes">Go Classes</a>
|
|
<ul>
|
|
<li><a href="#Go_class_memory">Go Class Memory Management</a>
|
|
<li><a href="#Go_class_inheritance">Go Class Inheritance</a>
|
|
</ul>
|
|
<li><a href="#Go_templates">Go Templates</a>
|
|
<li><a href="#Go_threads">Go and C/C++ Threads</a>
|
|
<li><a href="#Go_exceptions">Go and C++ Exceptions</a>
|
|
<li><a href="#Go_director_classes">Go Director Classes</a>
|
|
<ul>
|
|
<li><a href="#Go_director_example_cpp_code">Example C++ code</a>
|
|
<li><a href="#Go_director_enable">Enable director feature</a>
|
|
<li><a href="#Go_director_ctor_dtor">Constructor and destructor</a>
|
|
<li><a href="#Go_director_overriding">Override virtual methods</a>
|
|
<li><a href="#Go_director_base_methods">Call base methods</a>
|
|
<li><a href="#Go_director_subclass">Subclass via embedding</a>
|
|
<li><a href="#Go_director_finalizer">Memory management with runtime.SetFinalizer</a>
|
|
<li><a href="#Go_director_foobargo_class">Complete FooBarGo example class</a>
|
|
</ul>
|
|
<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>
|
|
<li><a href="#Go_typemaps">Go typemaps</a>
|
|
</ul>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
This chapter describes SWIG's support of Go. For more information on
|
|
the Go programming language
|
|
see <a href="https://golang.org/">golang.org</a>.
|
|
</p>
|
|
|
|
<H2><a name="Go_overview">25.1 Overview</a></H2>
|
|
|
|
|
|
<p>
|
|
Go does not support direct calling of functions written in C/C++. The
|
|
<a href="https://golang.org/cmd/cgo/">cgo program</a> may be used to generate
|
|
wrappers to call C code from Go, but there is no convenient way to call C++
|
|
code. SWIG fills this gap.
|
|
</p>
|
|
|
|
<p>
|
|
There are (at least) two different Go compilers. The first is the gc compiler
|
|
of the <a href="https://golang.org/doc/install">Go distribution</a>, normally
|
|
invoked via the <a href="https://golang.org/cmd/go/">go tool</a>.
|
|
SWIG supports the gc compiler version 1.20 or later.
|
|
The second Go compiler is the <a href="https://golang.org/doc/install/gccgo">
|
|
gccgo compiler</a>, which is a frontend to the GCC compiler suite.
|
|
The interface to C/C++ code is completely different for the two Go compilers.
|
|
SWIG supports both Go compilers, selected by the <tt>-gccgo</tt> command line
|
|
option.
|
|
</p>
|
|
|
|
<p>
|
|
Go is a type-safe compiled language and the wrapper code generated by SWIG is
|
|
type-safe as well. In case of type issues the build will fail and hence SWIG's
|
|
<a href="Modules.html#Modules_nn2">runtime library</a> and
|
|
<a href="Typemaps.html#Typemaps_runtime_type_checker">runtime type checking</a>
|
|
are not used.
|
|
</p>
|
|
|
|
<H2><a name="Go_examples">25.2 Examples</a></H2>
|
|
|
|
|
|
<p>
|
|
Working examples can be found in the
|
|
<a href="https://github.com/swig/swig/tree/master/Examples/go">SWIG source tree
|
|
</a>.
|
|
</p>
|
|
|
|
<p>
|
|
Please note that the examples in the SWIG source tree use makefiles with the .i
|
|
SWIG interface file extension for backwards compatibility with Go 1.
|
|
</p>
|
|
|
|
|
|
<H2><a name="Go_running_swig">25.3 Running SWIG with Go</a></H2>
|
|
|
|
|
|
<p>
|
|
Most Go programs are built using the <a href="https://golang.org/cmd/go/">go
|
|
tool</a>. Since Go 1.1 the go tool has support for SWIG. To use it, give your
|
|
SWIG interface file the extension .swig (for C code) or .swigcxx (for C++ code).
|
|
Put that file in a GOPATH/src directory as usual for Go sources. Put other
|
|
C/C++ code in the same directory with extensions of .c and .cxx. The
|
|
<tt>go build</tt> and <tt>go install</tt> commands will automatically run SWIG
|
|
for you and compile the generated wrapper code. To check the SWIG command line
|
|
options the go tool uses run <tt>go build -x</tt>. To access the automatically
|
|
generated files run <tt>go build -work</tt>. You'll find the files under the
|
|
temporary WORK directory.
|
|
</p>
|
|
|
|
<p>
|
|
To manually generate and compile C/C++ wrapper code for Go, use the <tt>-go</tt>
|
|
option with SWIG. By default SWIG will generate code for the Go compiler of the
|
|
Go distribution. To generate code for gccgo, you should also use the
|
|
<tt>-gccgo</tt> option.
|
|
</p>
|
|
|
|
<p>
|
|
By default SWIG will generate files that can be used directly
|
|
by <tt>go build</tt>. This requires Go 1.2 or later. Put your SWIG
|
|
interface file in a directory under GOPATH/src, and give it a name
|
|
that does <b>not</b> end in the .swig or .swigcxx extension.
|
|
Typically the SWIG interface file extension is .i in this case.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
% swig -go example.i
|
|
% go install
|
|
</pre></div>
|
|
|
|
<p>
|
|
You will now have a Go package that you can import from other Go packages as
|
|
usual.
|
|
</p>
|
|
|
|
|
|
<H3><a name="Go_commandline">25.3.1 Go-specific Commandline Options</a></H3>
|
|
|
|
|
|
<p>
|
|
These are the command line options for SWIG's Go module. They can
|
|
also be seen by using:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
swig -go -help
|
|
</pre></div>
|
|
|
|
<table summary="Go-specific options">
|
|
<tr>
|
|
<th>Go-specific options</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-cgo</td>
|
|
<td>Generate files to be used as input for the Go cgo tool. This is
|
|
the default.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-no-cgo</td>
|
|
<td>This option is no longer supported.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-intgosize <s></td>
|
|
<td>Set the size for the Go type <tt>int</tt>. This controls the size
|
|
that the C/C++ code expects to see. The <s> argument should
|
|
be 32 or 64. This option was required during the
|
|
transition from Go 1.0 to Go 1.1, as the size of <tt>int</tt> on
|
|
64-bit x86 systems changed between those releases (from 32 bits to
|
|
64 bits). It was made optional in SWIG 4.1.0 and if not specified SWIG
|
|
will assume that the size of <tt>int</tt> is the size of a C
|
|
pointer.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-gccgo</td>
|
|
<td>Generate code for gccgo. The default is to generate code for
|
|
the Go compiler of the Go distribution.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-package <name></td>
|
|
<td>Set the name of the Go package to <name>. The default
|
|
package name is the SWIG module name.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-use-shlib</td>
|
|
<td>Tell SWIG to emit code that uses a shared library. This is only
|
|
meaningful for the Go compiler of the Go distribution, which needs to know at
|
|
compile time whether a shared library will be used.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-soname <name></td>
|
|
<td>Set the runtime name of the shared library that the dynamic linker
|
|
should include at runtime. The default is the package name with
|
|
".so" appended. This is only used when generating code for
|
|
the Go compiler of the Go distribution; when using gccgo, the equivalent name
|
|
will be taken from the <code>-soname</code> option passed to the linker.
|
|
Using this option implies the -use-shlib option.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-go-pkgpath <pkgpath></td>
|
|
<td>When generating code for gccgo, set the pkgpath to use. This
|
|
corresponds to the <tt>-fgo-pkgpath</tt> option to gccgo.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-go-prefix <prefix></td>
|
|
<td>When generating code for gccgo, set the prefix to use. This
|
|
corresponds to the <tt>-fgo-prefix</tt> option to gccgo.
|
|
If <tt>-go-pkgpath</tt> is used, <tt>-go-prefix</tt> will be
|
|
ignored.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-import-prefix <prefix></td>
|
|
<td>A prefix to add when turning a %import prefix in the SWIG
|
|
interface file into an import statement in the Go file. For
|
|
example, with <code>-import-prefix mymodule</code>, a SWIG
|
|
interface file <code>%import mypackage</code> will become a Go
|
|
import statement <code>import "mymodule/mypackage"</code>.</td>
|
|
</table>
|
|
|
|
|
|
<H3><a name="Go_outputs">25.3.2 Generated Wrapper Files</a></H3>
|
|
|
|
|
|
<p>
|
|
SWIG will generate the following files when generating wrapper
|
|
code:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>
|
|
MODULE.go will contain the Go functions that your Go code will call.
|
|
These functions will be wrappers for the C++ functions defined by your
|
|
module. This file should, of course, be compiled with the Go
|
|
compiler.
|
|
</li>
|
|
<li>
|
|
MODULE_wrap.c or MODULE_wrap.cxx will contain C/C++ functions will be
|
|
invoked by the Go wrapper code. This file should be compiled with the
|
|
usual C or C++ compiler.
|
|
</li>
|
|
<li>
|
|
MODULE_wrap.h will be generated if you use the directors feature. It
|
|
provides a definition of the generated C++ director classes. It is
|
|
generally not necessary to use this file, but in some special cases it
|
|
may be helpful to include it in your code, compiled with the usual C
|
|
or C++ compiler.
|
|
</li>
|
|
</ul>
|
|
|
|
|
|
<H2><a name="Go_basic_tour">25.4 A tour of basic C/C++ wrapping</a></H2>
|
|
|
|
|
|
<p>
|
|
By default, SWIG attempts to build a natural Go interface to your
|
|
C/C++ code. However, the languages are somewhat different, so some
|
|
modifications have to occur. This section briefly covers the
|
|
essential aspects of this wrapping.
|
|
</p>
|
|
|
|
<H3><a name="Go_package">25.4.1 Go Package Name</a></H3>
|
|
|
|
|
|
<p>
|
|
All Go source code lives in a package. The name of this package will
|
|
default to the name of the module from SWIG's <tt>%module</tt>
|
|
directive. You may override this by using SWIG's <tt>-package</tt>
|
|
command line option.
|
|
</p>
|
|
|
|
<H3><a name="Go_names">25.4.2 Go Names</a></H3>
|
|
|
|
|
|
<p>
|
|
In Go, a function is only visible outside the current package if the
|
|
first letter of the name is uppercase. This is quite different from
|
|
C/C++. Because of this, C/C++ names are modified when generating the
|
|
Go interface: the first letter is forced to be uppercase if it is not
|
|
already. This affects the names of functions, methods, variables,
|
|
constants, enums, and classes.
|
|
</p>
|
|
|
|
<p>
|
|
C/C++ variables are wrapped with setter and getter functions in Go.
|
|
First the first letter of the variable name will be forced to
|
|
uppercase, and then <tt>Get</tt> or <tt>Set</tt> will be prepended.
|
|
For example, if the C/C++ variable is called <tt>var</tt>, then SWIG
|
|
will define the functions <tt>GetVar</tt> and <tt>SetVar</tt>. If a
|
|
variable is declared as <tt>const</tt>, or if
|
|
SWIG's <a href="SWIG.html#SWIG_readonly_variables">
|
|
<tt>%immutable</tt> directive</a> is used for the variable, then only
|
|
the getter will be defined.
|
|
</p>
|
|
|
|
<p>
|
|
C++ classes will be discussed further below. Here we'll note that the
|
|
first letter of the class name will be forced to uppercase to give the
|
|
name of a type in Go. A constructor will be named <tt>New</tt>
|
|
followed by that name, and the destructor will be
|
|
named <tt>Delete</tt> followed by that name.
|
|
</p>
|
|
|
|
<H3><a name="Go_constants">25.4.3 Go Constants</a></H3>
|
|
|
|
|
|
<p>
|
|
C/C++ constants created via <tt>#define</tt> or the <tt>%constant</tt>
|
|
directive become Go constants, declared with a <tt>const</tt>
|
|
declaration.
|
|
|
|
<H3><a name="Go_enumerations">25.4.4 Go Enumerations</a></H3>
|
|
|
|
|
|
<p>
|
|
C/C++ enumeration types will cause SWIG to define an integer type with
|
|
the name of the enumeration (with first letter forced to uppercase as
|
|
usual). The values of the enumeration will become variables in Go;
|
|
code should avoid modifying those variables.
|
|
</p>
|
|
|
|
<H3><a name="Go_classes">25.4.5 Go Classes</a></H3>
|
|
|
|
|
|
<p>
|
|
Go has interfaces, methods and inheritance, but it does not have
|
|
classes in the same sense as C++. This sections describes how SWIG
|
|
represents C++ classes represented in Go.
|
|
</p>
|
|
|
|
<p>
|
|
For a C++ class <tt>ClassName</tt>, SWIG will define two types in Go:
|
|
an underlying type, which will just hold a pointer to the C++ type,
|
|
and an interface type. The interface type will be
|
|
named <tt>ClassName</tt>. SWIG will define a
|
|
function <tt>NewClassName</tt> which will take any constructor
|
|
arguments and return a value of the interface
|
|
type <tt>ClassName</tt>. SWIG will also define a
|
|
destructor <tt>DeleteClassName</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
SWIG will represent any methods of the C++ class as methods on the
|
|
underlying type, and also as methods of the interface type. Thus C++
|
|
methods may be invoked directly using the
|
|
usual <tt>val.MethodName</tt> syntax. Public members of the C++ class
|
|
will be given getter and setter functions defined as methods of the
|
|
class.
|
|
</p>
|
|
|
|
<p>
|
|
SWIG will represent static methods of C++ classes as ordinary Go
|
|
functions. SWIG will use names like <tt>ClassNameMethodName</tt>.
|
|
SWIG will give static members getter and setter functions with names
|
|
like <tt>GetClassNameVarName</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
Given a value of the interface type, Go code can retrieve the pointer
|
|
to the C++ type by calling the <tt>Swigcptr</tt> method. This will
|
|
return a value of type <tt>SwigcptrClassName</tt>, which is just a
|
|
name for <tt>uintptr</tt>. A Go type conversion can be used to
|
|
convert this value to a different C++ type, but note that this
|
|
conversion will not be type checked and is essentially equivalent
|
|
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
|
|
}
|
|
|
|
func 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_memory">25.4.5.1 Go Class Memory Management</a></H4>
|
|
|
|
|
|
<p>
|
|
Calling <tt>NewClassName</tt> for a C++ class <tt>ClassName</tt> will allocate
|
|
memory using the C++ memory allocator. This memory will not be automatically
|
|
freed by Go's garbage collector as the object ownership is not tracked. When
|
|
you are done with the C++ object you must free it using
|
|
<tt>DeleteClassName</tt>.<br>
|
|
<br>
|
|
The most Go idiomatic way to manage the memory for some C++ class is to call
|
|
<tt>NewClassName</tt> followed by a
|
|
<tt><a href="https://golang.org/doc/effective_go.html#defer">defer</a></tt> of
|
|
the <tt>DeleteClassName</tt> call. Using <tt>defer</tt> ensures that the memory
|
|
of the C++ object is freed as soon as the function containing the <tt>defer</tt>
|
|
statement returns. Furthermore <tt>defer</tt> works great for short-lived
|
|
objects and fits nicely C++'s RAII idiom. Example:
|
|
</p>
|
|
<div class="code">
|
|
<pre>
|
|
func UseClassName(...) ... {
|
|
o := NewClassName(...)
|
|
defer DeleteClassName(o)
|
|
// Use the ClassName object
|
|
return ...
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
With increasing complexity, especially complex C++ object hierarchies, the
|
|
correct placement of <tt>defer</tt> statements becomes harder and harder as C++
|
|
objects need to be freed in the correct order. This problem can be eased by
|
|
keeping a C++ object function local so that it is only available to the function
|
|
that creates a C++ object and functions called by this function. Example:
|
|
</p>
|
|
<div class="code">
|
|
<pre>
|
|
func WithClassName(constructor args, f func(ClassName, ...interface{}) error, data ...interface{}) error {
|
|
o := NewClassName(constructor args)
|
|
defer DeleteClassName(o)
|
|
return f(o, data...)
|
|
}
|
|
|
|
func UseClassName(o ClassName, data ...interface{}) (err error) {
|
|
// Use the ClassName object and additional data and return error.
|
|
}
|
|
|
|
func main() {
|
|
WithClassName(constructor args, UseClassName, additional data)
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Using <tt>defer</tt> has limitations though, especially when it comes to
|
|
long-lived C++ objects whose lifetimes are hard to predict. For such C++
|
|
objects a common technique is to store the C++ object into a Go object, and to
|
|
use the Go function <tt>runtime.SetFinalizer</tt> to add a finalizer which frees
|
|
the C++ object when the Go object is freed. It is strongly recommended to read
|
|
the <a href="https://golang.org/pkg/runtime/#SetFinalizer">runtime.SetFinalizer
|
|
</a> documentation before using this technique to understand the
|
|
<tt>runtime.SetFinalizer</tt> limitations.<br>
|
|
</p>
|
|
<p>
|
|
Common pitfalls with <tt>runtime.SetFinalizer</tt> are:
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
If a hierarchy of C++ objects will be automatically freed by Go finalizers then
|
|
the Go objects that store the C++ objects need to replicate the hierarchy of the
|
|
C++ objects to prevent that C++ objects are freed prematurely while other C++
|
|
objects still rely on them.
|
|
</li>
|
|
<li>
|
|
The usage of Go finalizers is problematic with C++'s RAII idiom as it isn't
|
|
predictable when the finalizer will run and this might require a Close or Delete
|
|
method to be added the Go object that stores a C++ object to mitigate.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
<tt>runtime.SetFinalizer</tt> Example:
|
|
</p>
|
|
<div class="code">
|
|
<pre>
|
|
import (
|
|
"runtime"
|
|
"wrap" // SWIG generated wrapper code
|
|
)
|
|
|
|
type GoClassName struct {
|
|
wcn wrap.ClassName
|
|
}
|
|
|
|
func NewGoClassName() *GoClassName {
|
|
o := &GoClassName{wcn: wrap.NewClassName()}
|
|
runtime.SetFinalizer(o, deleteGoClassName)
|
|
return o
|
|
}
|
|
|
|
func deleteGoClassName(o *GoClassName) {
|
|
// Runs typically in a different OS thread!
|
|
wrap.DeleteClassName(o.wcn)
|
|
o.wcn = nil
|
|
}
|
|
|
|
func (o *GoClassName) Close() {
|
|
// If the C++ object has a Close method.
|
|
o.wcn.Close()
|
|
|
|
// If the GoClassName object is no longer in an usable state.
|
|
runtime.SetFinalizer(o, nil) // Remove finalizer.
|
|
deleteGoClassName() // Free the C++ object.
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<H4><a name="Go_class_inheritance">25.4.5.2 Go Class Inheritance</a></H4>
|
|
|
|
|
|
<p>
|
|
C++ class inheritance is automatically represented in Go due to its
|
|
use of interfaces. The interface for a child class will be a superset
|
|
of the interface of its parent class. Thus a value of the child class
|
|
type in Go may be passed to a function which expects the parent class.
|
|
Doing the reverse will require an explicit type assertion, which will
|
|
be checked dynamically.
|
|
</p>
|
|
|
|
<H3><a name="Go_templates">25.4.6 Go Templates</a></H3>
|
|
|
|
|
|
<p>
|
|
In order to use C++ templates in Go, you must tell SWIG to create
|
|
wrappers for a particular template instantiation. To do this, use
|
|
the <tt>%template</tt> directive.
|
|
|
|
<H3><a name="Go_threads">25.4.7 Go and C/C++ Threads</a></H3>
|
|
|
|
|
|
<p>
|
|
C and C++ code can use operating system threads and thread local
|
|
storage. Go code uses goroutines, which are multiplexed onto
|
|
operating system threads. This multiplexing means that Go code can
|
|
change to run on a different thread at any time. C/C++ code, on the
|
|
other hand, may assume that it runs on a single thread; this is true
|
|
in particular if the C/C++ code uses thread local storage.
|
|
</p>
|
|
|
|
<p>
|
|
In order to use Go code with C/C++ code that expects to run on a
|
|
single thread, the Go code must call
|
|
the <a href="https://pkg.go.dev/runtime#LockOSThread"><code>runtime.LockOSThread</code></a>
|
|
function to lock the goroutine onto a single thread.
|
|
</p>
|
|
|
|
<H3><a name="Go_exceptions">25.4.8 Go and C++ Exceptions</a></H3>
|
|
|
|
|
|
<p>
|
|
C++ exceptions do not interoperate with Go code. Attempts to throw
|
|
C++ exceptions through a Go caller are unreliable: in many cases the
|
|
C++ exception handler will be unable to unwind the stack, and the
|
|
program will crash. The only safe way to handle C++ exceptions is to
|
|
catch them in C++ before returning to Go.
|
|
</p>
|
|
|
|
<H3><a name="Go_director_classes">25.4.9 Go Director Classes</a></H3>
|
|
|
|
|
|
<p>
|
|
SWIG's director feature permits a Go type to act as the subclass of a C++ class.
|
|
This is complicated by the fact that C++ and Go define inheritance differently.
|
|
SWIG normally represents the C++ class inheritance automatically in Go via
|
|
interfaces but with a Go type representing a subclass of a C++ class some manual
|
|
work is necessary.
|
|
</p>
|
|
|
|
<p>
|
|
This subchapter gives a step by step guide how to properly subclass a C++ class
|
|
with a Go type. In general it is strongly recommended to follow this guide
|
|
completely to avoid common pitfalls with directors in Go.
|
|
</p>
|
|
|
|
|
|
<H4><a name="Go_director_example_cpp_code">25.4.9.1 Example C++ code</a></H4>
|
|
|
|
|
|
<p>
|
|
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>FooBarAbstract</tt> abstract C++ class:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
class FooBarAbstract
|
|
{
|
|
public:
|
|
FooBarAbstract() {};
|
|
virtual ~FooBarAbstract() {};
|
|
|
|
std::string FooBar() {
|
|
return this->Foo() + ", " + this->Bar();
|
|
};
|
|
|
|
protected:
|
|
virtual std::string Foo() {
|
|
return "Foo";
|
|
};
|
|
|
|
virtual std::string Bar() = 0;
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<tt>FooBarCpp</tt> C++ class:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
class FooBarCpp : public FooBarAbstract
|
|
{
|
|
protected:
|
|
virtual std::string Foo() {
|
|
return "C++ " + FooBarAbstract::Foo();
|
|
}
|
|
|
|
virtual std::string Bar() {
|
|
return "C++ Bar";
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Returned string by the <tt>FooBarCpp::FooBar</tt> method is:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
C++ Foo, C++ Bar
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<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>.
|
|
</p>
|
|
|
|
|
|
<H4><a name="Go_director_enable">25.4.9.2 Enable director feature</a></H4>
|
|
|
|
|
|
<p>
|
|
The director feature is disabled by default. To use directors you must make two
|
|
changes to the interface file. First, add the "directors" option to the %module
|
|
directive, like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module(directors="1") modulename
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Second, you must use the %feature("director") directive to tell SWIG which
|
|
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") FooBarAbstract;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
For a more detailed documentation of the director feature and how to enable or
|
|
disable it for specific classes and virtual methods see SWIG's Java
|
|
documentation on directors.
|
|
</p>
|
|
|
|
|
|
<H4><a name="Go_director_ctor_dtor">25.4.9.3 Constructor and destructor</a></H4>
|
|
|
|
|
|
<p>
|
|
SWIG creates an additional set of constructor and destructor functions once the
|
|
director feature has been enabled for a C++ class.
|
|
<tt>NewDirectorClassName</tt> allows overriding virtual methods on the new
|
|
object instance and <tt>DeleteDirectorClassName</tt> needs to be used to free a
|
|
director object instance created with <tt>NewDirectorClassName</tt>.
|
|
More on overriding virtual methods follows later in this guide under
|
|
<a href="#Go_director_overriding">overriding virtual methods</a>.
|
|
</p>
|
|
|
|
<p>
|
|
The default constructor and destructor functions <tt>NewClassName</tt> and
|
|
<tt>DeleteClassName</tt> can still be used as before so that existing code
|
|
doesn't break just because the director feature has been enabled for a C++
|
|
class. The behavior is undefined if the default and director constructor and
|
|
destructor functions get mixed and so great care needs to be taken that only one
|
|
of the constructor and destructor function pairs is used for any object
|
|
instance. Both constructor functions, the default and the director one, return
|
|
the same interface type. This makes it potentially hard to know which
|
|
destructor function, the default or the director one, needs to be called to
|
|
delete an object instance.
|
|
</p>
|
|
|
|
<p>
|
|
In <b>theory</b> the <tt>DirectorInterface</tt> method could be used to
|
|
determine if an object instance was created via <tt>NewDirectorClassName</tt>:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
if o.DirectorInterface() != nil {
|
|
DeleteDirectorClassName(o)
|
|
} else {
|
|
DeleteClassName(o)
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In <b>practice</b> it is strongly recommended to embed a director object
|
|
instance in a Go struct so that a director object instance will be represented
|
|
as a distinct Go type that subclasses a C++ class. For this Go type custom
|
|
constructor and destructor functions take care of the director constructor and
|
|
destructor function calls and the resulting Go class will appear to the user as
|
|
any other SWIG wrapped C++ class. More on properly subclassing a C++ class
|
|
follows later in this guide under <a href="#Go_director_subclass">subclass via
|
|
embedding</a>.
|
|
</p>
|
|
|
|
|
|
<H4><a name="Go_director_overriding">25.4.9.4 Override virtual methods</a></H4>
|
|
|
|
|
|
<p>
|
|
In order to override virtual methods on a C++ class with Go methods the
|
|
<tt>NewDirectorClassName</tt> constructor functions receives a
|
|
<tt>DirectorInterface</tt> argument. The methods in the <tt>
|
|
DirectorInterface</tt> are a subset of the public and protected virtual methods
|
|
of the C++ class.
|
|
Virtual methods that have a final specifier are unsurprisingly excluded.
|
|
If the <tt>DirectorInterface</tt> contains a method with a
|
|
matching signature to a virtual method of the C++ class then the virtual C++
|
|
method will be overwritten with the Go method. As Go doesn't support protected
|
|
methods all overridden protected virtual C++ methods will be public in Go.
|
|
</p>
|
|
|
|
<p>
|
|
As an example see part of the <tt>FooBarGo</tt> class:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
type overwrittenMethodsOnFooBarAbstract struct {
|
|
fb FooBarAbstract
|
|
}
|
|
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
|
...
|
|
}
|
|
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
|
|
...
|
|
}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om)
|
|
om.fb = fb
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<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>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>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>overwrittenMethodsOnFooBarAbstract</tt> struct so that they can be used by
|
|
the Go methods.
|
|
</p>
|
|
|
|
|
|
<H4><a name="Go_director_base_methods">25.4.9.5 Call base methods</a></H4>
|
|
|
|
|
|
<p>
|
|
Often a virtual method will be overwritten to extend the original behavior of
|
|
the method in the base class. This is also the case for the
|
|
<tt>FooBarCpp::Foo</tt> method of the example code:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
virtual std::string Foo() {
|
|
return "C++ " + FooBarAbstract::Foo();
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
To use base methods the <tt>DirectorClassNameMethodName</tt> wrapper functions
|
|
are automatically generated by SWIG for public and protected virtual methods.
|
|
The <tt>FooBarGo.Foo</tt> implementation in the example looks like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
|
return "Go " + DirectorFooBarAbstractFoo(om.fb)
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<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>.
|
|
</p>
|
|
|
|
|
|
<H4><a name="Go_director_subclass">25.4.9.6 Subclass via embedding</a></H4>
|
|
|
|
|
|
<p>
|
|
<a href="#Go_director_ctor_dtor">As previously mentioned in this guide</a> the
|
|
default and director constructor functions return the same interface type. To
|
|
properly subclass a C++ class with a Go type the director object instance
|
|
returned by the <tt>NewDirectorClassName</tt> constructor function should be
|
|
embedded into a Go struct so that it represents a distinct but compatible type
|
|
in Go's type system. This Go struct should be private and the constructor and
|
|
destructor functions should instead work with a public interface type so that
|
|
the Go class that subclasses a C++ class can be used as a compatible drop in.
|
|
</p>
|
|
|
|
<p>
|
|
The subclassing part of the <tt>FooBarGo</tt> class for an example looks like
|
|
this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
type FooBarGo interface {
|
|
FooBarAbstract
|
|
deleteFooBarAbstract()
|
|
IsFooBarGo()
|
|
}
|
|
|
|
type fooBarGo struct {
|
|
FooBarAbstract
|
|
}
|
|
|
|
func (fbgs *fooBarGo) deleteFooBarAbstract() {
|
|
DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
|
|
}
|
|
|
|
func (fbgs *fooBarGo) IsFooBarGo() {}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om)
|
|
om.fb = fb
|
|
|
|
return &fooBarGo{FooBarAbstract: fb}
|
|
}
|
|
|
|
func DeleteFooBarGo(fbg FooBarGo) {
|
|
fbg.deleteFooBarAbstract()
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<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 private <tt>fooBarGo</tt> struct embeds <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. Furthermore 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.
|
|
</p>
|
|
|
|
|
|
<H4><a name="Go_director_finalizer">25.4.9.7 Memory management with runtime.SetFinalizer</a></H4>
|
|
|
|
|
|
<p>
|
|
In general all guidelines for <a href="#Go_class_memory">C++ class memory
|
|
management</a> apply as well to director classes. One often overlooked
|
|
limitation with <tt>runtime.SetFinalizer</tt> is that a finalizer doesn't run
|
|
in case of a cycle and director classes typically have a cycle. The cycle
|
|
in the <tt>FooBarGo</tt> class is here:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
type overwrittenMethodsOnFooBarAbstract struct {
|
|
fb FooBarAbstract
|
|
}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om) // fb.v = om
|
|
om.fb = fb // Backlink causes cycle as fb.v = om!
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
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>
|
|
FooBarAbstract</tt> director instance can be automatically deleted by setting
|
|
the finalizer on <tt>fooBarGo</tt>:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
type fooBarGo struct {
|
|
FooBarAbstract
|
|
}
|
|
|
|
type overwrittenMethodsOnFooBarAbstract struct {
|
|
fb FooBarAbstract
|
|
}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
om := &overwrittenMethodsOnFooBarAbstract{}
|
|
fb := NewDirectorFooBarAbstract(om)
|
|
om.fb = fb // Backlink causes cycle as fb.v = om!
|
|
|
|
fbgs := &fooBarGo{FooBarAbstract: fb}
|
|
runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
|
|
return fbgs
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Furthermore if <tt>runtime.SetFinalizer</tt> is in use either the <tt>
|
|
DeleteClassName</tt> destructor function needs to be removed or the <tt>
|
|
fooBarGo</tt> struct needs additional data to prevent double deletion. Please
|
|
read the <a href="#Go_class_memory">C++ class memory management</a> subchapter
|
|
before using <tt>runtime.SetFinalizer</tt> to know all of its gotchas.
|
|
</p>
|
|
|
|
|
|
<H4><a name="Go_director_foobargo_class">25.4.9.8 Complete FooBarGo example class</a></H4>
|
|
|
|
|
|
<p>
|
|
The complete and annotated <tt>FooBarGo</tt> class looks like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
// 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 {
|
|
FooBarAbstract
|
|
deleteFooBarAbstract()
|
|
IsFooBarGo()
|
|
}
|
|
|
|
// Via embedding fooBarGo "inherits" all methods of FooBarAbstract.
|
|
type fooBarGo struct {
|
|
FooBarAbstract
|
|
}
|
|
|
|
func (fbgs *fooBarGo) deleteFooBarAbstract() {
|
|
DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
|
|
}
|
|
|
|
// 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 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 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 overridden methods can use them.
|
|
}
|
|
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
|
// DirectorFooBarAbstractFoo calls the base method FooBarAbstract::Foo.
|
|
return "Go " + DirectorFooBarAbstractFoo(om.fb)
|
|
}
|
|
|
|
func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
|
|
return "Go Bar"
|
|
}
|
|
|
|
func NewFooBarGo() FooBarGo {
|
|
// 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{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. Furthermore
|
|
// 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.deleteFooBarAbstract()
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Returned string by the <tt>FooBarGo.FooBar</tt> method is:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
Go Foo, Go Bar
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
For comparison the <tt>FooBarCpp</tt> class looks like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
class FooBarCpp : public FooBarAbstract
|
|
{
|
|
protected:
|
|
virtual std::string Foo() {
|
|
return "C++ " + FooBarAbstract::Foo();
|
|
}
|
|
|
|
virtual std::string Bar() {
|
|
return "C++ Bar";
|
|
}
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
For comparison the returned string by the <tt>FooBarCpp::FooBar</tt> method is:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
C++ Foo, C++ Bar
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The complete source of this example can be found under
|
|
<a href="https://github.com/swig/swig/tree/master/Examples/go/director">
|
|
SWIG/Examples/go/director/</a>.
|
|
</p>
|
|
|
|
|
|
<H3><a name="Go_primitive_type_mappings">25.4.10 Default Go primitive type mappings</a></H3>
|
|
|
|
|
|
<p>
|
|
The following table lists the default type mapping from C/C++ to Go.
|
|
This table will tell you which Go type to expect for a function which
|
|
uses a given C/C++ type.
|
|
</p>
|
|
|
|
<table BORDER summary="Go primitive type mappings">
|
|
<tr>
|
|
<td><b>C/C++ type</b></td>
|
|
<td><b>Go type</b></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>bool</td>
|
|
<td>bool</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>char</td>
|
|
<td>byte</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>signed char</td>
|
|
<td>int8</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>unsigned char</td>
|
|
<td>byte</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>short</td>
|
|
<td>int16</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>unsigned short</td>
|
|
<td>uint16</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>int</td>
|
|
<td>int</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>unsigned int</td>
|
|
<td>uint</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>long</td>
|
|
<td>int64</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>unsigned long</td>
|
|
<td>uint64</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>long long</td>
|
|
<td>int64</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>unsigned long long</td>
|
|
<td>uint64</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>float</td>
|
|
<td>float32</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>double</td>
|
|
<td>float64</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>char *<br>char []</td>
|
|
<td>string</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
<p>
|
|
Note that SWIG wraps the C <tt>char</tt> type as a character. Pointers
|
|
and arrays of this type are wrapped as strings. The <tt>signed
|
|
char</tt> type can be used if you want to treat <tt>char</tt> as a
|
|
signed number rather than a character. Also note that all const
|
|
references to primitive types are treated as if they are passed by
|
|
value.
|
|
</p>
|
|
|
|
<p>
|
|
These type mappings are defined by the "gotype" typemap. You may change
|
|
that typemap, or add new values, to control how C/C++ types are mapped
|
|
into Go types.
|
|
</p>
|
|
|
|
<H3><a name="Go_output_arguments">25.4.11 Output arguments</a></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 output 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 <typemaps.i>
|
|
double modf(double x, double *OUTPUT);
|
|
</pre>
|
|
</div>
|
|
<p>or you can use the <code>%apply</code> directive:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <typemaps.i>
|
|
%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="#Go_adding_additional_code">additional functions written in go</a> that
|
|
hide the ugly details.</p>
|
|
|
|
<p>There are no <code>char *OUTPUT</code> typemaps. However you can
|
|
apply the <code>signed char *</code> typemaps instead:</p>
|
|
<div class="code">
|
|
<pre>
|
|
%include <typemaps.i>
|
|
%apply signed char *OUTPUT {char *output};
|
|
void f(char *output);
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Go_adding_additional_code">25.4.12 Adding additional go code</a></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 <typemaps.i>
|
|
// 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>If you need to import other go packages, you can do this with
|
|
<code>%go_import</code>. For example,</p>
|
|
<div class="code">
|
|
<pre>
|
|
%go_import("fmt", _ "unusedPackage", rp "renamed/package")
|
|
|
|
%insert(go_wrapper) %{
|
|
|
|
func foo() {
|
|
fmt.Println("Some string:", rp.GetString())
|
|
}
|
|
|
|
// Importing the same package twice is permitted,
|
|
// Go code will be generated with only the first instance of the import.
|
|
%go_import("fmt")
|
|
|
|
%insert(go_wrapper) %{
|
|
|
|
func bar() {
|
|
fmt.Println("Hello world!")
|
|
}
|
|
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Go_typemaps">25.4.13 Go typemaps</a></H3>
|
|
|
|
|
|
<p>
|
|
You can use the <tt>%typemap</tt> directive to modify SWIG's default
|
|
wrapping behavior for specific C/C++ types. You need to be familiar
|
|
with the material in the general
|
|
"<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter. That chapter
|
|
explains how to define a typemap. This section describes some
|
|
specific typemaps used for Go.
|
|
</p>
|
|
|
|
<p>
|
|
In general type conversion code may be written either in C/C++ or in
|
|
Go. The choice to make normally depends on where memory should be
|
|
allocated. To allocate memory controlled by the Go garbage collector,
|
|
write Go code. To allocate memory in the C/C++ heap, write C code.
|
|
</p>
|
|
|
|
<table BORDER summary="Go Typemaps">
|
|
<tr>
|
|
<td><b>Typemap</b></td>
|
|
<td><b>Description</b></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>gotype</td>
|
|
<td>
|
|
The Go type to use for a C++ type. This type will appear in the
|
|
generated Go wrapper function. If this is not defined SWIG will use a
|
|
default as <a href="#Go_primitive_type_mappings">described above</a>.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>imtype</td>
|
|
<td>
|
|
An intermediate Go type used by the "goin", "goout", "godirectorin",
|
|
and "godirectorout" typemaps. If this typemap is not defined for a
|
|
C/C++ type, the gotype typemap will be used. This is useful when
|
|
gotype is best converted to C/C++ using Go code.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>goin</td>
|
|
<td>
|
|
Go code to convert from gotype to imtype when calling a C/C++
|
|
function. SWIG will then internally convert imtype to a C/C++ type
|
|
and pass it down. If this is not defined, or is the empty string, no
|
|
conversion is done.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>in</td>
|
|
<td>
|
|
C/C++ code to convert the internally generated C/C++ type, based on
|
|
imtype, into the C/C++ type that a function call expects. If this is
|
|
not defined the value will simply be cast to the desired type.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>out</td>
|
|
<td>
|
|
C/C++ code to convert the C/C++ type that a function call returns into
|
|
the internally generated C/C++ type, based on imtype, that will be
|
|
returned to Go. If this is not defined the value will simply be cast
|
|
to the desired type.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>goout</td>
|
|
<td>
|
|
Go code to convert a value returned from a C/C++ function from imtype
|
|
to gotype. If this is not defined, or is the empty string, no
|
|
conversion is done.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>argout</td>
|
|
<td>
|
|
C/C++ code to adjust an argument value when returning from a function.
|
|
This is called after the real C/C++ function has run. This uses the
|
|
internally generated C/C++ type, based on imtype. This is only useful
|
|
for a pointer type of some sort. If this is not defined nothing will
|
|
be done.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>goargout</td>
|
|
<td>
|
|
Go code to adjust an argument value when returning from a function.
|
|
This is called after the real C/C++ function has run. The value will
|
|
be in imtype. This is only useful for a pointer type of some sort.
|
|
If this is not defined, or is the empty string, nothing will be done.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>directorin</td>
|
|
<td>
|
|
C/C++ code to convert the C/C++ type used to call a director method
|
|
into the internally generated C/C++ type, based on imtype, that will
|
|
be passed to Go. If this is not defined the value will simply be cast
|
|
to the desired type.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>godirectorin</td>
|
|
<td>
|
|
Go code to convert a value used to call a director method from imtype
|
|
to gotype. If this is not defined, or is the empty string, no
|
|
conversion is done.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>godirectorout</td>
|
|
<td>
|
|
Go code to convert a value returned from a director method from gotype
|
|
to imtype. If this is not defined, or is the empty string, no
|
|
conversion is done.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>directorout</td>
|
|
<td>
|
|
C/C++ code to convert a value returned from a director method from the
|
|
internally generated C/C++ type, based on imtype, into the type that
|
|
the method should return If this is not defined the value will simply
|
|
be cast to the desired type.
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
</body>
|
|
</html>
|