c++ - 如何在 Go 中使用 C++

标签 c++ wrapper go

在新的 Go 中语言,如何调用 C++ 代码?换句话说,我如何包装我的 C++ 类并在 Go 中使用它们?

最佳答案

更新:我已成功将一个小型测试 C++ 类与 Go 链接

如果你用 C 接口(interface)包装你的 C++ 代码,你应该能够用 cgo 调用你的库(参见 $GOROOT/misc/cgo/gmp 中的 gmp 示例)。

我不确定 C++ 中的类的想法是否真的可以在 Go 中表达,因为它没有继承。

这是一个例子:

我有一个 C++ 类定义为:

// foo.hpp
class cxxFoo {
public:
  int a;
  cxxFoo(int _a):a(_a){};
  ~cxxFoo(){};
  void Bar();
};

// foo.cpp
#include <iostream>
#include "foo.hpp"
void
cxxFoo::Bar(void){
  std::cout<<this->a<<std::endl;
}

我想在 Go 中使用它。我将使用C接口(interface)

// foo.h
#ifdef __cplusplus
extern "C" {
#endif
  typedef void* Foo;
  Foo FooInit(void);
  void FooFree(Foo);
  void FooBar(Foo);
#ifdef __cplusplus
}
#endif

(我使用 void* 而不是 C 结构,因此编译器知道 Foo 的大小)

实现是:

//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();
}

完成所有这些后,Go 文件是:

// foo.go
package 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));
}

我用来编译它的makefile是:

// 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)

尝试使用以下方法对其进行测试:

// foo_test.go
package foo
import "testing"
func TestFoo(t *testing.T){
    foo := New();
    foo.Bar();
    foo.Free();
}

您需要使用 make install 安装共享库,然后运行 ​​make test。预期输出为:

gotest
rm -f _test/foo.a _gotest_.6
6g -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.6
1
PASS

关于c++ - 如何在 Go 中使用 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1713214/

相关文章:

c++ - 使用时钟计算时间的值为零 - linux

c++ - 我怎样才能使类论坛在 C++ 中使用字符串?

c# - ObjectSet 包装器不适用于 linqToEntities 子查询

go - 捕获传递给 http.Server.Serve 的 net.Listener

c++一旦达到数组大小或eof就停止循环

c++ - 为什么 Microsoft Visual Studio 找不到 <stdint.h>?

java - 使用 JNI 构建 C++ Java 包装器

带有函数的python包装函数

go - 运行go env时,显示的GOPATH与我在环境变量中设置的内容有所不同吗?

go - 在没有循环依赖的 Go 中注册包