This is an example of Go code calling to a C++ library with a C wrapper.
go build # this only ensures it compilesgo test # actually runs tests| // 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(); | |
| } |
| 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)))) | |
| } |
| // 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 |
| 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") | |
| } | |
| } |
| #include <iostream> | |
| #include "nummer.hpp" | |
| void cxxNum::Increment(void) { | |
| this->value++; | |
| } | |
| int cxxNum::GetValue(void) { | |
| return this->value; | |
| } |
| class cxxNum { | |
| private: | |
| int value; | |
| public: | |
| cxxNum(int _num):value(_num){}; | |
| ~cxxNum(){}; | |
| void Increment(void); | |
| int GetValue(void); | |
| }; |