通过swig可以将c/c++的接口导出,然后go可以直接调用
一个例子
1 | MacBook-Pro-4:~ zhangshihua$ go get github.com/zacg/simplelib |
继续执行
1 | cd $GOPATH/github.com/zacg/simplelib |
看下swig的参数:
1 | swig --help |
看下swig go语言的特殊参数:
1 | swig -go -help |
执行测试集:
1 | MacBook-Pro-4:simplelib zhangshihua$ go test -v |
代码解释
原理可以通过追踪代码自行查看,我们首先看看simplelib.h头文件
1 | #ifndef SIMPLECLASS_H |
c++定义了一个类SimpleClass,其中有三个方法,hello(),helloString(),helloBytes().我们首先通过编写一个swig接口文件simplelib.i导出这三个函数:
1 | %module simplelib //go的包名 |
调用’swig -go -cgo -c++ -intgosize 64 simplelib.i’命令生成’simplelib_wrap.cxx’和’simplelib.go’文件.
编写如下测试代码:
1 | package main |
可以看到,调用时与使用go语言写的库没什么区别.甚至把cgo的逻辑都已经隐藏.
增加一个回调
如果c++代码中设置了回调类,回调类中包括各种阶段的回调函数,如何用go实现这个回调类和回调函数呢?
c++代码修改如下:
1 | class SimpleClassCallback |
增加了一个c++类SimpleClassCallback,其中有一个函数onStart
1 | class SimpleClass |
SimpleClass中增加一个函数setCallBack,参数为增加的新类SimpleClassCallback.然后增加一个实现:
1 | void SimpleClass::setCallBack(SimpleClassCallback *scc){ |
输出”world from callback!”并且调用onStart方法.那么go中如何实现onStart方法呢?
首先需要修改swig接口文件:
1 | %module(directors="1") simplelib |
增加feature语句表明需要被实现的类,module语句后边增加’directors=”1”‘
然后实现如下go代码:
1 | package simplelib |
解释如下(注意该写法完全参照链接2中示例,官方文档也强烈建议需要按这种方法编写):
- 定义SCCGo接口,是SimpleClassCallback的超类.调用时通过NewSCCGo调用,返回的就是该接口类型
- 调用回调类时按NewDirectorSimpleClassCallback,传入的参数是一个实现了SimpleClassCallback类方法的结构体.
- sccGo实现了SCCGo接口
调用swig命令生成新的wrapper
1 | swig -go -cgo -c++ -intgosize 64 simplelib.i |
然后再代码中就可以如下使用:
1 | c := simplelib.NewSCCGo() |
1 | MacBook-Pro-4:simplelib zhangshihua$ go run simple.go |