将C++代码用C作一次封装,就可以让Go调用了。

这是一个C++头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef CGO_CPPGO_CLASS_H_
#define CGO_CPPGO_CLASS_H_
 
#include <stdint.h>
 
class X
{
public:
    X(int32_t a);
    ~X();
    void Plus();
    int32_t Func(int32_t b);
private:
    int32_t m_;
};
 
#endif

这是对应的源文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using std::cout;
using std::endl;
 
#include "class.h"
 
X::X(int32_t a)
    :m_{ a }
{
    cout << "X::X" << endl;
}
 
X::~X()
{
    cout << "X::~X" << endl;
}
 
void X::Plus()
{
    m_ += 1;
}
 
int32_t X::Func(int32_t b)
{
    return m_ + b;
}

为了让Go感知不到C++(class、std::cout等)的存在,定义一个结构体:

1
2
3
4
typedef struct _X_t
{
    int unused;
}X_t;

这个结构体来充当class X的作用。

完整的C头文件如下:(这个头文件中没有任何C++特有的东西!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef C_WRAPPER_H_
#define C_WRAPPER_H_
 
#include <stdint.h>
 
typedef struct _X_t
{
    int unused;
}X_t;
 
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif
 
EXTERN_C X_t *NewX(int32_t a); // 充当构造函数
EXTERN_C void Delete(X_t *px); // 充当析构函数
EXTERN_C void Plus(X_t *px);
EXTERN_C int32_t Func(X_t *px, int32_t b);
 
#endif

源文件(.cpp)如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "c-wrapper.h"
#include "class.h"
 
X_t *NewX(int32_t a)
{
    X *px = new X{ a };
    return (X_t*)px;
}
 
void Delete(X_t *px)
{
    X *p = (X*)px;
    delete p;
}
 
void Plus(X_t *px)
{
    ((X*)px)->Plus();
}
 
int32_t Func(X_t *px, int32_t b)
{
    return ((X*)px)->Func(b);
}

接下来,就可以在Go中包含c-wrapper.h文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
 
import (
    "fmt"
)
 
/*
#cgo CPPFLAGS: -std=c++11
#include "c-wrapper.h"
*/
import "C"
 
func main() {
    px := C.NewX(3)
    C.Plus(px)
    var n int32 = int32(C.Func(px, 7))
    fmt.Println(n)
    C.Delete(px)
}

结果如下:

1
2
3
X::X
11
X::~X

这就实现了Go使用C++代码。

如果想在Go中使用大型C++开源库,这个方法有些麻烦(而且C++的编译比较慢),但不失为一种选择。

http://my.oschina.net/jthmath/blog/614298

不用SWIG,Go使用C++代码的方式的更多相关文章

  1. 最新的JavaScript核心语言标准——ES6,彻底改变你编写JS代码的方式!【转载+整理】

    原文地址 本文内容 ECMAScript 发生了什么变化? 新标准 版本号6 兑现承诺 迭代器和for-of循环 生成器 Generators 模板字符串 不定参数和默认参数 解构 Destructu ...

  2. 32位汇编第三讲,RadAsm,IDE的配置和使用,以及汇编代码注入方式

    32位汇编第三讲,RadAsm,IDE的配置和使用,以及汇编代码注入方式 一丶RadAsm的配置和使用 用了怎么长时间的命令行方式,我们发现了几个问题 1.没有代码提醒功能 2.编写代码很慢,记不住各 ...

  3. 不用浏览器,直接用代码发送文件给webservices所在服务器 并且可以周期行的发送

    package com.toic.test; import java.io.DataInputStream; import java.io.DataOutputStream; import java. ...

  4. 最新的JavaScript核心语言标准——ES6,彻底改变你编写JS代码的方式!

    原文地址 迁移到:http://www.bdata-cap.com/newsinfo/1741515.html 本文内容 ECMAScript 发生了什么变化? 新标准 版本号6 兑现承诺 迭代器和f ...

  5. 通过代码的方式完成WCF服务的寄宿工作

    使用纯代码的方式进行服务寄宿 服务寄宿的目的是为了开启一个进程,为WCF服务提供一个运行的环境.通过为服务添加一个或者多个终结点,使之暴露给潜在的服务消费,服务消费者通过匹配的终结点对该服务进行调用, ...

  6. 编写css代码的方式

            css(层叠样式表) 在一个网页中主要负责了页面的数据样式.       编写css代码的方式:       第一种: 在style标签中编写css代码. 只能用于本页面中,复用性不强 ...

  7. WCF使用纯代码的方式进行服务寄宿

    服务寄宿的目的是为了开启一个进程,为WCF服务提供一个运行的环境.通过为服务添加一个或者多个终结点,使之暴露给潜在的服务消费,服务消费者通过匹配的终结点对该服务进行调用,除去上面的两种寄宿方式,还可以 ...

  8. Java 10 的 10 个新特性,将彻底改变你写代码的方式!

    Java 9才发布几个月,很多玩意都没整明白,现在Java 10又快要来了.. 这时候我真尼玛想说:线上用的JDK 7 甚至JDK 6,JDK 8 还没用熟,JDK 9 才发布不久不知道啥玩意,JDK ...

  9. 21_Android中常见对话框,光传感器,通过重力感应器编写出指南针应用,帧动画,通过Jav代码的方式编写补间动画,通过XML的方式编写补间动画

     1 关于常见的对话框,主要有: 常见的对话框,单选对话框,多选对话框,进度条对话框(转圈类型的),带进度条的对话框. 案例结构: 完成如下结构的案例,将所有的案例都测试一下: 2 编写MainA ...

  10. 如何用代码的方式取出SAP C4C销售订单创建后所有业务伙伴的数据

    比如我创建了一个Sales Order(销售订单)后,如何用代码的方式取出这些通过SAP Partner determination自动填充的Involved Parties信息呢? 一种方法可以使用 ...

随机推荐

  1. 删除缓存内容----unrecognized selector sent to instance

    这条错误主要还得看unrecognized前面,,我的时[NSNumber-length...]其实是变量类型错误.. 无法识别选择器发送实例,,本来意思就是你的controllerview找不到视图 ...

  2. ubuntu 10.04 下 samba 服务的配置

    1. 安装 $ sudo apt-get install samba $ sudo apt-get install samba-common $ sudo apt-get install samb . ...

  3. jquery-1.10.2.min.js之Multiple markers at this line

    1.windows-preferences  输入validation 2. 点击进入  3. 将JavaScript validator for js files 的两个对勾去了就OK!     4 ...

  4. elk 索引

    zjtest7-redis:/usr/local/logstash-2.3.4/config# cat logstash_agent.conf input { file { type => &q ...

  5. fedora 设置命令别名

    用命令 alias 举例: alias ggw="g++ -g -Wall" ggw 是自定义的别名,可根据需要进行修改设置,等于后面的则是别名的具体含义,在终端输入ggw就像当于 ...

  6. BZOJ 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐

    1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 Description 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按F ...

  7. poj 3295 Tautology(栈)

    题目链接:http://poj.org/problem?id=3295 思路分析:判断逻辑表达式是否为永真式问题.根据该表达式的特点,逻辑词在逻辑变量前,类似于后缀表达式求值问题. 算法中使用两个栈, ...

  8. C#中的DataTable简单使用Merge

    //不同结构的DataTable追加第二个DataTable数据在对应行后的 简单使用//不同结构的DataTable追加在行后面的合并 DataTable dt = new DataTable(); ...

  9. ListView.MultiChoiceModeListener

    参考:http://www.cnblogs.com/a284628487/p/3460400.html和http://blog.csdn.net/mayingcai1987/article/detai ...

  10. Keil4 每次选build 编译(F7)都全部编译的解决办法

    Keil4 每次选build 编译(F7)都全部编译的解决办法 http://blog.csdn.net/wchengshen/article/details/50440079 Keil4 每次选bu ...