How to use C++ in Go?
helloworld20102010 · · 3776 次点击 · · 开始浏览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(){};voidBar();};// foo.cpp#include<iostream>#include"foo.hpp"void
cxxFoo::Bar(void){
std::cout<<this->a<<std::endl;}
which I want to use in go. I'll use the c interface
// foo.h#ifdef __cplusplus
extern"C"{#endiftypedefvoid*Foo;FooFooInit(void);voidFooFree(Foo);voidFooBar(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"FooFooInit(){
cxxFoo * ret =new cxxFoo(1);return(void*)ret;}voidFooFree(Foo f){
cxxFoo * foo =(cxxFoo*)f;delete foo;}voidFooBar(Foo f){
cxxFoo * foo =(cxxFoo*)f;
foo->Bar();}
with all that done, the go file is
// foo.go
package foo
// #include "foo.h"import"C"import"unsafe"
type GoFoostruct{
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
// makefile
TARG=foo
CGOFILES=foo.go
include $(GOROOT)/src/Make.$(GOARCH)
include $(GOROOT)/src/Make.pkg
foo.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.go
package foo
import"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
gotest
rm -f _test/foo.a _gotest_.66g-o _gotest_.6 foo.cgo1.go foo.cgo2.go foo_test.go
rm -f _test/foo.a
gopack grc _test/foo.a _gotest_.6 foo.cgo3.61
PASS
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
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(){};voidBar();};// foo.cpp#include<iostream>#include"foo.hpp"void
cxxFoo::Bar(void){
std::cout<<this->a<<std::endl;}
which I want to use in go. I'll use the c interface
// foo.h#ifdef __cplusplus
extern"C"{#endiftypedefvoid*Foo;FooFooInit(void);voidFooFree(Foo);voidFooBar(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"FooFooInit(){
cxxFoo * ret =new cxxFoo(1);return(void*)ret;}voidFooFree(Foo f){
cxxFoo * foo =(cxxFoo*)f;delete foo;}voidFooBar(Foo f){
cxxFoo * foo =(cxxFoo*)f;
foo->Bar();}
with all that done, the go file is
// foo.go
package foo
// #include "foo.h"import"C"import"unsafe"
type GoFoostruct{
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
// makefile
TARG=foo
CGOFILES=foo.go
include $(GOROOT)/src/Make.$(GOARCH)
include $(GOROOT)/src/Make.pkg
foo.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.go
package foo
import"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
gotest
rm -f _test/foo.a _gotest_.66g-o _gotest_.6 foo.cgo1.go foo.cgo2.go foo_test.go
rm -f _test/foo.a
gopack grc _test/foo.a _gotest_.6 foo.cgo3.61
PASS