不用 SWIG,Go 使用 C++ 代码的方式
不用 SWIG,Go 使用 C++ 代码的方式
风华神使 发表于2年前
不用 SWIG,Go 使用 C++ 代码的方式
  • 发表于 2年前
  • 阅读 3396
  • 收藏 51
  • 点赞 2
  • 评论 8

腾讯云 新注册用户 域名抢购1元起>>>   

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

将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++的编译比较慢),但不失为一种选择。

标签: Go Golang C C++ SWIG
共有 人打赏支持
粉丝 22
博文 61
码字总数 40451
评论 (8)
红烧土豆
42
邪恶胖子
go可以使用c++的boost库了?
风华神使

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

go可以使用c++的boost库了?
试试呗
O油菜

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

go可以使用c++的boost库了?
boost是头库。。
魏曼奇
boost可不是头库。
无锡首席大都督程序员
用汇编吧,我觉得只有汇编才能匹配楼主的风骚了
邪恶胖子

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

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

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

……对我有用吗?
O油菜

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

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

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

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

……对我有用吗?
头库是在编译器那里实体化的,不能用go调用
×
风华神使
若认为文好,请随意打赏。
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: