文档章节

不用 SWIG,Go 使用 C++ 代码的方式

风华神使
 风华神使
发布于 2016/02/08 01:07
字数 412
阅读 4080
收藏 51

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

这是一个C++头文件:

#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

这是对应的源文件:

#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等)的存在,定义一个结构体:

typedef struct _X_t
{
    int unused;
}X_t;

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

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

#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)如下:

#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文件:

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)
}

结果如下:

X::X
11
X::~X

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

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

© 著作权归作者所有

共有 人打赏支持
风华神使
粉丝 25
博文 77
码字总数 42460
作品 0
南开
架构师
私信 提问
加载中

评论(8)

O油菜
O油菜

引用来自“邪恶胖子”的评论

引用来自“O油菜”的评论

引用来自“邪恶胖子”的评论

go可以使用c++的boost库了?
boost是头库。。

……对我有用吗?
头库是在编译器那里实体化的,不能用go调用
邪恶胖子
邪恶胖子

引用来自“O油菜”的评论

引用来自“邪恶胖子”的评论

go可以使用c++的boost库了?
boost是头库。。

……对我有用吗?
无锡首席大都督程序员
用汇编吧,我觉得只有汇编才能匹配楼主的风骚了
魏曼奇
魏曼奇
boost可不是头库。
O油菜
O油菜

引用来自“邪恶胖子”的评论

go可以使用c++的boost库了?
boost是头库。。
风华神使
风华神使

引用来自“邪恶胖子”的评论

go可以使用c++的boost库了?
试试呗
邪恶胖子
邪恶胖子
go可以使用c++的boost库了?
红烧土豆
红烧土豆
42
SWIG与JAVA 交互最全开发指南一

项目背景 最近开始研究做移动端项目,但是本人基本是做了五六年的c++的底层研发,对C++的研发可以说是驾轻就熟了,但是对于android还是属于刚入门阶段,虽然断断续续做移动端也做了一年,但是...

揽月凡尘
2018/06/16
0
0
C/C++ 和 Python混合编程

链接:https://www.zhihu.com/question/23003213/answer/56121859 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 #include int main(int argc, char *...

sirius_0
2018/04/21
0
0
SWIG入门6: Python Proxy Class和Builtin Type

在前几篇文章中,从一个较高的层次上说明了SWIG的基本用法。这篇文章会深入到SWIG的一些实现的细节中。SWIG默认的封装方式,是把C/C++的struct和class封装到Python Proxy Class中。不过从SWI...

costaxu
2012/09/08
0
0
公司打算做一个C++到Java的技术迁移,想用SWIG做过渡的工具,使用过SWIG的XD能不能给点意见?

公司有个做了很久很久的桌面产品,使用C++加wxWidgets,代码结构、工具都很陈旧,工程师维护起来叫苦连连。 最近前端从C++迁移到Java端,但因为有上百万行的代码量,想用SWIG做过渡,即较低层...

Yongqiang
2013/04/11
1K
9
swig3.0 生成不了cpp代码,求高手分析原因..

swig jni自动生成代码配置文件 my-swig-generate.mk # MY_SWIG_PACKAGE MY_SWIG_MODE MY_SWIG_INTERFACES #Android构建系统的SWIG扩展 #@author Onur cinar # #检查变量MY_SWIG_PACKAGE是否已......

2014-jay
2014/04/27
388
0

没有更多内容

加载失败,请刷新页面

加载更多

如何限制用户仅通过HTTPS方式访问OSS?

一、当前存在的问题 当前OSS支持用户使用HTTPS/HTTP协议访问Bucket。但由于HTTP存在安全漏洞。大型企业客户都要求使用HTTPS方式访问OSS,并且拒绝HTTP访问请求。 目前OSS可以通过RAM policy方...

阿里云官方博客
27分钟前
2
0
详解深度学习之经典网络架构——LeNet

一、基本简介 LeNet-5出自论文Gradient-Based Learning Applied to Document Recognition,是一种用于手写体字符识别的非常高效的卷积神经网络。 二、LeNet网络的基本结构 LeNet5 这个网络虽...

AI女神
30分钟前
3
0
日志服务Python消费组实战(二):实时分发数据

场景目标 使用日志服务的Web-tracking、logtail(文件极简)、syslog等收集上来的日志经常存在各种各样的格式,我们需要针对特定的日志(例如topic)进行一定的分发到特定的logstore中处理和...

阿里云云栖社区
30分钟前
3
0
LVM 增加磁盘扩容

sudo parted /dev/sdeparted> mklabel gptparted> mkpart primary lvm ext4 %0 %100parted> printsudo lvmlvm> pvcreate /dev/sde1lvm> vgextend vg-data /dev/sde1lvm> lve......

仪山湖
34分钟前
1
0
Linux挂载本地iso镜像,不联网使用yum命令

上传iso镜像文件到/mnt 目录下 在/mnt目录下创建Server目录 mkdir Server 备份 /etc/yum.repos.d/目录下的repo文件 cd /etc/yum.repos.dmkdir repobakmv *.repo repobak/ 挂载本地iso文件...

AustinYe
35分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部