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

将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++代码的方式)