[Go] Add an example for goin and godirectorin

Shows how to use a go directory for passing an NULL terminated argv type
array.

This also exercises the bug in the previous commit.  That's why the
call1 function isn't assigned to zero, that the only case where that bug
happens.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
This commit is contained in:
Corey Minyard 2022-03-20 15:04:27 -05:00
commit 546763ffbc
6 changed files with 190 additions and 0 deletions

View file

@ -12,3 +12,4 @@ reference
simple
template
variables
goin

18
Examples/go/goin/Makefile Normal file
View file

@ -0,0 +1,18 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
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_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean

106
Examples/go/goin/example.i Normal file
View file

@ -0,0 +1,106 @@
%module(directors="1") example
%inline %{
// Helper functions for converting string arrays
#include <stdlib.h>
void *alloc_ptr_array(unsigned int len)
{
return calloc(len, sizeof(void *));
}
void set_ptr_array(void *ain, unsigned int pos, void *val)
{
void **a = (void **) ain;
a[pos] = val;
}
void *get_ptr_array(void *ain, unsigned int pos)
{
void **a = (void **) ain;
return a[pos];
}
void free_ptr_array(void *ain)
{
void **a = (void **) ain;
unsigned int i;
if (!a)
return;
for (i = 0; a[i]; i++) {
free(a[i]);
}
free(a);
}
char *uintptr_to_string(void *in)
{
return (char *) in;
}
void *string_to_uintptr(char *in)
{
return strdup(in);
}
%}
// These typemaps convert between an array of strings in Go and a
// const char** that is NULL terminated in C++.
%typemap(gotype) (const char * const *) "[]string";
%typemap(imtype) (const char * const *) "uintptr";
%typemap(goin) (const char * const *) {
if $input == nil || len($input) == 0 {
$result = 0
} else {
$result = Alloc_ptr_array(uint(len($input) + 1))
defer func() {
Free_ptr_array($result)
}()
var i uint
for i = 0; i < uint(len($input)); i++ {
Set_ptr_array($result, i, String_to_uintptr($input[i]))
}
}
}
%typemap(in) (const char * const *) {
$1 = (char **) $input;
}
%typemap(godirectorin) (const char * const *) {
if ($input == 0) {
$result = nil
} else {
var i uint
for i = 0; ; i++ {
var v uintptr = Get_ptr_array($input, i)
if v == 0 {
break
}
}
if i == 0 {
$result = nil
} else {
$result = make([]string, i)
for i = 0; ; i++ {
var v uintptr = Get_ptr_array($input, i)
if v == 0 {
break
}
$result[i] = Uintptr_to_string(v)
}
}
}
}
%feature("director") callbacks;
%inline %{
class callbacks {
public:
virtual bool call1(int v, const char * const *strarray);
virtual ~callbacks() {}
};
bool check1(callbacks *c, int v, const char * const *strarray) {
return c->call1(v, strarray);
}
bool callbacks::call1(int v, const char * const *strarray) {
return false;
}
%}

View file

@ -0,0 +1,26 @@
<html>
<head>
<title>SWIG:Examples:go:going</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/goin/</tt>
<hr>
<H2>Example of using goin and godirectorin</H2>
<p>
This example converts between a Go []string and a "const char * const *"
in C/C++. It does this for a director and for a normal call.
<p>
<ul>
<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>

38
Examples/go/goin/runme.go Normal file
View file

@ -0,0 +1,38 @@
package main
import (
"fmt"
"swigtests/example"
)
type mycallbacks struct {
example.Callbacks
}
var tststrs = []string{ "A", "BCD", "EFGH" }
var tstint int = 5
func (v *mycallbacks) Call1(val int, strarray []string) bool {
var rv bool = true
for i, s := range strarray {
fmt.Printf("%d: %s\n", i, s)
if s != tststrs[i] {
fmt.Printf(" ***Mismatch, expected %s\n", tststrs[i])
rv = false
}
}
if val != tstint {
rv = false
}
return rv
}
func main() {
cbs := &mycallbacks{}
cbs.Callbacks = example.NewDirectorCallbacks(cbs)
worked := example.Check1(cbs, tstint, tststrs)
if !worked {
panic("Data mismatch")
}
}

View file

@ -24,6 +24,7 @@ certain C declarations are turned into constants.
<li><a href="callback/index.html">callback</a>. C++ callbacks using directors.
<li><a href="extend/index.html">extend</a>. Polymorphism using directors.
<li><a href="director/index.html">director</a>. Example how to utilize the director feature.
<li><a href="goin/index.html">director</a>. Example how to use goin and godirectorin.
</ul>
<h2>Compilation Issues</h2>