不用 SWIG,Go 使用 C++ 代碼的方式
來自: http://my.oschina.net/jthmath/blog/614298?fromerr=w5tJd1x3
將C++代碼用C作一次封裝,就可以讓Go調用了。
這是一個C++頭文件:
#ifndef CGO_CPPGO_CLASSHdefine CGO_CPPGO_CLASSH
include <stdint.h>
class X { public: X(int32_t a); ~X(); void Plus(); int32_t Func(int32_t b); private: int32t m; };
endif</pre>
這是對應的源文件:
#include <iostream> using std::cout; using std::endl;include "class.h"
X::X(int32t a) :m{ a } { cout << "X::X" << endl; }
X::~X() { cout << "X::~X" << endl; }
void X::Plus() { m_ += 1; }
int32_t X::Func(int32t b) { return m + b; }</pre>
為了讓Go感知不到C++(class、std::cout等)的存在,定義一個結構體:
typedef struct _X_t { int unused; }X_t;這個結構體來充當class X的作用。
完整的C頭文件如下:(這個頭文件中沒有任何C++特有的東西!)
#ifndef C_WRAPPERHdefine C_WRAPPERH
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</pre>
源文件(.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); }</pre>
接下來,就可以在Go中包含c-wrapper.h文件:
package mainimport ( "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) }</pre>
結果如下:
X::X 11 X::~X這就實現了Go使用C++代碼。
如果想在Go中使用大型C++開源庫,這個方法有些麻煩(而且C++的編譯比較慢),但不失為一種選擇。
</div>