当前位置: 首页 > 面试题库 >

如何在Go中使用C ++

计胤
2023-03-14
问题内容

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


问题答案:

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

如果您使用C接口包装C ++代码,则应该可以使用cgo调用您的库(请参阅中的gmp示例$GOROOT/misc/cgo/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接口

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

(我使用a 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


 类似资料:
  • 问题内容: 尝试使用Go的http包时,我无法确定的语法。尽管我尝试了其他一些被编译器拒绝的其他事情,但这里只有我标记的以下内容是我必须编译的。 该URL可以,因为可以正常使用,但是在我运行时,它只是一个空字符串,并且始终为零。我需要怎么做才能取出数据?编译器拒绝了其他尝试。 输出看起来像这样: 问题答案: 尝试给切片buf设置一个大小,例如 读取器最多读取给定缓冲区的len()。 来自io.go

  • 问题内容: 我需要在Go中对int64的较大值执行运算,例如求幂和除法,但是我遇到了溢出问题。我尝试将它们转换为float64,但随后遇到其他问题。这是我尝试过的。 我有一个整数变量,必须将其转换为float64才能使用方便的数学包(https://golang.org/pkg/math)。 但是,如果整数变量太大,则无法正确转换。我假设这是因为大小大于float64。例如: 我正在尝试使用mat

  • 问题内容: 我正在使用Vector类型存储字节数组(可变大小) 一切正常,但是当我尝试检索值时,编译器告诉我我需要使用类型断言。所以我添加了这些,然后尝试 但是当我运行它时,它会失败: 是否知道如何从Vector用于存储其数据的空Element接口中“投射” /转换为实际的[] byte数组,然后供以后使用? 更新(Go1): 矢量软件包已于2011-10-18删除。 问题答案: 这对我来说很好。

  • Go语言中是否有枚举的简单实现?像下面这样的东西?

  • 通过上一小节的介绍,我们知道session是在服务器端实现的一种用户和服务器之间认证的解决方案,目前Go标准包没有为session提供任何支持,这小节我们将会自己动手来实现go版本的session管理和创建。 session创建过程 session的基本原理是由服务器为每个会话维护一份信息数据,客户端和服务端依靠一个全局唯一的标识来访问这份数据,以达到交互的目的。当用户访问Web应用时,服务端程序

  • 问题内容: 我目前正在尝试在mongodb内部的文档数组中提取单个对象。这是一个样本数据集: 我可以在mongo中使用以下命令成功查询: 我无法使用mgo进行相同操作,并尝试了以下操作: 使用嵌套(抛出:合成文字中缺少类型,地图文字中缺少键) 我正在使用httprouter,p.ByName(“ …”)调用是传递给处理程序的参数。 提前致谢。 问题答案: 将与该 方法一起使用,因为doc指出,这使