转载

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

原文  http://my.oschina.net/jthmath/blog/614298?fromerr=w5tJd1x3
正文到此结束
Loading...