golang中使用cgo呼叫c++程式
1 背景
這兩天在考慮使用golang搭建一個http服務,呼叫別人的linux sdk。由於linux sdk是用c寫的,直接使用cgo呼叫c是很方便的,但是個人想使用c++來呼叫c的函式,封裝成c++語法,c++可以使用一些庫,對於開發是比較方便的,所以就得考慮使用cgo呼叫c++程式。
網上一搜,目前實現cgo呼叫c++主要有三種方式:
1 swig
2 swift
3 使用c包裝c++,然後cgo呼叫c
對於以上3種方式,第2種我是沒看過,第1種就瀏覽了下,沒寫過。主要是想用第3種,可以純粹的寫c++,c。
環境:
ubuntu 16 64bit (個人喜歡用centos 7.*)
gcc g++都是預設的。
golang gopath = /home/user/gopath
說明:以下程式碼是從網上下載的,但是別人的實現是要編譯可執行檔案,即go build, 然後執行可執行檔案。(原始碼地址:draffensperger/go-interlang )不能通過go run *.go 來執行,很嫌棄這種,麻煩,所以自己就來該動了。自己專案中的程式碼就不能放在這了,原理都是相同的。
2 golang 呼叫c++ 例項
原始碼: example
目錄結構:
exampleOne 一定要放在src中,防止找不到包
$gopath: src - exampleOne - main.go - temp - one.go, point.cxx point.hxx wrap_point.cxx wrap_point.hxx
temp中是從網上下的原始碼,不作改動。
然後就可以執行:
go run main.go
檔案與程式碼:
main.go
// main.go
package main
import (
"funcExample/temp"
)
func main () {
temp.P()
}
temp 下的 one.go
// one.go package temp // #include "wrap_point.hxx" import "C" import "fmt" func init() { fmt.Println("Hi from Go, about to calculate distance in C++ ...") distance := C.distance_between(1.0, 1.0, 2.0, 2.0) fmt.Printf("Go has result, distance is: %v\n", distance) } func P() { distance := C.distance_between(1.0, 1.0, 2.0, 2.0) fmt.Println(distance) }
temp下的 point.cxx
// point.cxx
#include "point.hxx"
#include <math.h>
#include <iostream>
Point::Point(double x, double y): x_(x), y_(y) {
}
double Point::distance_to(Point p) {
std::cout << "C++ says: finding distance between (" << x_ << "," << y_
<< "), and (" << p.x_ << "," << p.y_ << ")" << std::endl;
double x_dist = x_ - p.x_;
double y_dist = y_ - p.y_;
return sqrt(x_dist * x_dist + y_dist * y_dist);
}
temp 下的 point.hxx
// point.hxx
#ifndef POINT_H
#define POINT_H
class Point {
public:
Point(double x, double y);
double distance_to(Point p);
private:
double x_, y_;
};
#endif
temp 下的wrap_point.cxx
// wrap_point.cxx
#include "wrap_point.hxx"
#include "point.hxx"
double distance_between(double x1, double y1, double x2, double y2) {
return Point(x1, y1).distance_to(Point(x2, y2));
}
temp 下的 wrap_point.hxx
// wrap_point.hxx
#ifndef WRAP_POINT_H
#define WRAP_POINT_H
// __cplusplus gets defined when a C++ compiler processes the file
#ifdef __cplusplus
// extern "C" is needed so the C++ compiler exports the symbols without name
// manging.
extern "C" {
#endif
double distance_between(double x1, double y1, double x2, double y2);
#ifdef __cplusplus
}
#endif
#endif
對於以上的程式碼自己不做過多說明,都是c/c++ 的用法。
關於cgo語法型別與c的對應關係,可以直接檢視cgo文件 command cgo,cgo除了提供直接與c資料型別的對應型別,還支援使用函式將golang資料型別轉換成c的資料型別,比如 func C.CString(string) *C.char
見文件說明。
3 其他例項
github原始碼中的exmapleTwo 是與以上例項類似的。只不過以上對c++類的包裝使用比上面更詳細。其中的temp也是從網上下載的原始碼。
更多cgo設定檔案include, lib的方式可以看看其他相關資料,此處懶得打字。