将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. 转: c++继承中的内存布局

    英文原文: http://www.openrce.org/articles/files/jangrayhood.pdf 翻译: http://blog.csdn.net/jiangyi711/arti ...

  2. ThinkPHP 3.1.2 控制器的模块和操作

    本节课大纲: 一.空模块和空操作 1.空操作 function _empty($name){ $this->show("$name 不存在 <a href='__APP__/In ...

  3. XMPP--- error : linker command failed with exit code 1

    error: linker command failed with exit code 1 (use -v to see invocation) 错误原因:libidn.a文件没添加上去 解决方法:l ...

  4. More Divisors(反素数)

    More Divisors Time Limit: 2 Seconds      Memory Limit: 65536 KB Everybody knows that we use decimal ...

  5. Unity KillCount

    using UnityEngine; using System.Collections; public class KillCountMult : MonoBehaviour { public GUI ...

  6. Axure滚动效果实现

    下面的这个透明区域用于显示滚动效果,它本身是一个处于隐藏状态的动态面板,它里面也放了一个动态面板用于产生移动的效果 里面的动态面板起名“实际内容”,注意它的默认状态是“状态2”,状态2和状态一的内容一 ...

  7. python中的class

    尽管Python在Function Programming中有着其他语言难以企及的的优势,但是我们也不要忘了Python也是一门OO语言哦.因此我们关注Python在FP上的优势的同时,还得了解一下P ...

  8. Spring通过AOP实现对Redis的缓存同步

    废话不多说 说下思路:使用aop注解,在Service实现类添加需要用到redis的方法上,当每次请求过来则对其进行拦截,如果是查询则从redis进行get key,如果是update则删除key,防 ...

  9. BZOJ 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草( dp )

    dp... dp( l , r , k )  , 表示 吃了[ l , r ] 的草 , k = 1 表示最后在 r 处 , k = 0 表示最后在 l 处 . ------------------- ...

  10. Tomcat 内存设置

    大型项目或者使用了SSH 的话, Tomcat 可能会报 java.lang.OutOfmemoryError: PermGen Space Windows: 在 bin/catlina.bat 最上 ...