将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++的编译比较慢),但不失为一种选择。
来源:oschina
链接:https://my.oschina.net/u/2321748/blog/614298