Skip to content

Instantly share code, notes, and snippets.

@nmarley
Last active March 31, 2025 22:32
Show Gist options
  • Select an option

  • Save nmarley/6d4dadc002ff99dd4835bd34c6b025c7 to your computer and use it in GitHub Desktop.

Select an option

Save nmarley/6d4dadc002ff99dd4835bd34c6b025c7 to your computer and use it in GitHub Desktop.

Revisions

  1. nmarley revised this gist Jul 26, 2019. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -4,9 +4,13 @@ This is an example of Go code calling to a C++ library with a C wrapper.

    ## Build

    ```sh
    go build # this only ensures it compiles
    ```


    ## Test

    ```sh
    go test # actually runs tests
    ```
  2. nmarley created this gist Jul 26, 2019.
    12 changes: 12 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    # Go / C++ bindings example

    This is an example of Go code calling to a C++ library with a C wrapper.

    ## Build

    go build # this only ensures it compiles


    ## Test

    go test # actually runs tests
    23 changes: 23 additions & 0 deletions num.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    // num.cpp
    #include "nummer.hpp"
    #include "num.h"

    Num NumInit() {
    cxxNum * ret = new cxxNum(1);
    return (void*)ret;
    }

    void NumFree(Num n) {
    cxxNum * num = (cxxNum*)n;
    delete num;
    }

    void NumIncrement(Num n) {
    cxxNum * num = (cxxNum*)n;
    num->Increment();
    }

    int NumGetValue(Num n) {
    cxxNum * num = (cxxNum*)n;
    return num->GetValue();
    }
    26 changes: 26 additions & 0 deletions num.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    package num

    // #cgo LDFLAGS: -L. -lstdc++
    // #cgo CXXFLAGS: -std=c++14 -I.
    // #include "num.h"
    import "C"
    import "unsafe"

    type GoNum struct {
    num C.Num
    }

    func New() GoNum {
    var ret GoNum
    ret.num = C.NumInit()
    return ret
    }
    func (n GoNum) Free() {
    C.NumFree((C.Num)(unsafe.Pointer(n.num)))
    }
    func (n GoNum) Inc() {
    C.NumIncrement((C.Num)(unsafe.Pointer(n.num)))
    }
    func (n GoNum) GetValue() int {
    return int(C.NumGetValue((C.Num)(unsafe.Pointer(n.num))))
    }
    14 changes: 14 additions & 0 deletions num.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    // num.h
    #ifdef __cplusplus
    extern "C" {
    #endif

    typedef void* Num;
    Num NumInit(void);
    void NumFree(Num);
    void NumIncrement(Num);
    int NumGetValue(Num);

    #ifdef __cplusplus
    }
    #endif
    27 changes: 27 additions & 0 deletions num_test.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    package num

    import (
    "reflect"
    "testing"
    )

    func TestNum(t *testing.T) {
    num := New()
    num.Inc()
    if num.GetValue() != 2 {
    t.Error("unexpected value received")
    }
    num.Inc()
    num.Inc()
    num.Inc()
    if num.GetValue() != 5 {
    t.Error("unexpected value received")
    }
    value := num.GetValue()
    num.Free()

    typ := reflect.TypeOf(value)
    if typ.Name() != "int" {
    t.Error("got unexpected type")
    }
    }
    10 changes: 10 additions & 0 deletions nummer.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    #include <iostream>
    #include "nummer.hpp"

    void cxxNum::Increment(void) {
    this->value++;
    }

    int cxxNum::GetValue(void) {
    return this->value;
    }
    10 changes: 10 additions & 0 deletions nummer.hpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    class cxxNum {
    private:
    int value;

    public:
    cxxNum(int _num):value(_num){};
    ~cxxNum(){};
    void Increment(void);
    int GetValue(void);
    };