這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Update: I've succeeded in linking a small test c++ class with go
If you wrap you c++ code with a c interface you should be able to call your library with cgo (see the example of gmp in $GOROOT/misc/cgo/gmp).
I'm not sure if the idea of a class in c++ is really expressible in go, as it doesn't have inheritance.
Here's an example
I have a c++ class defined as
// foo.hppclass cxxFoo {public: int a; cxxFoo(int _a):a(_a){}; ~cxxFoo(){}; void Bar();};// foo.cpp#include <iostream>#include "foo.hpp"voidcxxFoo::Bar(void){ std::cout<<this->a<<std::endl;}
which I want to use in go. I'll use the c interface
// foo.h#ifdef __cplusplusextern "C" {#endif typedef void* Foo; Foo FooInit(void); void FooFree(Foo); void FooBar(Foo);#ifdef __cplusplus}#endif
(I use a void* instead of a c struct so the compiler knows the size of Foo)
The implementation is
//cfoo.cpp#include "foo.hpp"#include "foo.h"Foo FooInit(){ cxxFoo * ret = new cxxFoo(1); return (void*)ret;}void FooFree(Foo f){ cxxFoo * foo = (cxxFoo*)f; delete foo;}void FooBar(Foo f){ cxxFoo * foo = (cxxFoo*)f; foo->Bar();}
with all that done, the go file is
// foo.gopackage foo// #include "foo.h"import "C"import "unsafe"type GoFoo struct { foo C.Foo;}func New()(GoFoo){ var ret GoFoo; ret.foo = C.FooInit(); return ret;}func (f GoFoo)Free(){ C.FooFree(unsafe.Pointer(f.foo));}func (f GoFoo)Bar(){ C.FooBar(unsafe.Pointer(f.foo));}
The makefile I used to compile this was
// makefileTARG=fooCGOFILES=foo.goinclude $(GOROOT)/src/Make.$(GOARCH)include $(GOROOT)/src/Make.pkgfoo.o:foo.cpp g++ $(_CGO_CFLAGS_$(GOARCH)) -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $<cfoo.o:cfoo.cpp g++ $(_CGO_CFLAGS_$(GOARCH)) -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $<CGO_LDFLAGS+=-lstdc++$(elem)_foo.so: foo.cgo4.o foo.o cfoo.o gcc $(_CGO_CFLAGS_$(GOARCH)) $(_CGO_LDFLAGS_$(GOOS)) -o $@ $^ $(CGO_LDFLAGS)
Try testing it with
// foo_test.gopackage fooimport "testing"func TestFoo(t *testing.T){ foo := New(); foo.Bar(); foo.Free();}
You'll need to install the shared library with make install, then run make test. Expected output is
gotestrm -f _test/foo.a _gotest_.66g -o _gotest_.6 foo.cgo1.go foo.cgo2.go foo_test.gorm -f _test/foo.agopack grc _test/foo.a _gotest_.6 foo.cgo3.61PASS