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

HorCribb 8年前發布 | 14K 次閱讀 C/C++開發 C/C++

來自: http://my.oschina.net/jthmath/blog/614298?fromerr=w5tJd1x3

將C++代碼用C作一次封裝,就可以讓Go調用了。

這是一個C++頭文件:

#ifndef CGO_CPPGO_CLASSH

define 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_WRAPPERH

define 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 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) }</pre>

結果如下:

X::X
11
X::~X

這就實現了Go使用C++代碼。

如果想在Go中使用大型C++開源庫,這個方法有些麻煩(而且C++的編譯比較慢),但不失為一種選擇。

</div>

 本文由用戶 HorCribb 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!