环境:
centos_7_x86_x64,gcc_4.8.5
一、安装swig
1. 安装pcre
yum install -y pcre pcre-tools pcre-devel
2. 安装yacc
yum install -y byacc
3. 下载swig-rel-3.0.12.tar.gz
4. 解压到任意目录下,并生成configure文件
tar -xvzf swig-rel-3.0.12.tar.gz cd swig-rel-3.0.12 ./autogen.sh
5. 生成Makefile文件
./configure
6. 编译和安装
make && make install
7. 验证安装是否成功
swig -version
这里说一下为什么要编译swig源码来进行安装,在yum上安装swig的版本比较低,而较低版本的swig不支持-cgo参数,具体见官方文档。
二、安装golang
1. 安装go
yum install -y go
2. 验证安装是否成功
go version
三、创建C++动态链接库
1. 编写test_cpp.h文件
#ifndef _TEST_CPP_H_ #define _TEST_CPP_H_ #include <stdint.h> #include <string> /// 回调类 class ICallback { public: virtual void notify(const std::string& s) = 0; }; /// 测试类 class TestCall { public: static TestCall* Create() { return new TestCall(); } void SetCallback(ICallback* callback) { callback_ = callback; } int32_t Test(const std::string& s); private: TestCall() : callback_(NULL) {} ICallback* callback_; }; #endif
2. 编写test_cpp.cpp文件
#include <iostream> #include "test_cpp.h" int32_t TestCall::Test(const std::string & s) { std::cout << "TestCall::Test(" << s << ")" << std::endl; if (callback_) { callback_->notify(s); } return 0; }
3. 编写CMakeLists.txt文件
cmake_minimum_required(VERSION 2.8) project(test_cpp C CXX) set(SRC_LISTS test_cpp.cpp) add_library(test_cpp SHARED ${SRC_LISTS})
4. 编译生成动态链接库libtest_cpp.so
mkdir cmake cd cmake cmake .. make
由于在golang中不能直接使用C++函数,所以我们稍后会使用swig工具,生成C函数提供给golang使用。
四、使用swig从C++生成C函数接口
1. 编写定义文件go_test_cpp.swigcxx
/* Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ /* An example of writing a C++ virtual function in Go. */ %module(directors="1") go_test_cpp %init %{ //printf("Initialization rms done. "); %} %typemap(gotype) (char **ppInstrumentID, int nCount) "[]string" %typemap(in) (char **ppInstrumentID, int nCount) %{ { int i; _gostring_* a; $2 = $input.len; a = (_gostring_*) $input.array; $1 = (char **) malloc (($2 + 1) * sizeof (char *)); for (i = 0; i < $2; i++) { /* Not work */ //_gostring_ *ps = &a[i]; //$1[i] = (char *) ps->p; //$1[i][ps->n] = ' '; /*Work well*/ _gostring_ *ps = &a[i]; $1[i] = (char*) malloc(ps->n + 1); memcpy($1[i], ps->p, ps->n); $1[i][ps->n] = '