├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── callback ├── callback.cxx ├── callback.h ├── callback.swigcxx ├── doc.go ├── example_test.go └── gocallback.go ├── classes ├── classes.cxx ├── classes.h ├── classes.swigcxx ├── doc.go └── example_test.go ├── constants ├── constants.h ├── constants.swig ├── doc.go └── example_test.go ├── director ├── director.h ├── director.swigcxx ├── doc.go ├── example_test.go └── godirector.go ├── doc.go ├── enums ├── doc.go ├── enums.cxx ├── enums.h ├── enums.swigcxx └── example_test.go ├── extends ├── doc.go ├── example_test.go ├── extends.cxx ├── extends.h ├── extends.swigcxx └── goextends.go ├── funcptr ├── doc.go ├── example_test.go ├── funcptr.c ├── funcptr.h └── funcptr.swig ├── pointer ├── doc.go ├── example_test.go ├── pointer.c ├── pointer.h └── pointer.swig ├── reference ├── doc.go ├── example_test.go ├── reference.cxx ├── reference.h └── reference.swigcxx ├── simple ├── doc.go ├── example_test.go ├── simple.c ├── simple.h └── simple.swig ├── templates ├── doc.go ├── example_test.go ├── templates.h └── templates.swigcxx └── variables ├── doc.go ├── example_test.go ├── variables.c ├── variables.h └── variables.swig /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | sudo: required 4 | 5 | go: 6 | - tip 7 | 8 | addons: 9 | apt: 10 | packages: 11 | - swig 12 | 13 | install: 14 | - go get -u github.com/stretchr/testify/assert 15 | 16 | script: 17 | - go test -v ./... 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Bob Liu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # swiggo 2 | 3 | [![Build Status](https://travis-ci.org/Akagi201/swiggo.svg)](https://travis-ci.org/Akagi201/swiggo) 4 | [![Go Report Card](https://goreportcard.com/badge/github.com/Akagi201/swiggo)](https://goreportcard.com/report/github.com/Akagi201/swiggo) 5 | [![GoDoc](https://godoc.org/github.com/Akagi201/swiggo?status.svg)](https://godoc.org/github.com/Akagi201/swiggo) 6 | 7 | Call C/C++ lib with the help of swig 8 | 9 | ## Generate Go package file and C/C++ wrapper file 10 | * `mv interface.swig/interface.swigxx interface.i` 11 | * For C: `swig -go -cgo -intgosize 64 interface.i` 12 | * For C++: `swig -go -cgo -c++ -intgosize 64 interface.i` 13 | 14 | ## Usage 15 | * `go get github.com/Akagi201/swiggo` 16 | 17 | ## TODO 18 | - [ ] Auto gen Go package files for godoc and IDE to browser Go definitions. 19 | -------------------------------------------------------------------------------- /callback/callback.cxx: -------------------------------------------------------------------------------- 1 | /* File : callback.cxx */ 2 | 3 | #include "callback.h" 4 | 5 | -------------------------------------------------------------------------------- /callback/callback.h: -------------------------------------------------------------------------------- 1 | /* File : callback.h */ 2 | 3 | #include 4 | #include 5 | 6 | class Callback { 7 | public: 8 | virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } 9 | virtual void run() { std::cout << "Callback::run()" << std::endl; } 10 | }; 11 | 12 | 13 | class Caller { 14 | private: 15 | Callback *_callback; 16 | public: 17 | Caller(): _callback(0) {} 18 | ~Caller() { delCallback(); } 19 | void delCallback() { delete _callback; _callback = 0; } 20 | void setCallback(Callback *cb) { delCallback(); _callback = cb; } 21 | void call() { if (_callback) _callback->run(); } 22 | }; 23 | -------------------------------------------------------------------------------- /callback/callback.swigcxx: -------------------------------------------------------------------------------- 1 | /* File : callback.i */ 2 | %module(directors="1") callback 3 | %{ 4 | #include "callback.h" 5 | %} 6 | 7 | /* turn on director wrapping Callback */ 8 | %feature("director") Callback; 9 | 10 | %include "callback.h" 11 | 12 | -------------------------------------------------------------------------------- /callback/doc.go: -------------------------------------------------------------------------------- 1 | package callback 2 | -------------------------------------------------------------------------------- /callback/example_test.go: -------------------------------------------------------------------------------- 1 | package callback_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Akagi201/swiggo/callback" 8 | ) 9 | 10 | func TestExample(t *testing.T) { 11 | fmt.Println("Adding and calling a normal C++ callback") 12 | fmt.Println("----------------------------------------") 13 | 14 | caller := callback.NewCaller() 15 | cb := callback.NewCallback() 16 | 17 | caller.SetCallback(cb) 18 | caller.Call() 19 | caller.DelCallback() 20 | 21 | go_callback := callback.NewGoCallback() 22 | 23 | fmt.Println() 24 | fmt.Println("Adding and calling a Go callback") 25 | fmt.Println("--------------------------------") 26 | 27 | caller.SetCallback(go_callback) 28 | caller.Call() 29 | caller.DelCallback() 30 | 31 | callback.DeleteGoCallback(go_callback) 32 | 33 | fmt.Println() 34 | fmt.Println("Go exit") 35 | } 36 | -------------------------------------------------------------------------------- /callback/gocallback.go: -------------------------------------------------------------------------------- 1 | package callback 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type GoCallback interface { 8 | Callback 9 | deleteCallback() 10 | IsGoCallback() 11 | } 12 | 13 | type goCallback struct { 14 | Callback 15 | } 16 | 17 | func (p *goCallback) deleteCallback() { 18 | DeleteDirectorCallback(p.Callback) 19 | } 20 | 21 | func (p *goCallback) IsGoCallback() {} 22 | 23 | type overwrittenMethodsOnCallback struct { 24 | p Callback 25 | } 26 | 27 | func NewGoCallback() GoCallback { 28 | om := &overwrittenMethodsOnCallback{} 29 | p := NewDirectorCallback(om) 30 | om.p = p 31 | 32 | return &goCallback{Callback: p} 33 | } 34 | 35 | func DeleteGoCallback(p GoCallback) { 36 | p.deleteCallback() 37 | } 38 | 39 | func (p *goCallback) Run() { 40 | fmt.Println("GoCallback.Run") 41 | } 42 | -------------------------------------------------------------------------------- /classes/classes.cxx: -------------------------------------------------------------------------------- 1 | /* File : classes.cxx */ 2 | 3 | #include "classes.h" 4 | #define M_PI 3.14159265358979323846 5 | 6 | /* Move the shape to a new location */ 7 | void Shape::move(double dx, double dy) { 8 | x += dx; 9 | y += dy; 10 | } 11 | 12 | int Shape::nshapes = 0; 13 | 14 | double Circle::area() { 15 | return M_PI*radius*radius; 16 | } 17 | 18 | double Circle::perimeter() { 19 | return 2*M_PI*radius; 20 | } 21 | 22 | double Square::area() { 23 | return width*width; 24 | } 25 | 26 | double Square::perimeter() { 27 | return 4*width; 28 | } 29 | -------------------------------------------------------------------------------- /classes/classes.h: -------------------------------------------------------------------------------- 1 | /* File : classes.h */ 2 | 3 | class Shape { 4 | public: 5 | Shape() { 6 | nshapes++; 7 | } 8 | virtual ~Shape() { 9 | nshapes--; 10 | } 11 | double x, y; 12 | void move(double dx, double dy); 13 | virtual double area() = 0; 14 | virtual double perimeter() = 0; 15 | static int nshapes; 16 | }; 17 | 18 | class Circle : public Shape { 19 | private: 20 | double radius; 21 | public: 22 | Circle(double r) : radius(r) { } 23 | virtual double area(); 24 | virtual double perimeter(); 25 | }; 26 | 27 | class Square : public Shape { 28 | private: 29 | double width; 30 | public: 31 | Square(double w) : width(w) { } 32 | virtual double area(); 33 | virtual double perimeter(); 34 | }; 35 | -------------------------------------------------------------------------------- /classes/classes.swigcxx: -------------------------------------------------------------------------------- 1 | /* File : classes.i */ 2 | %module classes 3 | 4 | %{ 5 | #include "classes.h" 6 | %} 7 | 8 | /* Let's just grab the original header file here */ 9 | %include "classes.h" 10 | -------------------------------------------------------------------------------- /classes/doc.go: -------------------------------------------------------------------------------- 1 | package classes 2 | -------------------------------------------------------------------------------- /classes/example_test.go: -------------------------------------------------------------------------------- 1 | package classes_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Akagi201/swiggo/classes" 8 | ) 9 | 10 | func TestExample(t *testing.T) { 11 | // This example illustrates how C++ classes can be used from Go using SWIG. 12 | // ----- Object creation ----- 13 | 14 | // Creating some objects 15 | c := classes.NewCircle(10) 16 | fmt.Println(" Created circle", c) 17 | s := classes.NewSquare(10) 18 | fmt.Println(" Created square", s) 19 | 20 | // ----- Access a static member ----- 21 | 22 | fmt.Println("\nA total of", classes.GetShapeNshapes(), "shapes were created") 23 | 24 | // ----- Member data access ----- 25 | 26 | // Notice how we can do this using functions specific to 27 | // the 'Circle' class. 28 | c.SetX(20) 29 | c.SetY(30) 30 | 31 | // Now use the same functions in the base class 32 | var shape classes.Shape = s 33 | shape.SetX(-10) 34 | shape.SetY(5) 35 | 36 | fmt.Println("\nHere is their current position:") 37 | fmt.Println(" Circle = (", c.GetX(), " ", c.GetY(), ")") 38 | fmt.Println(" Square = (", s.GetX(), " ", s.GetY(), ")") 39 | 40 | // ----- Call some methods ----- 41 | 42 | fmt.Println("\nHere are some properties of the shapes:") 43 | shapes := []classes.Shape{c, s} 44 | for i := 0; i < len(shapes); i++ { 45 | fmt.Println(" ", shapes[i]) 46 | fmt.Println(" area = ", shapes[i].Area()) 47 | fmt.Println(" perimeter = ", shapes[i].Perimeter()) 48 | } 49 | 50 | // Notice how the area() and perimeter() functions really 51 | // invoke the appropriate virtual method on each object. 52 | 53 | // ----- Delete everything ----- 54 | 55 | fmt.Println("\nGuess I'll clean up now") 56 | 57 | // Note: this invokes the virtual destructor 58 | // You could leave this to the garbage collector 59 | classes.DeleteCircle(c) 60 | classes.DeleteSquare(s) 61 | 62 | fmt.Println(classes.GetShapeNshapes(), " shapes remain") 63 | fmt.Println("Goodbye") 64 | } 65 | -------------------------------------------------------------------------------- /constants/constants.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* A few preprocessor macros */ 4 | 5 | #define ICONST 42 6 | #define FCONST 2.1828 7 | #define CCONST 'x' 8 | #define CCONST2 '\n' 9 | #define SCONST "Hello World" 10 | #define SCONST2 "\"Hello World\"" 11 | 12 | /* This should work just fine */ 13 | #define EXPR ICONST + 3*(FCONST) 14 | 15 | /* This shouldn't do anything */ 16 | #define EXTERN extern 17 | 18 | /* Neither should this (BAR isn't defined) */ 19 | #define FOO (ICONST + BAR) 20 | -------------------------------------------------------------------------------- /constants/constants.swig: -------------------------------------------------------------------------------- 1 | /* File : constants.swig */ 2 | %module constants 3 | 4 | %{ 5 | #include "constants.h" 6 | %} 7 | 8 | %include "constants.h" 9 | 10 | /* The following directives also produce constants */ 11 | 12 | %constant int iconst = 37; 13 | %constant double fconst = 3.14; 14 | -------------------------------------------------------------------------------- /constants/doc.go: -------------------------------------------------------------------------------- 1 | package constants 2 | -------------------------------------------------------------------------------- /constants/example_test.go: -------------------------------------------------------------------------------- 1 | package constants_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Akagi201/swiggo/constants" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestConstants(t *testing.T) { 11 | assert.Equal(t, 42, constants.ICONST) 12 | assert.Equal(t, 2.1828, constants.FCONST) 13 | // assert.Equal(t, 'x', constants.CCONST) 14 | // assert.Equal(t, '\n', constants.CCONST2) 15 | assert.Equal(t, "Hello World", constants.SCONST) 16 | assert.Equal(t, 48.5484, constants.EXPR) 17 | assert.Equal(t, 37, constants.Iconst) 18 | assert.Equal(t, 3.14, constants.Fconst) 19 | } 20 | -------------------------------------------------------------------------------- /director/director.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class FooBarAbstract 7 | { 8 | public: 9 | FooBarAbstract() {}; 10 | virtual ~FooBarAbstract() {}; 11 | 12 | std::string FooBar() { 13 | return this->Foo() + ", " + this->Bar(); 14 | }; 15 | 16 | protected: 17 | virtual std::string Foo() { 18 | return "Foo"; 19 | }; 20 | 21 | virtual std::string Bar() = 0; 22 | }; 23 | 24 | 25 | class FooBarCpp : public FooBarAbstract 26 | { 27 | protected: 28 | virtual std::string Foo() { 29 | return "C++ " + FooBarAbstract::Foo(); 30 | } 31 | 32 | virtual std::string Bar() { 33 | return "C++ Bar"; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /director/director.swigcxx: -------------------------------------------------------------------------------- 1 | /* File : director.i */ 2 | %module(directors="1") director 3 | 4 | %include "std_string.i" 5 | 6 | %header %{ 7 | #include "director.h" 8 | %} 9 | 10 | %feature("director") FooBarAbstract; 11 | %include "director.h" 12 | -------------------------------------------------------------------------------- /director/doc.go: -------------------------------------------------------------------------------- 1 | package director 2 | -------------------------------------------------------------------------------- /director/example_test.go: -------------------------------------------------------------------------------- 1 | package director_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "os" 8 | 9 | "github.com/Akagi201/swiggo/director" 10 | ) 11 | 12 | func Compare(name string, got string, exp string) error { 13 | fmt.Printf("%s; Got: '%s'; Expected: '%s'\n", name, got, exp) 14 | if got != exp { 15 | return fmt.Errorf("%s returned unexpected string! Got: '%s'; Expected: '%s'\n", name, got, exp) 16 | } 17 | return nil 18 | } 19 | 20 | func testFooBarCpp() error { 21 | fb := director.NewFooBarCpp() 22 | defer director.DeleteFooBarCpp(fb) 23 | return Compare("FooBarCpp.FooBar()", fb.FooBar(), "C++ Foo, C++ Bar") 24 | } 25 | 26 | func testFooBarGo() error { 27 | fb := director.NewFooBarGo() 28 | defer director.DeleteFooBarGo(fb) 29 | return Compare("FooBarGo.FooBar()", fb.FooBar(), "Go Foo, Go Bar") 30 | } 31 | 32 | func TestExample(t *testing.T) { 33 | fmt.Println("Test output:") 34 | fmt.Println("------------") 35 | err := testFooBarCpp() 36 | err = testFooBarGo() 37 | fmt.Println("------------") 38 | if err != nil { 39 | fmt.Fprintf(os.Stderr, "Tests failed! Last error: %s\n", err.Error()) 40 | os.Exit(1) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /director/godirector.go: -------------------------------------------------------------------------------- 1 | package director 2 | 3 | // FooBarGo is a superset of FooBarAbstract and hence FooBarGo can be used as a 4 | // drop in replacement for FooBarAbstract but the reverse causes a compile time 5 | // error. 6 | type FooBarGo interface { 7 | FooBarAbstract 8 | deleteFooBarAbstract() 9 | IsFooBarGo() 10 | } 11 | 12 | // Via embedding fooBarGo "inherits" all methods of FooBarAbstract. 13 | type fooBarGo struct { 14 | FooBarAbstract 15 | } 16 | 17 | func (fbgs *fooBarGo) deleteFooBarAbstract() { 18 | DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract) 19 | } 20 | 21 | // The IsFooBarGo method ensures that FooBarGo is a superset of FooBarAbstract. 22 | // This is also how the class hierarchy gets represented by the SWIG generated 23 | // wrapper code. For an instance FooBarCpp has the IsFooBarAbstract and 24 | // IsFooBarCpp methods. 25 | func (fbgs *fooBarGo) IsFooBarGo() {} 26 | 27 | // Go type that defines the DirectorInterface. It contains the Foo and Bar 28 | // methods that overwrite the respective virtual C++ methods on FooBarAbstract. 29 | type overwrittenMethodsOnFooBarAbstract struct { 30 | // Backlink to FooBarAbstract so that the rest of the class can be used by 31 | // the overridden methods. 32 | fb FooBarAbstract 33 | 34 | // If additional constructor arguments have been given they are typically 35 | // stored here so that the overriden methods can use them. 36 | } 37 | 38 | func (om *overwrittenMethodsOnFooBarAbstract) Foo() string { 39 | // DirectorFooBarAbstractFoo calls the base method FooBarAbstract::Foo. 40 | return "Go " + DirectorFooBarAbstractFoo(om.fb) 41 | } 42 | 43 | func (om *overwrittenMethodsOnFooBarAbstract) Bar() string { 44 | return "Go Bar" 45 | } 46 | 47 | func NewFooBarGo() FooBarGo { 48 | // Instantiate FooBarAbstract with selected methods overridden. The methods 49 | // that will be overwritten are defined on 50 | // overwrittenMethodsOnFooBarAbstract and have a compatible signature to the 51 | // respective virtual C++ methods. Furthermore additional constructor 52 | // arguments will be typically stored in the 53 | // overwrittenMethodsOnFooBarAbstract struct. 54 | om := &overwrittenMethodsOnFooBarAbstract{} 55 | fb := NewDirectorFooBarAbstract(om) 56 | om.fb = fb // Backlink causes cycle as fb.v = om! 57 | 58 | fbgs := &fooBarGo{FooBarAbstract: fb} 59 | // The memory of the FooBarAbstract director object instance can be 60 | // automatically freed once the FooBarGo instance is garbage collected by 61 | // uncommenting the following line. Please make sure to understand the 62 | // runtime.SetFinalizer specific gotchas before doing this. Furthemore 63 | // DeleteFooBarGo should be deleted if a finalizer is in use or the fooBarGo 64 | // struct needs additional data to prevent double deletion. 65 | // runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract) 66 | return fbgs 67 | } 68 | 69 | // Recommended to be removed if runtime.SetFinalizer is in use. 70 | func DeleteFooBarGo(fbg FooBarGo) { 71 | fbg.deleteFooBarAbstract() 72 | } 73 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // Package swiggo shows how to call C/C++ lib with the help of swig 2 | package swiggo 3 | -------------------------------------------------------------------------------- /enums/doc.go: -------------------------------------------------------------------------------- 1 | package enums 2 | -------------------------------------------------------------------------------- /enums/enums.cxx: -------------------------------------------------------------------------------- 1 | /* File : enums.cxx */ 2 | 3 | #include "enums.h" 4 | #include 5 | 6 | void Foo::enum_test(speed s) { 7 | if (s == IMPULSE) { 8 | printf("IMPULSE speed\n"); 9 | } else if (s == WARP) { 10 | printf("WARP speed\n"); 11 | } else if (s == LUDICROUS) { 12 | printf("LUDICROUS speed\n"); 13 | } else { 14 | printf("Unknown speed\n"); 15 | } 16 | } 17 | 18 | void enum_test(color c, Foo::speed s) { 19 | if (c == RED) { 20 | printf("color = RED, "); 21 | } else if (c == BLUE) { 22 | printf("color = BLUE, "); 23 | } else if (c == GREEN) { 24 | printf("color = GREEN, "); 25 | } else { 26 | printf("color = Unknown color!, "); 27 | } 28 | if (s == Foo::IMPULSE) { 29 | printf("speed = IMPULSE speed\n"); 30 | } else if (s == Foo::WARP) { 31 | printf("speed = WARP speed\n"); 32 | } else if (s == Foo::LUDICROUS) { 33 | printf("speed = LUDICROUS speed\n"); 34 | } else { 35 | printf("speed = Unknown speed!\n"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /enums/enums.h: -------------------------------------------------------------------------------- 1 | /* File : enums.h */ 2 | 3 | enum color { RED, BLUE, GREEN }; 4 | 5 | class Foo { 6 | public: 7 | Foo() { } 8 | enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 }; 9 | void enum_test(speed s); 10 | }; 11 | 12 | void enum_test(color c, Foo::speed s); 13 | -------------------------------------------------------------------------------- /enums/enums.swigcxx: -------------------------------------------------------------------------------- 1 | /* File : enums.i */ 2 | %module enums 3 | 4 | %{ 5 | #include "enums.h" 6 | %} 7 | 8 | /* Let's just grab the original header file here */ 9 | 10 | %include "enums.h" 11 | -------------------------------------------------------------------------------- /enums/example_test.go: -------------------------------------------------------------------------------- 1 | package enums_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Akagi201/swiggo/enums" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestExample(t *testing.T) { 11 | // Print out the value of some enums 12 | // *** color *** 13 | color := enums.RED 14 | assert.Equal(t, enums.Color(0), color) 15 | color = enums.BLUE 16 | assert.Equal(t, enums.Color(1), color) 17 | color = enums.GREEN 18 | assert.Equal(t, enums.Color(2), color) 19 | 20 | // *** Foo::speed *** 21 | speed := enums.FooIMPULSE 22 | assert.Equal(t, enums.FooSpeed(10), speed) 23 | speed = enums.FooWARP 24 | assert.Equal(t, enums.FooSpeed(20), speed) 25 | speed = enums.FooLUDICROUS 26 | assert.Equal(t, enums.FooSpeed(30), speed) 27 | 28 | // Testing use of enums with functions 29 | enums.Enum_test(enums.RED, enums.FooIMPULSE) 30 | enums.Enum_test(enums.BLUE, enums.FooWARP) 31 | enums.Enum_test(enums.GREEN, enums.FooLUDICROUS) 32 | 33 | // Testing use of enum with class method 34 | f := enums.NewFoo() 35 | 36 | f.Enum_test(enums.FooIMPULSE) 37 | f.Enum_test(enums.FooWARP) 38 | f.Enum_test(enums.FooLUDICROUS) 39 | } 40 | -------------------------------------------------------------------------------- /extends/doc.go: -------------------------------------------------------------------------------- 1 | package extends 2 | -------------------------------------------------------------------------------- /extends/example_test.go: -------------------------------------------------------------------------------- 1 | package extends_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Akagi201/swiggo/extends" 8 | ) 9 | 10 | func TestExample(t *testing.T) { 11 | // Create an instance of CEO, a class derived from the Go 12 | // proxy of the underlying C++ class. The calls to getName() 13 | // and getPosition() are standard, the call to getTitle() uses 14 | // the director wrappers to call CEO.getPosition(). 15 | e := extends.NewCEO("Alice") 16 | fmt.Println(e.GetName(), " is a ", e.GetPosition()) 17 | fmt.Println("Just call her \"", e.GetTitle(), "\"") 18 | fmt.Println("----------------------") 19 | 20 | // Create a new EmployeeList instance. This class does not 21 | // have a C++ director wrapper, but can be used freely with 22 | // other classes that do. 23 | list := extends.NewEmployeeList() 24 | 25 | // EmployeeList owns its items, so we must surrender ownership 26 | // of objects we add. 27 | // e.DisownMemory() 28 | list.AddEmployee(e) 29 | fmt.Println("----------------------") 30 | 31 | // Now we access the first four items in list (three are C++ 32 | // objects that EmployeeList's constructor adds, the last is 33 | // our CEO). The virtual methods of all these instances are 34 | // treated the same. For items 0, 1, and 2, all methods 35 | // resolve in C++. For item 3, our CEO, GetTitle calls 36 | // GetPosition which resolves in Go. The call to GetPosition 37 | // is slightly different, however, because of the overridden 38 | // GetPosition() call, since now the object reference has been 39 | // "laundered" by passing through EmployeeList as an 40 | // Employee*. Previously, Go resolved the call immediately in 41 | // CEO, but now Go thinks the object is an instance of class 42 | // Employee. So the call passes through the Employee proxy 43 | // class and on to the C wrappers and C++ director, eventually 44 | // ending up back at the Go CEO implementation of 45 | // getPosition(). The call to GetTitle() for item 3 runs the 46 | // C++ Employee::getTitle() method, which in turn calls 47 | // GetPosition(). This virtual method call passes down 48 | // through the C++ director class to the Go implementation 49 | // in CEO. All this routing takes place transparently. 50 | fmt.Println("(position, title) for items 0-3:") 51 | fmt.Println(" ", list.Get_item(0).GetPosition(), ", \"", list.Get_item(0).GetTitle(), "\"") 52 | fmt.Println(" ", list.Get_item(1).GetPosition(), ", \"", list.Get_item(1).GetTitle(), "\"") 53 | fmt.Println(" ", list.Get_item(2).GetPosition(), ", \"", list.Get_item(2).GetTitle(), "\"") 54 | fmt.Println(" ", list.Get_item(3).GetPosition(), ", \"", list.Get_item(3).GetTitle(), "\"") 55 | fmt.Println("----------------------") 56 | 57 | // Time to delete the EmployeeList, which will delete all the 58 | // Employee* items it contains. The last item is our CEO, 59 | // which gets destroyed as well and hence there is no need to 60 | // call DeleteCEO. 61 | extends.DeleteEmployeeList(list) 62 | fmt.Println("----------------------") 63 | 64 | // All done. 65 | fmt.Println("Go exit") 66 | } 67 | -------------------------------------------------------------------------------- /extends/extends.cxx: -------------------------------------------------------------------------------- 1 | /* File : extends.cxx */ 2 | 3 | #include "extends.h" 4 | -------------------------------------------------------------------------------- /extends/extends.h: -------------------------------------------------------------------------------- 1 | /* File : extends.h */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Employee { 10 | private: 11 | std::string name; 12 | public: 13 | Employee(const char* n): name(n) {} 14 | virtual std::string getTitle() { return getPosition() + " " + getName(); } 15 | virtual std::string getName() { return name; } 16 | virtual std::string getPosition() const { return "Employee"; } 17 | virtual ~Employee() { printf("~Employee() @ %p\n", (void *)this); } 18 | }; 19 | 20 | 21 | class Manager: public Employee { 22 | public: 23 | Manager(const char* n): Employee(n) {} 24 | virtual std::string getPosition() const { return "Manager"; } 25 | }; 26 | 27 | 28 | class EmployeeList { 29 | std::vector list; 30 | public: 31 | EmployeeList() { 32 | list.push_back(new Employee("Bob")); 33 | list.push_back(new Employee("Jane")); 34 | list.push_back(new Manager("Ted")); 35 | } 36 | void addEmployee(Employee *p) { 37 | list.push_back(p); 38 | std::cout << "New employee added. Current employees are:" << std::endl; 39 | std::vector::iterator i; 40 | for (i=list.begin(); i!=list.end(); i++) { 41 | std::cout << " " << (*i)->getTitle() << std::endl; 42 | } 43 | } 44 | const Employee *get_item(int i) { 45 | return list[i]; 46 | } 47 | ~EmployeeList() { 48 | std::vector::iterator i; 49 | std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl; 50 | for (i=list.begin(); i!=list.end(); i++) { 51 | delete *i; 52 | } 53 | std::cout << "~EmployeeList empty." << std::endl; 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /extends/extends.swigcxx: -------------------------------------------------------------------------------- 1 | /* File : extends.i */ 2 | %module(directors="1") extends 3 | %{ 4 | #include "extends.h" 5 | %} 6 | 7 | %include "std_vector.i" 8 | %include "std_string.i" 9 | 10 | /* turn on director wrapping for Manager */ 11 | %feature("director") Employee; 12 | %feature("director") Manager; 13 | 14 | %include "extends.h" 15 | -------------------------------------------------------------------------------- /extends/goextends.go: -------------------------------------------------------------------------------- 1 | package extends 2 | 3 | type CEO interface { 4 | Manager 5 | deleteManager() 6 | IsCEO() 7 | } 8 | 9 | type ceo struct { 10 | Manager 11 | } 12 | 13 | func (p *ceo) deleteManager() { 14 | DeleteDirectorManager(p.Manager) 15 | } 16 | 17 | func (p *ceo) IsCEO() {} 18 | 19 | type overwrittenMethodsOnManager struct { 20 | p Manager 21 | } 22 | 23 | func NewCEO(name string) CEO { 24 | om := &overwrittenMethodsOnManager{} 25 | p := NewDirectorManager(om, name) 26 | om.p = p 27 | 28 | return &ceo{Manager: p} 29 | } 30 | 31 | func DeleteCEO(p CEO) { 32 | p.deleteManager() 33 | } 34 | 35 | func (p *ceo) GetPosition() string { 36 | return "CEO" 37 | } 38 | -------------------------------------------------------------------------------- /funcptr/doc.go: -------------------------------------------------------------------------------- 1 | package funcptr 2 | -------------------------------------------------------------------------------- /funcptr/example_test.go: -------------------------------------------------------------------------------- 1 | package funcptr_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Akagi201/swiggo/funcptr" 8 | ) 9 | 10 | func TestExample(t *testing.T) { 11 | a := 37 12 | b := 42 13 | 14 | // Now call our C function with a bunch of callbacks 15 | 16 | fmt.Println("Trying some C callback functions") 17 | fmt.Println(" a = ", a) 18 | fmt.Println(" b = ", b) 19 | fmt.Println(" ADD(a,b) = ", funcptr.Do_op(a, b, funcptr.ADD)) 20 | fmt.Println(" SUB(a,b) = ", funcptr.Do_op(a, b, funcptr.SUB)) 21 | fmt.Println(" MUL(a,b) = ", funcptr.Do_op(a, b, funcptr.MUL)) 22 | 23 | fmt.Println("Here is what the C callback function classes are called in Go") 24 | fmt.Println(" ADD = ", funcptr.ADD) 25 | fmt.Println(" SUB = ", funcptr.SUB) 26 | fmt.Println(" MUL = ", funcptr.MUL) 27 | } 28 | -------------------------------------------------------------------------------- /funcptr/funcptr.c: -------------------------------------------------------------------------------- 1 | /* File : funcptr.c */ 2 | 3 | int do_op(int a, int b, int (*op)(int,int)) { 4 | return (*op)(a,b); 5 | } 6 | 7 | int add(int a, int b) { 8 | return a+b; 9 | } 10 | 11 | int sub(int a, int b) { 12 | return a-b; 13 | } 14 | 15 | int mul(int a, int b) { 16 | return a*b; 17 | } 18 | 19 | int (*funcvar)(int,int) = add; 20 | -------------------------------------------------------------------------------- /funcptr/funcptr.h: -------------------------------------------------------------------------------- 1 | /* file: funcptr.h */ 2 | 3 | extern int do_op(int,int, int (*op)(int,int)); 4 | extern int add(int,int); 5 | extern int sub(int,int); 6 | extern int mul(int,int); 7 | 8 | extern int (*funcvar)(int,int); 9 | 10 | -------------------------------------------------------------------------------- /funcptr/funcptr.swig: -------------------------------------------------------------------------------- 1 | /* File : funcptr.i */ 2 | %module funcptr 3 | %{ 4 | #include "funcptr.h" 5 | %} 6 | 7 | /* Wrap a function taking a pointer to a function */ 8 | extern int do_op(int a, int b, int (*op)(int, int)); 9 | 10 | /* Now install a bunch of "ops" as constants */ 11 | %constant int (*ADD)(int,int) = add; 12 | %constant int (*SUB)(int,int) = sub; 13 | %constant int (*MUL)(int,int) = mul; 14 | 15 | extern int (*funcvar)(int,int); 16 | 17 | -------------------------------------------------------------------------------- /pointer/doc.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | -------------------------------------------------------------------------------- /pointer/example_test.go: -------------------------------------------------------------------------------- 1 | package pointer_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "fmt" 7 | 8 | "github.com/Akagi201/swiggo/pointer" 9 | ) 10 | 11 | func TestExample(t *testing.T) { 12 | // First create some objects using the pointer library. 13 | fmt.Println("Testing the pointer library") 14 | a := pointer.New_intp() 15 | b := pointer.New_intp() 16 | c := pointer.New_intp() 17 | pointer.Intp_assign(a, 37) 18 | pointer.Intp_assign(b, 42) 19 | 20 | fmt.Println(" a =", a) 21 | fmt.Println(" b =", b) 22 | fmt.Println(" c =", c) 23 | 24 | // Call the add() function with some pointers 25 | pointer.Add(a, b, c) 26 | 27 | // Now get the result 28 | res := pointer.Intp_value(c) 29 | fmt.Println(" 37 + 42 =", res) 30 | 31 | // Clean up the pointers 32 | pointer.Delete_intp(a) 33 | pointer.Delete_intp(b) 34 | pointer.Delete_intp(c) 35 | 36 | // Now try the typemap library 37 | // Now it is no longer necessary to manufacture pointers. 38 | // Instead we use a single element slice which in Go is modifiable. 39 | 40 | fmt.Println("Trying the typemap library") 41 | r := []int{0} 42 | pointer.Sub(37, 42, r) 43 | fmt.Println(" 37 - 42 = ", r[0]) 44 | 45 | // Now try the version with return value 46 | 47 | fmt.Println("Testing return value") 48 | q := pointer.Divide(42, 37, r) 49 | fmt.Println(" 42/37 = ", q, " remainder ", r[0]) 50 | } 51 | -------------------------------------------------------------------------------- /pointer/pointer.c: -------------------------------------------------------------------------------- 1 | /* File : pointer.c */ 2 | 3 | #include "pointer.h" 4 | 5 | void add(int *x, int *y, int *result) { 6 | *result = *x + *y; 7 | } 8 | 9 | void sub(int *x, int *y, int *result) { 10 | *result = *x - *y; 11 | } 12 | 13 | int divide(int n, int d, int *r) { 14 | int q; 15 | q = n/d; 16 | *r = n - q*d; 17 | return q; 18 | } 19 | -------------------------------------------------------------------------------- /pointer/pointer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern void add(int *, int *, int *); 4 | extern void sub(int *, int *, int *); 5 | extern int divide(int, int, int *); 6 | -------------------------------------------------------------------------------- /pointer/pointer.swig: -------------------------------------------------------------------------------- 1 | /* File : pointer.i */ 2 | %module pointer 3 | 4 | %{ 5 | #include "pointer.h" 6 | %} 7 | 8 | /* This example illustrates a couple of different techniques 9 | for manipulating C pointers */ 10 | 11 | /* First we'll use the pointer library */ 12 | extern void add(int *x, int *y, int *result); 13 | %include cpointer.i 14 | %pointer_functions(int, intp); 15 | 16 | /* Next we'll use some typemaps */ 17 | 18 | %include typemaps.i 19 | extern void sub(int *INPUT, int *INPUT, int *OUTPUT); 20 | 21 | /* Next we'll use typemaps and the %apply directive */ 22 | 23 | %apply int *OUTPUT { int *r }; 24 | extern int divide(int n, int d, int *r); 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /reference/doc.go: -------------------------------------------------------------------------------- 1 | package reference 2 | -------------------------------------------------------------------------------- /reference/example_test.go: -------------------------------------------------------------------------------- 1 | package reference_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Akagi201/swiggo/reference" 8 | ) 9 | 10 | func TestExample(t *testing.T) { 11 | fmt.Println("Creating some objects:") 12 | a := reference.NewVector(3, 4, 5) 13 | b := reference.NewVector(10, 11, 12) 14 | 15 | fmt.Println(" Created ", a.Print()) 16 | fmt.Println(" Created ", b.Print()) 17 | 18 | // ----- Call an overloaded operator ----- 19 | 20 | // This calls the wrapper we placed around 21 | // 22 | // operator+(const Vector &a, const Vector &) 23 | // 24 | // It returns a new allocated object. 25 | 26 | fmt.Println("Adding a+b") 27 | c := reference.Addv(a, b) 28 | fmt.Println(" a+b = " + c.Print()) 29 | 30 | // Because addv returns a reference, Addv will return a 31 | // pointer allocated using Go's memory allocator. That means 32 | // that it will be freed by Go's garbage collector, and we can 33 | // not use DeleteVector to release it. 34 | 35 | c = nil 36 | 37 | // ----- Create a vector array ----- 38 | 39 | fmt.Println("Creating an array of vectors") 40 | va := reference.NewVectorArray(10) 41 | fmt.Println(" va = ", va) 42 | 43 | // ----- Set some values in the array ----- 44 | 45 | // These operators copy the value of Vector a and Vector b to 46 | // the vector array 47 | va.Set(0, a) 48 | va.Set(1, b) 49 | 50 | va.Set(2, reference.Addv(a, b)) 51 | 52 | // Get some values from the array 53 | 54 | fmt.Println("Getting some array values") 55 | for i := 0; i < 5; i++ { 56 | fmt.Println(" va(", i, ") = ", va.Get(i).Print()) 57 | } 58 | 59 | // Watch under resource meter to check on this 60 | fmt.Println("Making sure we don't leak memory.") 61 | for i := 0; i < 1000000; i++ { 62 | c = va.Get(i % 10) 63 | } 64 | 65 | // ----- Clean up ----- This could be omitted. The garbage 66 | // collector would then clean up for us. 67 | fmt.Println("Cleaning up") 68 | reference.DeleteVectorArray(va) 69 | reference.DeleteVector(a) 70 | reference.DeleteVector(b) 71 | } 72 | -------------------------------------------------------------------------------- /reference/reference.cxx: -------------------------------------------------------------------------------- 1 | /* File : reference.cxx */ 2 | 3 | /* Deal with Microsoft's attempt at deprecating C standard runtime functions */ 4 | #if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) 5 | # define _CRT_SECURE_NO_DEPRECATE 6 | #endif 7 | 8 | #include "reference.h" 9 | #include 10 | #include 11 | 12 | Vector operator+(const Vector &a, const Vector &b) { 13 | Vector r; 14 | r.x = a.x + b.x; 15 | r.y = a.y + b.y; 16 | r.z = a.z + b.z; 17 | return r; 18 | } 19 | 20 | char *Vector::print() { 21 | static char temp[512]; 22 | sprintf(temp,"Vector %p (%g,%g,%g)", (void *)this, x,y,z); 23 | return temp; 24 | } 25 | 26 | VectorArray::VectorArray(int size) { 27 | items = new Vector[size]; 28 | maxsize = size; 29 | } 30 | 31 | VectorArray::~VectorArray() { 32 | delete [] items; 33 | } 34 | 35 | Vector &VectorArray::operator[](int index) { 36 | if ((index < 0) || (index >= maxsize)) { 37 | printf("Panic! Array index out of bounds.\n"); 38 | exit(1); 39 | } 40 | return items[index]; 41 | } 42 | 43 | int VectorArray::size() { 44 | return maxsize; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /reference/reference.h: -------------------------------------------------------------------------------- 1 | /* File : reference.h */ 2 | 3 | class Vector { 4 | private: 5 | double x,y,z; 6 | public: 7 | Vector() : x(0), y(0), z(0) { } 8 | Vector(double x, double y, double z) : x(x), y(y), z(z) { } 9 | friend Vector operator+(const Vector &a, const Vector &b); 10 | char *print(); 11 | }; 12 | 13 | class VectorArray { 14 | private: 15 | Vector *items; 16 | int maxsize; 17 | public: 18 | VectorArray(int maxsize); 19 | ~VectorArray(); 20 | Vector &operator[](int); 21 | int size(); 22 | }; 23 | -------------------------------------------------------------------------------- /reference/reference.swigcxx: -------------------------------------------------------------------------------- 1 | /* File : reference.i */ 2 | 3 | /* This file has a few "typical" uses of C++ references. */ 4 | 5 | %module reference 6 | 7 | %{ 8 | #include "reference.h" 9 | %} 10 | 11 | class Vector { 12 | public: 13 | Vector(double x, double y, double z); 14 | ~Vector(); 15 | char *print(); 16 | }; 17 | 18 | /* This helper function calls an overloaded operator */ 19 | %inline %{ 20 | Vector addv(Vector &a, Vector &b) { 21 | return a+b; 22 | } 23 | %} 24 | 25 | /* Wrapper around an array of vectors class */ 26 | 27 | class VectorArray { 28 | public: 29 | VectorArray(int maxsize); 30 | ~VectorArray(); 31 | int size(); 32 | 33 | /* This wrapper provides an alternative to the [] operator */ 34 | %extend { 35 | Vector &get(int index) { 36 | return (*$self)[index]; 37 | } 38 | void set(int index, Vector &a) { 39 | (*$self)[index] = a; 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /simple/doc.go: -------------------------------------------------------------------------------- 1 | // Package simple go call c with swig 2 | package simple 3 | -------------------------------------------------------------------------------- /simple/example_test.go: -------------------------------------------------------------------------------- 1 | package simple_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/Akagi201/swiggo/simple" 7 | ) 8 | 9 | func Example() { 10 | // Call our gcd() function 11 | x := 42 12 | y := 105 13 | g := simple.Gcd(x, y) 14 | fmt.Println("The gcd of", x, "and", y, "is", g) 15 | 16 | // Manipulate the Foo global variable 17 | 18 | // Print its current value 19 | fmt.Println("Foo =", simple.GetFoo()) 20 | 21 | // Change its value 22 | simple.SetFoo(3.1415926) 23 | 24 | // See if the change took effect 25 | fmt.Println("Foo =", simple.GetFoo()) 26 | 27 | // Output: 28 | // The gcd of 42 and 105 is 21 29 | // Foo = 3 30 | // Foo = 3.1415926 31 | } 32 | -------------------------------------------------------------------------------- /simple/simple.c: -------------------------------------------------------------------------------- 1 | /* File : simple.c */ 2 | #include "simple.h" 3 | 4 | /* A global variable */ 5 | double Foo = 3.0; 6 | 7 | /* Compute the greatest common divisor of positive integers */ 8 | int gcd(int x, int y) { 9 | int g; 10 | g = y; 11 | while (x > 0) { 12 | g = x; 13 | x = y % x; 14 | y = g; 15 | } 16 | return g; 17 | } 18 | -------------------------------------------------------------------------------- /simple/simple.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern double Foo; 4 | extern int gcd(int x, int y); 5 | -------------------------------------------------------------------------------- /simple/simple.swig: -------------------------------------------------------------------------------- 1 | /* File : simple.swig */ 2 | %module simple 3 | %{ 4 | #include "simple.h" 5 | %} 6 | 7 | %include "simple.h" 8 | 9 | -------------------------------------------------------------------------------- /templates/doc.go: -------------------------------------------------------------------------------- 1 | package templates 2 | -------------------------------------------------------------------------------- /templates/example_test.go: -------------------------------------------------------------------------------- 1 | package templates_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Akagi201/swiggo/templates" 8 | ) 9 | 10 | func TestExample(t *testing.T) { 11 | // Call some templated functions 12 | fmt.Println(templates.Maxint(3, 7)) 13 | fmt.Println(templates.Maxdouble(3.14, 2.18)) 14 | 15 | // Create some class 16 | iv := templates.NewVecint(100) 17 | dv := templates.NewVecdouble(1000) 18 | 19 | for i := 0; i < 100; i++ { 20 | iv.Setitem(i, 2*i) 21 | } 22 | 23 | for i := 0; i < 1000; i++ { 24 | dv.Setitem(i, 1.0/float64(i+1)) 25 | } 26 | 27 | { 28 | sum := 0 29 | for i := 0; i < 100; i++ { 30 | sum = sum + iv.Getitem(i) 31 | } 32 | fmt.Println(sum) 33 | } 34 | 35 | { 36 | sum := float64(0.0) 37 | for i := 0; i < 1000; i++ { 38 | sum = sum + dv.Getitem(i) 39 | } 40 | fmt.Println(sum) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /templates/templates.h: -------------------------------------------------------------------------------- 1 | /* File : templates.h */ 2 | 3 | // Some template definitions 4 | 5 | template T max(T a, T b) { return a>b ? a : b; } 6 | 7 | template class vector { 8 | T *v; 9 | int sz; 10 | public: 11 | vector(int _sz) { 12 | v = new T[_sz]; 13 | sz = _sz; 14 | } 15 | T &get(int index) { 16 | return v[index]; 17 | } 18 | void set(int index, T &val) { 19 | v[index] = val; 20 | } 21 | #ifdef SWIG 22 | %extend { 23 | T getitem(int index) { 24 | return $self->get(index); 25 | } 26 | void setitem(int index, T val) { 27 | $self->set(index,val); 28 | } 29 | } 30 | #endif 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /templates/templates.swigcxx: -------------------------------------------------------------------------------- 1 | /* File : templates.i */ 2 | %module templates 3 | 4 | %{ 5 | #include "templates.h" 6 | %} 7 | 8 | /* Let's just grab the original header file here */ 9 | %include "templates.h" 10 | 11 | /* Now instantiate some specific template declarations */ 12 | 13 | %template(maxint) max; 14 | %template(maxdouble) max; 15 | %template(vecint) vector; 16 | %template(vecdouble) vector; 17 | 18 | -------------------------------------------------------------------------------- /variables/doc.go: -------------------------------------------------------------------------------- 1 | package variables 2 | -------------------------------------------------------------------------------- /variables/example_test.go: -------------------------------------------------------------------------------- 1 | package variables_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Akagi201/swiggo/variables" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestExample(t *testing.T) { 12 | // Try to set the values of some global variables 13 | 14 | variables.SetIvar(42) 15 | variables.SetSvar(-31000) 16 | variables.SetLvar(65537) 17 | variables.SetUivar(123456) 18 | variables.SetUsvar(61000) 19 | variables.SetUlvar(654321) 20 | variables.SetScvar(-13) 21 | variables.SetUcvar(251) 22 | variables.SetCvar('S') 23 | variables.SetFvar(3.14159) 24 | variables.SetDvar(2.1828) 25 | variables.SetStrvar("Hello World") 26 | variables.SetIptrvar(variables.New_int(37)) 27 | variables.SetPtptr(variables.New_Point(37, 42)) 28 | variables.SetName("Bill") 29 | 30 | // Now print out the values of the variables 31 | // Variables (values printed from Go) 32 | 33 | assert.Equal(t, 42, variables.GetIvar()) 34 | assert.Equal(t, int16(-31000), variables.GetSvar()) 35 | assert.Equal(t, int64(65537), variables.GetLvar()) 36 | assert.Equal(t, uint(123456), variables.GetUivar()) 37 | assert.Equal(t, uint16(61000), variables.GetUsvar()) 38 | assert.Equal(t, uint64(654321), variables.GetUlvar()) 39 | assert.Equal(t, int8(-13), variables.GetScvar()) 40 | assert.Equal(t, uint8(251), variables.GetUcvar()) 41 | assert.Equal(t, string("S"), fmt.Sprintf("%c", variables.GetCvar())) 42 | assert.Equal(t, float32(3.14159), variables.GetFvar()) 43 | //assert.Equal(t, 2.1828, variables.GetDvar()) 44 | 45 | assert.Equal(t, "Hello World", variables.GetStrvar()) 46 | assert.Equal(t, variables.New_int(37), variables.GetIptrvar()) 47 | assert.Equal(t, "Bill", variables.GetName()) 48 | assert.Equal(t, "Goodbye", variables.GetCstrvar()) 49 | //assert.Equal(t, variables.Point_print(variables.GetPtptr()), variables.GetPtptr()) 50 | //assert.Equal(t, variables.Point_print(variables.GetPt()), variables.GetPt()) 51 | 52 | // Variables (values printed from C) 53 | 54 | variables.Print_vars() 55 | 56 | // This line would not compile: since status is marked with 57 | // %immutable, there is no SetStatus function. 58 | // fmt.Println("\nNow I'm going to try and modify some read only variables") 59 | // variables.SetStatus(0) 60 | 61 | // I'm going to try and update a structure variable. 62 | 63 | variables.SetPt(variables.GetPtptr()) 64 | 65 | //assert.Equal(t, variables.Point_print(variables.GetPtptr()), variables.Pt_print()) 66 | } 67 | -------------------------------------------------------------------------------- /variables/variables.c: -------------------------------------------------------------------------------- 1 | /* File : variables.c */ 2 | 3 | /* I'm a file containing some C global variables */ 4 | 5 | /* Deal with Microsoft's attempt at deprecating C standard runtime functions */ 6 | #if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) 7 | # define _CRT_SECURE_NO_DEPRECATE 8 | #endif 9 | 10 | #include 11 | #include 12 | #include "variables.h" 13 | 14 | int ivar = 0; 15 | short svar = 0; 16 | long lvar = 0; 17 | unsigned int uivar = 0; 18 | unsigned short usvar = 0; 19 | unsigned long ulvar = 0; 20 | signed char scvar = 0; 21 | unsigned char ucvar = 0; 22 | char cvar = 0; 23 | float fvar = 0; 24 | double dvar = 0; 25 | char *strvar = 0; 26 | const char cstrvar[] = "Goodbye"; 27 | int *iptrvar = 0; 28 | char name[256] = "Dave"; 29 | char path[256] = "/home/beazley"; 30 | 31 | 32 | /* Global variables involving a structure */ 33 | Point *ptptr = 0; 34 | Point pt = { 10, 20 }; 35 | 36 | /* A variable that we will make read-only in the interface */ 37 | int status = 1; 38 | 39 | /* A debugging function to print out their values */ 40 | 41 | void print_vars() { 42 | printf("ivar = %d\n", ivar); 43 | printf("svar = %d\n", svar); 44 | printf("lvar = %ld\n", lvar); 45 | printf("uivar = %u\n", uivar); 46 | printf("usvar = %u\n", usvar); 47 | printf("ulvar = %lu\n", ulvar); 48 | printf("scvar = %d\n", scvar); 49 | printf("ucvar = %u\n", ucvar); 50 | printf("fvar = %g\n", fvar); 51 | printf("dvar = %g\n", dvar); 52 | printf("cvar = %c\n", cvar); 53 | printf("strvar = %s\n", strvar ? strvar : "(null)"); 54 | printf("cstrvar = %s\n", cstrvar); 55 | printf("iptrvar = %p\n", iptrvar); 56 | printf("name = %s\n", name); 57 | printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); 58 | printf("pt = (%d, %d)\n", pt.x, pt.y); 59 | printf("status = %d\n", status); 60 | } 61 | 62 | /* A function to create an integer (to test iptrvar) */ 63 | 64 | int *new_int(int value) { 65 | int *ip = (int *) malloc(sizeof(int)); 66 | *ip = value; 67 | return ip; 68 | } 69 | 70 | /* A function to create a point */ 71 | 72 | Point *new_Point(int x, int y) { 73 | Point *p = (Point *) malloc(sizeof(Point)); 74 | p->x = x; 75 | p->y = y; 76 | return p; 77 | } 78 | 79 | char * Point_print(Point *p) { 80 | static char buffer[256]; 81 | if (p) { 82 | sprintf(buffer,"(%d,%d)", p->x,p->y); 83 | } else { 84 | sprintf(buffer,"null"); 85 | } 86 | return buffer; 87 | } 88 | 89 | void pt_print() { 90 | printf("(%d, %d)\n", pt.x, pt.y); 91 | } 92 | -------------------------------------------------------------------------------- /variables/variables.h: -------------------------------------------------------------------------------- 1 | /* File: variables.h */ 2 | 3 | typedef struct { 4 | int x,y; 5 | } Point; 6 | 7 | -------------------------------------------------------------------------------- /variables/variables.swig: -------------------------------------------------------------------------------- 1 | /* File : variables.i */ 2 | %module variables 3 | %{ 4 | #include "variables.h" 5 | %} 6 | 7 | /* Some global variable declarations */ 8 | %inline %{ 9 | extern int ivar; 10 | extern short svar; 11 | extern long lvar; 12 | extern unsigned int uivar; 13 | extern unsigned short usvar; 14 | extern unsigned long ulvar; 15 | extern signed char scvar; 16 | extern unsigned char ucvar; 17 | extern char cvar; 18 | extern float fvar; 19 | extern double dvar; 20 | extern char *strvar; 21 | extern const char cstrvar[]; 22 | extern int *iptrvar; 23 | extern char name[256]; 24 | 25 | extern Point *ptptr; 26 | extern Point pt; 27 | %} 28 | 29 | 30 | /* Some read-only variables */ 31 | 32 | %immutable; 33 | 34 | %inline %{ 35 | extern int status; 36 | extern char path[256]; 37 | %} 38 | 39 | %mutable; 40 | 41 | /* Some helper functions to make it easier to test */ 42 | %inline %{ 43 | extern void print_vars(); 44 | extern int *new_int(int value); 45 | extern Point *new_Point(int x, int y); 46 | extern char *Point_print(Point *p); 47 | extern void pt_print(); 48 | %} 49 | --------------------------------------------------------------------------------