项目原来使用c++实现了底层逻辑,为了方便业务方使用,现在需要支持golang语言的sdk。经过调研了解到swig可以将C++导出接口类供其他脚本语言或者高级编程语言调用,本文基于swig实现C++类导出golang的接口类,然后在golang中利用struct实现继承。
为了更好地演示,本文利用简单的C++类进行描述。
首先定义C++的基类和一个辅助类,后面go会利用struct派生于基类BaseCase,辅助类用于调用派生类的函数。
// BaseCase.h
#include <string>
#include <iostream>
using namespace std;
class BaseCase
{
public:
BaseCase() {}
virtual ~BaseCase() {}
BaseCase(const BaseCase& rhs) {
m_caseName = rhs.m_caseName;
}
virtual void Run() {cout << "run the case in baseCase class." << endl;}
public:
string m_caseName;
};
class CaseRunner
{
public:
BaseCase* _baseCase_;
public:
CaseRunner():_baseCase_(0) {}
void RegisterCase(BaseCase *bc) {_baseCase_ = bc;}
void run() {if (_baseCase_) _baseCase_->Run();}
};
编写swig.i文件
// swig.i
%module(directors="1") baseCase
%{
#include "BaseCase.h"
%}
%include "std_string.i"
%include "std_map.i"
%feature("director") BaseCase;
%include "BaseCase.h"
然后利用swig命令行将导出BaseCase和CaseRunner的Golang接口类
// swig command line
swig -go -cgo -intgosize 64 -c++ swig.i
执行完上面个的命令之后,会生成对应的swig_wrap.cxx,swig_wrap.h,baseCase.go
然后编写test.go文件
package main
import (
"fmt"
. "baseCase"
)
type TestCase1Class interface {
BaseCase
deleteBaseCase()
IsTestCase1Class()
}
type testCase1Class struct {
BaseCase // 这个是swig导出来的interface接口
}
func (caseClass_ *testCase1Class) IsTestCase1Class() {}
func (caseClass_ *testCase1Class) deleteBaseCase() {
DeleteDirectorBaseCase(caseClass_.BaseCase)
}
type TestClass struct {
p BaseCase
}
func NewGoTestCase1Class() TestCase1Class {
om := &TestClass{}
p := NewDirectorBaseCase(om)
om.p = p
return &testCase1Class{BaseCase: p}
}
func (caseClass_ *TestClass) Run() {
fmt.Println("start to run caseClass ...")
caseClass_.case1()
caseClass_.case2()
}
// case1
func (caseClass_ *TestClass) case1() {
fmt.Println("run caseClass 1")
}
// case2
func (caseClass_ *TestClass) case2() {
fmt.Println("run caseClass 2")
}
func main() {
goCase := NewGoTestCase1Class()
caseRuner := NewCaseRunner()
caseRuner.RegisterCase(goCase)
caseRuner.Run()
return
}
执行打包命令,即可以编译一个test的可执行文件
>> go build test.go
>> ./test
start to run caseClass ...
run caseClass 1
run caseClass 2