go cgo c c++ cpp 写于2017-12-26
上篇博客讲到Go 如何调用 C, 这篇主要讲 Go 如何调用 C++ 。C++ 的代码目前没法内联在 Go 代码里,只能通过外部库方式引用,同时 cgo 也没办法直接调用 C++ 代码, 类也没法 new, 除了 extern “C” 方式声明的函数。所以 Go 要想调用 C++ 代码,可以通过 C 代码调 C++, 然后通过 Go 调 C 代码来实现。下面讲一个具体的例子。
example/ main.go foo/ foo.h foo.cpp bridge.h bridge.cfoo.h
class Foo { public: Foo(); ~Foo(); void bar(); }foo.cpp
#include <stdio.h> #include "foo.h" Foo::Foo() { } Foo::~Foo() { } void Foo::bar() { printf("hello bar\n"); }bridge.h
#ifdef __cplusplus extern "C" { #endif void bar(); #ifdef __cplusplus } #endifbridge.c
#include "foo.h" #include "bridge.h" void bar() { Foo* foo = new Foo(); foo->bar(); }以上 foo.h 和 foo.cpp 是 C++ 代码,我们使用 C 语言写个 bridge , 封装下 C++ 调用。
编译静态链接库
cd foo/ g++ -c foo.cpp g++ -c bridge.c ar -crs libfoo.a foo.o bridge.omain.go
package main // #cgo CFLAGS: -I${SRCDIR}/foo // #cgo LDFLAGS: -lstdc++ -L${SRCDIR}/foo -lfoo // #include "bridge.h" import "C" func main() { C.bar() }配置 #cgo 指令和调用 C 外部库一样,唯一需要注意的是 LDFLAGS 参数要加 -lstdc++。另外一个需要注意的地方是 C 语言调用 C++ 的时候头文件需要配置 extern "C" { ... } 大意是按照 C 语言的规范来编译和连接,我的主要工作语言不是 C/C++ 详细参考这篇博客。最后使用 go build 编译 Go 代码。